procedure TCheckBox.WndProc(var Message: TLMessage);
var
LBitmap: TCustomBitmap;
LDC: HDC;
LCanvas: TCanvas;
begin
inherited;
case Message.Msg of
LM_DESTROY: begin // LM_DESTROY
end; // LM_DESTROY
LM_PAINT: begin // LM_PAINT
LCanvas := TCanvas.Create;
try
LDC := GetDC(Self.Handle);
try
LCanvas.Handle := LDC;
CreateImage(LBitmap{%H-});
try
LCanvas.Draw(0, 0, LBitmap);
finally
LBitmap.Free;
end;
finally
ReleaseDC(Self.Handle, LDC);
end;
finally
LCanvas.Free;
end;
end; // LM_PAINT
end; // case Message.Msg of
end;
procedure TCheckBox.SetTransparent(const AValue: Boolean);
begin
if FTransparent = AValue then
Exit;
FTransparent := AValue;
Self.Invalidate;
end;
procedure TCheckBox.CreateImage(var AImage: TCustomBitmap);
var
LBitmap: TCustomBitmap;
LBackground: TColor;
LRect: TRect;
begin
// setup background color
if Self.Color = clDefault then
LBackground := Self.GetDefaultColor(dctBrush)
else
LBackground := Self.Color;
// create image to paint on
LBitmap := Graphics.TCustomBitmap.Create{%H-};
try
// setup defaults
LBitmap.SetSize(Self.ClientWidth, Self.ClientHeight);
LBitmap.Canvas.AntialiasingMode := amDontCare; //amOn;
LBitmap.Canvas.CopyMode := cmSrcCopy;
// setup font
LBitmap.Canvas.Font := Self.Font;
if Self.Font.Color = clDefault then
LBitmap.Canvas.Font.Color := Self.GetDefaultColor(dctFont);
// alpha test: transparency
// does not work :D (LBitmap is transparent but the control is not)
// currently it would let original CheckBox painting shine thru
if FTransparent then
begin
LBitmap.TransparentMode := tmFixed;
LBitmap.TransparentColor := LBackground;
LBitmap.Transparent := True;
end;
// setup initial canvas values
LBitmap.Canvas.Brush.Color := LBackground;
LBitmap.Canvas.Brush.Style := bsSolid;
LBitmap.Canvas.Pen.Style := psSolid;
// add small effect when the mouse is over the control
if FMouseOver then
LBitmap.Canvas.Pen.Color := clBtnHighlight
else
LBitmap.Canvas.Pen.Color := clBlack;
LBitmap.Canvas.Pen.Width := 1;
// clear image
LBitmap.Canvas.FillRect(LBitmap.Canvas.ClipRect);
// prepare circle coordinates
LRect.Top := (LBitmap.Canvas.Height - 13) div 2;
if (Self.Alignment = taRightJustify) and (Self.BiDiMode <> bdRightToLeft) then
LRect.Left := 2;
if (
((Self.Alignment = taRightJustify) and (Self.BiDiMode = bdRightToLeft))
or
((Self.Alignment = taLeftJustify) and (Self.BiDiMode = bdRightToLeft))
or
((Self.Alignment = taLeftJustify) and (Self.BiDiMode = bdLeftToRight))
)
then
LRect.Left := LBitmap.Canvas.ClipRect.Width - 15;
LRect.Right := LRect.Left + 13;
LRect.Bottom := LRect.Top + 13;
// choose color by current state
if Self.Checked or (Self.State = cbChecked) then
LBitmap.Canvas.Brush.Color := clLime;
if (not Self.Checked) or (Self.State = cbUnchecked) then
LBitmap.Canvas.Brush.Color := clRed;
if (Self.State = cbGrayed) then
LBitmap.Canvas.Brush.Color := clMedGray;
LBitmap.Canvas.Ellipse(LRect);
// prepare color and write text
LBitmap.Canvas.Brush.Color := LBackground;
if (Self.Alignment = taRightJustify) and (Self.BiDiMode <> bdRightToLeft) then
LBitmap.Canvas.TextOut(16, (LBitmap.Canvas.Height - LBitmap.Canvas.TextHeight(Self.Caption)) div 2, Self.Caption)
else
LBitmap.Canvas.TextOut(1, (LBitmap.Canvas.Height - LBitmap.Canvas.TextHeight(Self.Caption)) div 2, Self.Caption);
// when focused draw a rectangle around
if Self.Focused then
begin
LBitmap.Canvas.Brush.Color := clActiveCaption;
LBitmap.Canvas.FrameRect(LBitmap.Canvas.ClipRect);
end;
// transport image
AImage := TCustomBitmap.Create;
AImage.Assign(LBitmap);
finally
LBitmap.Free;
end;
end;
procedure TCheckBox.MouseEnter;
begin
FMouseOver := True;
inherited MouseEnter;
end;
procedure TCheckBox.MouseLeave;
begin
FMouseOver := False;
inherited MouseLeave;
end;