是的,这也是这个问题:
如何在启用主题的应用程序上使用Delphi7-> Delphi2007更改TCheckBox(或任何已处理控件)的字体颜色?
在网上和本网站上阅读了很多内容后,我找到了4种答案:
向用户提供有关他在表单上拥有的财产/数据状态的彩色反馈,对我来说似乎是合法的。
然后我刚刚安装了MSVC#2008 Express版本,令人惊讶的是,他们可以改变字体的颜色(复选框的属性ForeColor)然后是什么?
似乎并不是“微软这样设计的”。那么现在又回答了问题:
如何在启用主题的应用程序上使用Delphi 7通过Delphi 2007更改TCheckBox(或任何已处理控件)的字体颜色?
答案 0 :(得分:4)
这需要一些调整才能成为完美的解决方案,但对我有用:
将2方法添加到您的复选框组件
FOriginalCaption: string;
_MySetCap: Boolean;
procedure WMPaint(var msg: TWMPaint); message WM_PAINT;
procedure CMTextChanged(var Message: TMessage); message CM_TEXTCHANGED;
并以这种方式实施:
procedure TMyCheckbox.CMTextChanged(var Message: TMessage);
begin
inherited;
if _MySetCap then Exit;
FOriginalCaption := Caption;
end;
procedure TMyCheckbox.WMPaint(var msg: TWMPaint);
var
BtnWidth: Integer;
canv: TControlCanvas;
begin
BtnWidth := GetSystemMetrics(SM_CXMENUCHECK);
_MySetCap := True;
if not (csDesigning in ComponentState) then
Caption := '';
_MySetCap := False;
inherited;
canv := TControlCanvas.Create;
try
canv.Control := Self;
canv.Font := Font;
SetBkMode(canv.Handle, Ord(TRANSPARENT));
canv.TextOut(BtnWidth + 1, 2, FOriginalCaption);
finally
canv.Free;
end;
end;
答案 1 :(得分:2)
哦,但你可以!
只需将放在表单声明之前:
TCheckBox = class(StdCtrls.TCheckBox)
public
procedure CNCtlColorStatic(var Message: TWMCtlColorStatic); message CN_CTLCOLORSTATIC;
end;
TCheckBox的重新声明现在在运行时用作从表单的DFM流式传输的类型。现在实现这样的消息:
procedure TCheckBox.CNCtlColorStatic(var Message: TWMCtlColorStatic);
begin
SetTextColor(Message.ChildDC, ColorToRGB(clRed)); // or RGB(255,0,0));
SetBkMode(Message.ChildDC, TRANSPARENT);
Message.Result := GetStockObject(NULL_BRUSH);
end;
这会捕获WM_CTLCOLORSTATIC消息并将文本颜色更改为红色。这适用于非主题模式(使用WinXP经典版) - 但不适用于主题模式。
您应该知道,为了让主题控件向您发送此消息,控件应该为Theme-drawing API提供DTPB_USECTLCOLORSTATIC标志。可悲的是,这不是默认行为,我也不知道该怎么做。看看this问题。
答案 2 :(得分:1)
以下是我在我的应用中解决这个问题的方法:
这不是一个真正的复选框,它比我想要的工作多一点,但它在我的应用程序中运行得很好(它只有一个需要这种处理的复选框)。
答案 3 :(得分:0)
选项5.使用控件tyou作为基本选项并覆盖控件中的所有绘制消息(是的,您可以将其称为组件,但控件是可见组件的名称,因此您应该使用它)。只需捕获WM_PAINT,可能是WM_NCPAINT,您可以按照自己的风格绘制控件。至少你可以重用控件的整个功能。只要你不改变布局,只有你不需要改变命中测试的颜色。向上移动等等。
注意:我有覆盖TCustomEdit的经验,允许所有类型的颜色,背景文本,额外的按钮等。它需要相当长的时间才能正确读取MSDn和KB中的所有文档以确保控件做了我想做的事。
答案 4 :(得分:0)
此代码是@FLICKER的改进代码,比支持BidiMode
和文本的正确位置要好:
interface
TMSCheckBox = class(TCheckBox)
private
FOriginalCaption: string;
_MySetCap: Boolean;
procedure WMPaint (var Message: TWMPaint); message WM_PAINT;
procedure CMTextChanged(var Message: TMessage); message CM_TEXTCHANGED;
end;
implementation
procedure TMSCheckBox.CMTextChanged(var Message: TMessage);
begin
inherited;
if _MySetCap then Exit;
FOriginalCaption := Caption;
end;
procedure TMSCheckBox.WMPaint(var Message: TWMPaint);
const
SPACE :Integer = 2;
var
txtW, txtH, txtX,
BtnWidth: Integer;
canv: TControlCanvas;
begin
BtnWidth := GetSystemMetrics(SM_CXMENUCHECK);
_MySetCap := True;
if not (csDesigning in ComponentState) then
Caption := '';
_MySetCap := False;
inherited;
canv := TControlCanvas.Create;
try
canv.Control := Self;
canv.Font := Font;
txtW:= canv.TextWidth(FOriginalCaption);
txtH:= canv.TextHeight(FOriginalCaption);
if BiDiMode in [bdRightToLeft, bdRightToLeftReadingOnly] then
txtX:= Width - BtnWidth - SPACE - txtW
else
txtX:= BtnWidth + SPACE;
SetBkMode(canv.Handle, Ord(TRANSPARENT));
canv.TextOut(txtX, (Height - txtH) div 2 + 1, FOriginalCaption);
finally
canv.Free;
end;
end;