Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can you change the font color of a theme-enabled control?

Tags:

themes

delphi

Yes, this is again this question:

How can I change the font color of a TCheckBox (or any handled control) with Delphi7->Delphi2007 on a themes enabled application?

After reading a lot on the internet and on this site, I found 4 kinds of answer:

  1. and Most populare (even from QC): You can't, it's designed like that by Microsoft.
  2. Create a component that let you draw it like you want.
  3. Buy expensive component set that draws like you want.
  4. Do not use themes.

OK, but I am still unhappy with that.

Giving a user colored feedback for the status of a property/data he has on a form, seems legitimate to me.

Then I just installed the MSVC# 2008 Express edition, and what a surprise, they can change the color of the font (property ForeColor of the check box) Then what?

It does not seem to be a "it's designed like that, by Microsoft." then now the question again:

How can I change the font color of a TCheckBox (or any handled control) with Delphi 7 through Delphi 2007 on a theme-enabled application?

like image 266
Edouard Westphal Avatar asked Mar 01 '10 14:03

Edouard Westphal


3 Answers

This needs some tweak to be perfect solution but worked for me:

Add 2 method to your checkbox component

    FOriginalCaption: string;
    _MySetCap: Boolean;
    procedure WMPaint(var msg: TWMPaint); message WM_PAINT;
    procedure CMTextChanged(var Message: TMessage); message CM_TEXTCHANGED;

and implement this way:

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;
like image 186
FLICKER Avatar answered Nov 15 '22 22:11

FLICKER


Oh, but you can!

Just place this before the declaration of your form :

TCheckBox = class(StdCtrls.TCheckBox)
public
  procedure CNCtlColorStatic(var Message: TWMCtlColorStatic); message CN_CTLCOLORSTATIC;
end;

This re-declaration of TCheckBox is now used at runtime as the type streamed from your form's DFM. Now implement the message like this :

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;

This traps the WM_CTLCOLORSTATIC message and changes the text color to red. This works in non-themed mode for me (using WinXP classic) - but not in themed mode.

You should know that in order to let themed controls send you this message, the control should supply the DTPB_USECTLCOLORSTATIC flag to the Theme-drawing API's. Sadly, that's not default behaviour, and I don't know how to do it either. Look at this question too.

like image 26
PatrickvL Avatar answered Nov 15 '22 21:11

PatrickvL


Here's how I solved this in my app:

  1. Remove the caption from the checkbox and make it smaller--just big enough to show the actual checkbox without the caption.
  2. Put a TLabel next to the checkbox to act as the caption.
  3. In the Label's OnClick event, toggle the state of the checkbox.
  4. If the label has an Alt+letter keyboard accelerator, make the form handle the CM_DIALOGCHAR message. Copy the message handler from the TLabel source code and add a line to toggle the state of the checkbox.

It's not a real checkbox, and it's a bit more work than I'd like, but it works well enough in my app (which has only one checkbox that needs this treatment).

like image 32
Jan Goyvaerts Avatar answered Nov 15 '22 21:11

Jan Goyvaerts