function RenderWinControl(var AImage: TLazIntfImage; var ACanvas: TLazCanvas;
ACDWinControl: TCDWinControl; ACDForm: TCDForm): Boolean;
var
lWinControl, lParentControl: TWinControl;
struct : TPaintStruct;
lCanvas: TCanvas;
lControlCanvas: TLazCanvas;
lBaseWindowOrg: TPoint;
lControlStateEx: TCDControlStateEx;
lDrawControl: Boolean;
lRegion:TLazRegionWithChilds;
begin
Result := False;
lWinControl := ACDWinControl.WinControl;
{$ifdef VerboseCDWinControl}
DebugLn(Format('[RenderWinControl] lWinControl=%x Name=%s:%s Left=%d'
+ ' Top=%d Width=%d Height=%d', [PtrInt(lWinControl), lWinControl.Name, lWinControl.ClassName,
lWinControl.Left, lWinControl.Top, lWinControl.Width, lWinControl.Height]));
{$endif}
if lWinControl.Visible = False then Exit;
// Disable the drawing itself, but keep the window org and region operations
// or else clicking and other things are broken
lDrawControl := ACDWinControl.IsControlBackgroundVisible();
// Save the Canvas state
ACanvas.SaveState;
ACanvas.ResetCanvasState;
// lBaseWindowOrg makes debugging easier
// Iterate to find the appropriate BaseWindowOrg relative to the parent control
lBaseWindowOrg := FindControlPositionRelativeToTheForm(lWinControl);
ACanvas.BaseWindowOrg := Point(lBaseWindowOrg.X, lBaseWindowOrg.Y - ACDForm.ScrollY);
ACanvas.WindowOrg := Point(0, 0);
// Prepare the clippping relative to the form
ACanvas.Clipping := True;
ACDWinControl.Region.Rect := Bounds(lBaseWindowOrg.X, lBaseWindowOrg.Y - ACDForm.ScrollY,
lWinControl.Width, lWinControl.Height);
lRegion := TLazRegionWithChilds.Create;
lRegion.Assign(ACDWinControl.Region);
ACanvas.ClipRegion := lRegion;
lControlCanvas := ACanvas;
if (ACDWinControl.InvalidateCount > 0) and lDrawControl then
begin
ACDWinControl.UpdateImageAndCanvas();
lControlCanvas := ACDWinControl.ControlCanvas;
ACDWinControl.InvalidateCount := 0;
// Special drawing for some native controls
if (lWinControl is TCustomPanel) or (lWinControl is TTabSheet)
or (lWinControl is TCustomPage) or (lWinControl is TNotebook) then
begin
// Erase the background of TPanel controls, since it can draw it's own border, but fails to draw it's own background
// and also erase the background for TTabSheet (children of TPageControl) and TCustomPage (children of TNotebook)
lControlCanvas.SaveState;
lControlCanvas.Brush.FPColor := TColorToFPColor(lWinControl.GetRGBColorResolvingParent());
lControlCanvas.Pen.FPColor := lControlCanvas.Brush.FPColor;
lControlCanvas.Rectangle(Bounds(0, 0, lWinControl.Width, lWinControl.Height));
lControlCanvas.RestoreState(-1);
end
else if lWinControl is TCustomGroupBox then
begin
lControlCanvas.SaveState;
lControlStateEx := TCDControlStateEx.Create;
try
lControlStateEx.Font := lWinControl.Font;
lControlStateEx.Caption := lWinControl.Caption;
lControlStateEx.ParentRGBColor := lWinControl.GetRGBColorResolvingParent();
GetDefaultDrawer().DrawGroupBox(lControlCanvas, Point(0,0),
Size(lWinControl.Width, lWinControl.Height), [], lControlStateEx);
finally
lControlStateEx.Free;
lControlCanvas.RestoreState(-1);
end;
end;
// Send the drawing message
{$ifdef VerboseCDWinControl}
DebugLn('[RenderWinControl] before LCLSendPaintMsg');
{$endif}
FillChar(struct, SizeOf(TPaintStruct), 0);
struct.hdc := HDC(lControlCanvas);
LCLSendEraseBackgroundMsg(lWinControl, struct.hdc);
LCLSendPaintMsg(lWinControl, struct.hdc, @struct);
{$ifdef VerboseCDWinControl}
DebugLn('[RenderWinControl] after LCLSendPaintMsg');
{$endif}
end;
// Here we actually blit the control to the form canvas
if lDrawControl then
ACanvas.CanvasCopyRect(ACDWinControl.ControlCanvas, 0, 0, 0, 0,
lWinControl.Width, lWinControl.Height);
// Now restore it
ACanvas.RestoreState(-1);
Result := True;
end;