Author: Tomas Rutkauskas
How to modify the color of a TCheckBox
Answer:
I would do the drawing in the CN_DRAWITEM message handler. Below is the code of
such a checkbox:
1 { ... }
2 type
3 TMyCheckBox = class(TCheckBox)
4 protected
5 procedure CNDrawItem(var message: TWMDrawItem); message CN_DRAWITEM;
6 procedure CMEnabledchanged(var message: TMessage); message CM_ENABLEDCHANGED;
7 procedure CreateParams(var Params: TCreateParams); override;
8 procedure CreateWnd; override;
9 procedure SetChecked(Value: Boolean); override;
10 procedure SetButtonStyle;
11 public
12 constructor Create(AOwner: TComponent); override;
13 end;
14
15 { ... }
16
17 constructor TMyCheckBox.Create(AOwner: TComponent);
18 begin
19 inherited Create(AOwner);
20 ControlStyle := ControlStyle - [csDoubleClicks];
21 end;
22
23 procedure TMyCheckBox.CNDrawItem(var message: TWMDrawItem);
24 var
25 XCanvas: TCanvas;
26 XCaptionRect, XGlyphRect: TRect;
27
28 procedure xxDrawBitMap(ACanvas: TCanvas);
29 const
30 xx_h = 13;
31 xx_w = 13;
32 var
33 xxGlyph: TBitmap;
34 xxX, xxY, xxStepY, xxStepX: integer;
35 begin
36 xxGlyph := TBitmap.Create;
37 try
38 xxGlyph.Handle := LoadBitmap(0, PChar(OBM_CHECKBOXES));
39 xxY := XGlyphRect.Top + (XGlyphRect.Bottom - XGlyphRect.Top - xx_h) div 2;
40 xxX := 2;
41 xxStepX := 0;
42 xxStepY := 0;
43 if Enabled then
44 begin
45 case State of
46 cbChecked:
47 xxStepX := xxStepX + xx_w;
48 cbGrayed:
49 xxStepX := xxStepX + xx_w * 3;
50 end;
51 end
52 else if State = cbChecked then
53 xxStepX := xxStepX + xx_w * 3
54 else
55 xxStepX := xxStepX + xx_w * 2;
56 ACanvas.CopyRect(Rect(xxX, xxY, xxX + xx_w, xxY + xx_h), xxGlyph.Canvas,
57 Rect(xxStepX, xxStepY, xx_w + xxStepX, xx_h + xxStepY));
58 finally
59 xxGlyph.Free;
60 end;
61 end;
62
63 procedure xxDrawCaption;
64 var
65 xXFormat: longint;
66 begin
67 xXFormat := DT_VCENTER + DT_SINGLELINE + DT_LEFT;
68 xXFormat := DrawTextBiDiModeFlags(xXFormat);
69 DrawText(message.DrawItemStruct.hDC, PChar(Caption),
70 length(Caption), XCaptionRect, xXFormat);
71 end;
72
73 begin
74 XGlyphRect := message.DrawItemStruct.rcItem;
75 XGlyphRect.Right := 20;
76 XCaptionRect := message.DrawItemStruct.rcItem;
77 XCaptionRect.Left := XGlyphRect.Right;
78 XCanvas := TCanvas.Create;
79 try
80 XCanvas.Handle := message.DrawItemStruct.hDC;
81 XCanvas.Brush.Style := bsClear;
82 xxDrawBitMap(XCanvas);
83 xxDrawCaption;
84 finally
85 XCanvas.Free;
86 end;
87 end;
88
89 procedure TMyCheckBox.CMEnabledchanged(var message: TMessage);
90 begin
91 inherited;
92 Invalidate;
93 end;
94
95 procedure TMyCheckBox.CreateParams(var Params: TCreateParams);
96 begin
97 inherited CreateParams(Params);
98 Params.ExStyle := Params.ExStyle or WS_EX_Transparent;
99 end;
100
101 procedure TMyCheckBox.CreateWnd;
102 begin
103 inherited CreateWnd;
104 SetButtonStyle;
105 end;
106
107 procedure TMyCheckBox.SetChecked(Value: Boolean);
108 begin
109 inherited SetChecked(Value);
110 Invalidate;
111 end;
112
113 procedure TMyCheckBox.SetButtonStyle;
114 const
115 BS_MASK = $000F;
116 var
117 Style: Word;
118 begin
119 if HandleAllocated then
120 begin
121 Style := BS_CHECKBOX or BS_OWNERDRAW;
122 if GetWindowLong(Handle, GWL_STYLE) and BS_MASK <> Style then
123 SendMessage(Handle, BM_SETSTYLE, Style, 1);
124 end;
125 end;
|