tags:

views:

451

answers:

2

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?

A: 

Option 5. Use the control tyou like as a base option and override all the painting messages in the control (yes you can call it a component but control is the name for visible components so you should rather use that). Simply catch the WM_PAINT, possibly the WM_NCPAINT you can draw the control in your own style. At least you can reuse the whole functionality from the control. As long as you do not change the lay-out, only the colors you won't need to change the hittests mousedowns. up moves etc etc.

Note: I have the experience with overriding TCustomEdit to allow for all kind of colors, background text, extra buttons etc. It took quite some time to get it right and read all the documents from MSDn and KB to make sure the control did what I wanted it to do.

Ritsaert Hornstra
I understand that not as option 5, but as option 2a and my option 2 as option 2b ;^) ! But Why does C# does not need to override the wm_paint methode to change the color of the font color of a Checkbox component ?
Edouard Westphal
@Edouard. What's in a Name.. about the C# does not need it: c# has it's own control layer (Microsoft invents a new one for the .NET environment every so many years), Delphi uses the same controls that exists since Windows 95. Hence much more stability but sometimes you pay for that something simple gets more difficult; GDI is old but I think that in 10 years GDi is still around and what should you do with your WinForms app? Think about that!
Ritsaert Hornstra
I know that the GDI is quite old, I started worked with it, when i did my first step on Borland Object pascal on "windows 2" something like 1988. What you are saying is: C# can do that, because they are using a totaly different bunch of controls than the one used by delphi while themes are enabled ? As the Theme thing is responsible of drawing the new stuff, i would suppose that delphi is using the same components (ort at least library) than C# use.
Edouard Westphal
By the way, I have now also tested that on Access2003: Create form, add a checkbox, then set forecolor to red, and here also its working (Themed components + colored checkboxes) !!! and I am juste sure that Access2003 is designed for using older GDI than Delphi2007.
Edouard Westphal
@Edouard: Access uses its own custom control library (option 2.) Re C#: it depends which library you're talking about (WinForms, WPF, ...?) but if it's WinForms, it wraps and probably extends (option 2!) the inbuilt Windows controls. If it's something like WPF then it's a completely different control library.
David M
Why don't you like the answers you've already got? The options you list are accurate and valid - you can't just say "I don't like them, so I'll ask again."
David M
A: 

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.

PatrickvL