mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-09-08 12:39:18 +02:00
designer: fix painting (visible only on windows)
- use symmetric DC.Restore for all DC.Save calls - set control for designer DC since it is not always possible to retrieve control from DC (especially it is impossible on windows) - if GetDCOriginRelativeToWindow return False use another approach to retrieve this origin (using known DC control) - formatting git-svn-id: trunk@19064 -
This commit is contained in:
parent
dcab697872
commit
0a20153a4d
@ -2157,46 +2157,51 @@ end;
|
|||||||
|
|
||||||
procedure TControlSelection.DrawGrabbers(DC: TDesignerDeviceContext);
|
procedure TControlSelection.DrawGrabbers(DC: TDesignerDeviceContext);
|
||||||
var
|
var
|
||||||
OldBrushColor:TColor;
|
OldBrushColor: TColor;
|
||||||
g:TGrabIndex;
|
g: TGrabIndex;
|
||||||
Diff: TPoint;
|
Diff: TPoint;
|
||||||
RestoreBrush: boolean;
|
RestoreBrush: boolean;
|
||||||
|
|
||||||
procedure FillRect(RLeft,RTop,RRight,RBottom: integer);
|
procedure FillRect(RLeft, RTop, RRight, RBottom: integer);
|
||||||
|
begin
|
||||||
|
if not DC.RectVisible(RLeft, RTop, RRight, RBottom) then Exit;
|
||||||
|
if not RestoreBrush then
|
||||||
begin
|
begin
|
||||||
if not DC.RectVisible(RLeft,RTop,RRight,RBottom) then exit;
|
|
||||||
if not RestoreBrush then begin
|
|
||||||
DC.Save;
|
DC.Save;
|
||||||
with DC.Canvas do begin
|
with DC.Canvas do
|
||||||
OldBrushColor:=Brush.Color;
|
begin
|
||||||
Brush.Color:=GrabberColor;
|
OldBrushColor := Brush.Color;
|
||||||
|
Brush.Color := GrabberColor;
|
||||||
end;
|
end;
|
||||||
RestoreBrush:=true;
|
RestoreBrush := True;
|
||||||
end;
|
end;
|
||||||
DC.Canvas.FillRect(Rect(RLeft,RTop,RRight,RBottom));
|
DC.Canvas.FillRect(Rect(RLeft, RTop, RRight, RBottom));
|
||||||
//DC.Canvas.TextOut(RLeft,RTop,dbgs(ord(g)));
|
//DC.Canvas.TextOut(RLeft,RTop,dbgs(ord(g)));
|
||||||
end;
|
end;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
if (Count=0) or (FForm=nil) or LookupRootSelected
|
if (Count=0) or (FForm=nil) or LookupRootSelected or
|
||||||
or OnlyInvisiblePersistentsSelected then exit;
|
OnlyInvisiblePersistentsSelected then Exit;
|
||||||
|
|
||||||
Diff:=DC.FormOrigin;
|
Diff := DC.FormOrigin;
|
||||||
|
|
||||||
//debugln(['[DrawGrabbers] ',' DC=',Diff.X,',',Diff.Y,' Grabber1=',FGrabbers[0].Left,',',FGrabbers[0].Top]);
|
// debugln(['[DrawGrabbers] ',' DC=',Diff.X,',',Diff.Y,' Grabber1=',FGrabbers[0].Left,',',FGrabbers[0].Top]);
|
||||||
|
|
||||||
RestoreBrush:=false;
|
RestoreBrush := False;
|
||||||
for g:=Low(TGrabIndex) to High(TGrabIndex) do
|
for g := Low(TGrabIndex) to High(TGrabIndex) do
|
||||||
FillRect(
|
FillRect(
|
||||||
FGrabbers[g].Left-Diff.X
|
FGrabbers[g].Left-Diff.X
|
||||||
,FGrabbers[g].Top-Diff.Y
|
,FGrabbers[g].Top-Diff.Y
|
||||||
,FGrabbers[g].Left-Diff.X+FGrabbers[g].Width
|
,FGrabbers[g].Left-Diff.X+FGrabbers[g].Width
|
||||||
,FGrabbers[g].Top-Diff.Y+FGrabbers[g].Height
|
,FGrabbers[g].Top-Diff.Y+FGrabbers[g].Height
|
||||||
);
|
);
|
||||||
Include(FStates,cssGrabbersPainted);
|
Include(FStates, cssGrabbersPainted);
|
||||||
|
|
||||||
if RestoreBrush then
|
if RestoreBrush then
|
||||||
|
begin
|
||||||
DC.Canvas.Brush.Color:=OldBrushColor;
|
DC.Canvas.Brush.Color:=OldBrushColor;
|
||||||
|
DC.Restore;
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TControlSelection.DrawMarkerAt(DC: TDesignerDeviceContext;
|
procedure TControlSelection.DrawMarkerAt(DC: TDesignerDeviceContext;
|
||||||
@ -2208,11 +2213,12 @@ var
|
|||||||
procedure FillRect(RLeft, RTop, RRight, RBottom: integer);
|
procedure FillRect(RLeft, RTop, RRight, RBottom: integer);
|
||||||
begin
|
begin
|
||||||
if not DC.RectVisible(RLeft, RTop, RRight, RBottom) then exit;
|
if not DC.RectVisible(RLeft, RTop, RRight, RBottom) then exit;
|
||||||
if not RestoreBrush then begin
|
if not RestoreBrush then
|
||||||
|
begin
|
||||||
DC.Save;
|
DC.Save;
|
||||||
OldBrushColor:=DC.Canvas.Brush.Color;
|
OldBrushColor:=DC.Canvas.Brush.Color;
|
||||||
DC.Canvas.Brush.Color:=MarkerColor;
|
DC.Canvas.Brush.Color:=MarkerColor;
|
||||||
RestoreBrush:=true;
|
RestoreBrush := True;
|
||||||
end;
|
end;
|
||||||
DC.Canvas.FillRect(Rect(RLeft,RTop,RRight,RBottom));
|
DC.Canvas.FillRect(Rect(RLeft,RTop,RRight,RBottom));
|
||||||
end;
|
end;
|
||||||
@ -2225,7 +2231,10 @@ begin
|
|||||||
FillRect(ALeft+AWidth-MarkerSize,ATop+AHeight-MarkerSize
|
FillRect(ALeft+AWidth-MarkerSize,ATop+AHeight-MarkerSize
|
||||||
,ALeft+AWidth,ATop+AHeight);
|
,ALeft+AWidth,ATop+AHeight);
|
||||||
if RestoreBrush then
|
if RestoreBrush then
|
||||||
|
begin
|
||||||
DC.Canvas.Brush.Color:=OldBrushColor;
|
DC.Canvas.Brush.Color:=OldBrushColor;
|
||||||
|
DC.Restore;
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TControlSelection.DrawMarkers(DC: TDesignerDeviceContext);
|
procedure TControlSelection.DrawMarkers(DC: TDesignerDeviceContext);
|
||||||
@ -2360,8 +2369,10 @@ var
|
|||||||
DrawRubberLine(x1,y2,x2,y2);
|
DrawRubberLine(x1,y2,x2,y2);
|
||||||
DrawRubberLine(x1,y1,x1,y2);
|
DrawRubberLine(x1,y1,x1,y2);
|
||||||
DrawRubberLine(x2,y1,x2,y2);
|
DrawRubberLine(x2,y1,x2,y2);
|
||||||
if RestorePen then begin
|
if RestorePen then
|
||||||
|
begin
|
||||||
DC.Canvas.Pen.Color:=OldPenColor;
|
DC.Canvas.Pen.Color:=OldPenColor;
|
||||||
|
DC.Restore;
|
||||||
Include(FStates,cssRubberbandPainted);
|
Include(FStates,cssRubberbandPainted);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
@ -2997,7 +3008,11 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
if RestorePen then
|
if RestorePen then
|
||||||
|
begin
|
||||||
DC.Canvas.Pen.Color:=OldPenColor;
|
DC.Canvas.Pen.Color:=OldPenColor;
|
||||||
|
DC.Restore;
|
||||||
|
end;
|
||||||
|
DC.Restore;
|
||||||
Include(FStates,cssGuideLinesPainted);
|
Include(FStates,cssGuideLinesPainted);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
@ -1202,7 +1202,7 @@ begin
|
|||||||
if TheMessage.DC <> 0 then begin
|
if TheMessage.DC <> 0 then begin
|
||||||
Include(FFlags,dfNeedPainting);
|
Include(FFlags,dfNeedPainting);
|
||||||
|
|
||||||
DDC.SetDC(Form, TheMessage.DC);
|
DDC.SetDC(Form, Sender as TWinControl, TheMessage.DC);
|
||||||
{$IFDEF VerboseDesignerDraw}
|
{$IFDEF VerboseDesignerDraw}
|
||||||
writeln('TDesigner.PaintControl D ',Sender.Name,':',Sender.ClassName,
|
writeln('TDesigner.PaintControl D ',Sender.Name,':',Sender.ClassName,
|
||||||
' DC=',DbgS(DDC.DC,8),
|
' DC=',DbgS(DDC.DC,8),
|
||||||
@ -2570,6 +2570,7 @@ begin
|
|||||||
if (ControlSelection.Count > 1) and IsSelected then
|
if (ControlSelection.Count > 1) and IsSelected then
|
||||||
ControlSelection.DrawMarkerAt(aDDC,
|
ControlSelection.DrawMarkerAt(aDDC,
|
||||||
ItemLeft, ItemTop, NonVisualCompWidth, NonVisualCompWidth);
|
ItemLeft, ItemTop, NonVisualCompWidth, NonVisualCompWidth);
|
||||||
|
aDDC.Restore;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
@ -2585,11 +2586,11 @@ begin
|
|||||||
if (Form=nil) or (not Form.HandleAllocated) then exit;
|
if (Form=nil) or (not Form.HandleAllocated) then exit;
|
||||||
|
|
||||||
//writeln('TDesigner.DrawDesignerItems B painting');
|
//writeln('TDesigner.DrawDesignerItems B painting');
|
||||||
DesignerDC:=GetDesignerDC(Form.Handle);
|
DesignerDC := GetDesignerDC(Form.Handle);
|
||||||
DDC.SetDC(Form,DesignerDC);
|
DDC.SetDC(Form, Form, DesignerDC);
|
||||||
DoPaintDesignerItems;
|
DoPaintDesignerItems;
|
||||||
DDC.Clear;
|
DDC.Clear;
|
||||||
ReleaseDesignerDC(Form.Handle,DesignerDC);
|
ReleaseDesignerDC(Form.Handle, DesignerDC);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TDesigner.CheckFormBounds;
|
procedure TDesigner.CheckFormBounds;
|
||||||
@ -2623,22 +2624,23 @@ end;
|
|||||||
procedure TDesigner.DoPaintDesignerItems;
|
procedure TDesigner.DoPaintDesignerItems;
|
||||||
begin
|
begin
|
||||||
// marker (multi selection markers)
|
// marker (multi selection markers)
|
||||||
if (ControlSelection.SelectionForm=Form)
|
if (ControlSelection.SelectionForm = Form) and (ControlSelection.Count > 1) then
|
||||||
and (ControlSelection.Count>1) then begin
|
begin
|
||||||
ControlSelection.DrawMarkers(DDC);
|
ControlSelection.DrawMarkers(DDC);
|
||||||
end;
|
end;
|
||||||
// non visual component icons
|
// non visual component icons
|
||||||
DrawNonVisualComponents(DDC);
|
DrawNonVisualComponents(DDC);
|
||||||
// guidelines and grabbers
|
// guidelines and grabbers
|
||||||
if (ControlSelection.SelectionForm=Form) then begin
|
if (ControlSelection.SelectionForm=Form) then
|
||||||
|
begin
|
||||||
if EnvironmentOptions.ShowGuideLines then
|
if EnvironmentOptions.ShowGuideLines then
|
||||||
ControlSelection.DrawGuideLines(DDC);
|
ControlSelection.DrawGuideLines(DDC);
|
||||||
ControlSelection.DrawGrabbers(DDC);
|
ControlSelection.DrawGrabbers(DDC);
|
||||||
end;
|
end;
|
||||||
// rubberband
|
// rubberband
|
||||||
if ControlSelection.RubberBandActive
|
if ControlSelection.RubberBandActive and
|
||||||
and ((ControlSelection.SelectionForm=Form)
|
((ControlSelection.SelectionForm = Form) or (ControlSelection.SelectionForm = nil)) then
|
||||||
or (ControlSelection.SelectionForm=nil)) then begin
|
begin
|
||||||
ControlSelection.DrawRubberBand(DDC);
|
ControlSelection.DrawRubberBand(DDC);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
@ -49,6 +49,7 @@ type
|
|||||||
private
|
private
|
||||||
FCanvas: TCanvas;
|
FCanvas: TCanvas;
|
||||||
FDC: HDC;
|
FDC: HDC;
|
||||||
|
FDCControl: TWinControl;
|
||||||
FDCOrigin: TPoint; // DC origin on desktop
|
FDCOrigin: TPoint; // DC origin on desktop
|
||||||
FFlags: TDesignerDCFlags;
|
FFlags: TDesignerDCFlags;
|
||||||
FFormClientOrigin: TPoint; // Form client origin on desktop
|
FFormClientOrigin: TPoint; // Form client origin on desktop
|
||||||
@ -63,7 +64,7 @@ type
|
|||||||
public
|
public
|
||||||
constructor Create;
|
constructor Create;
|
||||||
destructor Destroy; override;
|
destructor Destroy; override;
|
||||||
procedure SetDC(AForm: TCustomForm; aDC: HDC);
|
procedure SetDC(AForm: TCustomForm; ADCControl: TWinControl; ADC: HDC);
|
||||||
procedure Clear;
|
procedure Clear;
|
||||||
procedure Save;
|
procedure Save;
|
||||||
procedure Restore;
|
procedure Restore;
|
||||||
@ -71,11 +72,9 @@ type
|
|||||||
property Canvas: TCanvas read FCanvas;
|
property Canvas: TCanvas read FCanvas;
|
||||||
property DC: HDC read FDC;
|
property DC: HDC read FDC;
|
||||||
property Form: TCustomForm read FForm;
|
property Form: TCustomForm read FForm;
|
||||||
property FormOrigin: TPoint
|
property FormOrigin: TPoint read GetFormOrigin;// DC origin relative to designer Form
|
||||||
read GetFormOrigin;// DC origin relative to designer Form
|
|
||||||
property DCOrigin: TPoint read GetDCOrigin; // DC origin on Desktop
|
property DCOrigin: TPoint read GetDCOrigin; // DC origin on Desktop
|
||||||
property FormClientOrigin: TPoint
|
property FormClientOrigin: TPoint read GetFormClientOrigin;// Form Client Origin on desktop
|
||||||
read GetFormClientOrigin;// Form Client Origin on desktop
|
|
||||||
property DCSize: TPoint read GetDCSize;
|
property DCSize: TPoint read GetDCSize;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -330,12 +329,13 @@ var
|
|||||||
CurFormClientOrigin: TPoint;
|
CurFormClientOrigin: TPoint;
|
||||||
CurFormOrigin: TPoint;
|
CurFormOrigin: TPoint;
|
||||||
begin
|
begin
|
||||||
if not (ddcDCOriginValid in FFlags) then begin
|
if not (ddcDCOriginValid in FFlags) then
|
||||||
CurFormClientOrigin:=FormClientOrigin;
|
begin
|
||||||
CurFormOrigin:=FormOrigin;
|
CurFormClientOrigin := FormClientOrigin;
|
||||||
FDCOrigin.X:=CurFormOrigin.X-CurFormClientOrigin.X;
|
CurFormOrigin := FormOrigin;
|
||||||
FDCOrigin.Y:=CurFormOrigin.Y-CurFormClientOrigin.Y;
|
FDCOrigin.X := CurFormOrigin.X - CurFormClientOrigin.X;
|
||||||
Include(FFlags,ddcDCOriginValid);
|
FDCOrigin.Y := CurFormOrigin.Y - CurFormClientOrigin.Y;
|
||||||
|
Include(FFlags, ddcDCOriginValid);
|
||||||
end;
|
end;
|
||||||
Result:=FDCOrigin;
|
Result:=FDCOrigin;
|
||||||
end;
|
end;
|
||||||
@ -353,20 +353,41 @@ end;
|
|||||||
function TDesignerDeviceContext.GetFormClientOrigin: TPoint;
|
function TDesignerDeviceContext.GetFormClientOrigin: TPoint;
|
||||||
// returns the Form Client Origin on desktop
|
// returns the Form Client Origin on desktop
|
||||||
begin
|
begin
|
||||||
if not (ddcFormClientOriginValid in FFlags) then begin
|
if not (ddcFormClientOriginValid in FFlags) then
|
||||||
FFormClientOrigin:=FForm.ClientOrigin;
|
begin
|
||||||
Include(FFlags,ddcFormClientOriginValid);
|
FFormClientOrigin := FForm.ClientOrigin;
|
||||||
|
Include(FFlags, ddcFormClientOriginValid);
|
||||||
end;
|
end;
|
||||||
Result:=FFormClientOrigin;
|
Result := FFormClientOrigin;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TDesignerDeviceContext.GetFormOrigin: TPoint;
|
function TDesignerDeviceContext.GetFormOrigin: TPoint;
|
||||||
// returns the DC origin relative to the form client origin
|
// returns the DC origin relative to the form client origin
|
||||||
// For example: The DC of the client area of the form itself will return 0,0
|
// For example: The DC of the client area of the form itself will return 0,0
|
||||||
|
var
|
||||||
|
AControlOrigin: TPoint;
|
||||||
begin
|
begin
|
||||||
if not (ddcFormOriginValid in FFlags) then
|
if not (ddcFormOriginValid in FFlags) then
|
||||||
begin
|
begin
|
||||||
GetDCOriginRelativeToWindow(FDC, FForm.Handle, FFormOrigin);
|
if not GetDCOriginRelativeToWindow(FDC, FForm.Handle, FFormOrigin) then
|
||||||
|
begin
|
||||||
|
// For some reason we cannot retrieve DC origin. It can happen for exmample
|
||||||
|
// when DC is not controld DC but double buffer DC. Lets use another trick
|
||||||
|
if FDCControl <> nil then
|
||||||
|
begin
|
||||||
|
AControlOrigin := FDCControl.ClientToScreen(Point(0, 0));
|
||||||
|
FFormOrigin := FForm.ClientToScreen(Point(0, 0));
|
||||||
|
FFormOrigin.X := AControlOrigin.X - FFormOrigin.X;
|
||||||
|
FFormOrigin.Y := AControlOrigin.Y - FFormOrigin.Y;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
FFormOrigin := Point(0, 0);
|
||||||
|
if GetWindowOrgEx(FDC, @AControlOrigin) <> 0 then
|
||||||
|
begin
|
||||||
|
Dec(FFormOrigin.X, AControlOrigin.X);
|
||||||
|
Dec(FFormOrigin.Y, AControlOrigin.Y);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
Include(FFlags, ddcFormOriginValid);
|
Include(FFlags, ddcFormOriginValid);
|
||||||
// DebugLn(['New origin: ', FFormOrigin.X, ':', FFormOrigin.Y]);
|
// DebugLn(['New origin: ', FFormOrigin.X, ':', FFormOrigin.Y]);
|
||||||
end;
|
end;
|
||||||
@ -385,11 +406,12 @@ begin
|
|||||||
inherited Destroy;
|
inherited Destroy;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TDesignerDeviceContext.SetDC(AForm: TCustomForm; aDC: HDC);
|
procedure TDesignerDeviceContext.SetDC(AForm: TCustomForm; ADCControl: TWinControl; ADC: HDC);
|
||||||
begin
|
begin
|
||||||
Clear;
|
Clear;
|
||||||
FDC:=aDC;
|
FDC := ADC;
|
||||||
FForm:=AForm;
|
FDCControl := ADCControl;
|
||||||
|
FForm := AForm;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TDesignerDeviceContext.Clear;
|
procedure TDesignerDeviceContext.Clear;
|
||||||
|
Loading…
Reference in New Issue
Block a user