2010-03-01 65 views
7

是的,这又是一个问题:如何更改启用主题的控件的字体颜色?

如何在启用主题的应用程序上使用Delphi7-> Delphi2007更改TCheckBox(或任何处理控件)的字体颜色?

在互联网上,并在此网站上阅读了很多之后,我找到4种回答:

  1. 和大多数populare(甚至从QC):你不能,它的设计像微软。
  2. 创建,让像你想你画它的组件。
  3. 购买昂贵的组件集,吸引了像你想要的。
  4. 不要使用主题。

OK,但我仍然不满这一点。

给予一个属性/数据他有一个表格上的状态的用户反馈有色,似乎合法的给我。

然后我刚安装的MSVC#2008 Express版本,那叫一个惊喜,他们可以改变(复选框的财产前景色)的字体颜色然后呢?

它似乎并没有成为一个“它的设计那样,由微软。”那么现在问题又来了:

我怎样才能改变一个TCheckBox的字体颜色(或任何处理的对照)与德尔福7至2007年德尔福在启用主题的应用程序?

+0

什么让你觉得Visual Studio的开发人员不是简单地使用选项2? – 2010-03-01 15:06:07

+0

好吧,我并不需要,而试图重现“它的设计就是这样,由微软。”。在C#上。 我已将ForeColor设置为红色,并为我的复选框获取红色标题。 – 2010-03-01 17:50:49

回答

0

选项5.使用T优等作为基材的选择,并覆盖在控制了所有的绘画消息(是的,你可以把它叫做一个组成部分,但控制是可见的部件名称,以便您更应使用)的控制。简单地捕捉WM_PAINT,可能是WM_NCPAINT,您可以用自己的风格绘制控件。至少您可以重复使用控件的全部功能。只要你不改变布局,只有颜色你不需要改变hitousts mousedown。移动等等

注:我有重写TCustomEdit的经验,允许所有种类的颜色,背景文本,额外的按钮等。它花了相当一段时间才得到它的权利,并阅读MSDn的所有文件和KB以确保控制能够做到我想要的功能。

+0

我明白,不是作为选项5,而是作为选项2a和我的选项2作为选项2b; ^)! 但是为什么C#不需要重写wm_paint方法来更改复选框组件的字体颜色的颜色? – 2010-03-01 15:42:38

+0

@爱德华。名称中包含的内容不需要它:c#拥有自己的控制层(Microsoft每年为.NET环境提供一个新的控件),Delphi使用自Windows 95以来存在的相同控件。因此,更稳定,但有时你付出的代价是简单的事情变得更加困难; GDI已经很老了,但我认为在十年内,GDi仍然存在,你应该如何处理你的WinForms应用程序?考虑一下! – 2010-03-01 16:52:23

+0

我知道GDI已经很老了,我开始使用它,当我在Borland Object pascal上做了第一步,就像1988年的“windows 2”。你说的是:C#可以做到这一点,因为他们正在使用除了启用主题的delphi使用的控件之外,还有一组不同的控件?由于主题是负责绘制新的东西,我会假设delphi使用相同的组件(至少是库)比C#使用。 – 2010-03-01 18:04:34

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 classic) - 但不适用于主题模式。

你应该知道,为了让主题的控制给你这个消息时,控制应该提供DTPB_USECTLCOLORSTATIC标志的主题绘图API的。可悲的是,这不是默认行为,我也不知道如何去做。看看this的问题。

1

以下是我在我的应用程序解决了这个:

  1. 解除复选框中的标题,使之更小 - 只是大足以显示没有字幕的实际复选框。
  2. 将一个TLabel放在复选框旁边以充当标题。
  3. 在Label的OnClick事件中,切换复选框的状态。
  4. 如果标签具有Alt +字母键盘加速器,请使窗体处理CM_DIALOGCHAR消息。复制TLabel源代码中的消息处理程序,并添加一行以切换复选框的状态。

这不是一个真正的复选框,它比我想要的工作多一点,但它在我的应用程序(它只有一个复选框需要这种处理)时效果不错。

4

这需要一定的调整是完美的解决方案,但为我工作:

添加2的方法来你的CheckBox组件

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; 
+0

我相信这应该被标记为答案,很好的工作! – 2018-03-08 17:11:13

相关问题