mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-09-06 11:00:41 +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);
|
||||
var
|
||||
OldBrushColor:TColor;
|
||||
g:TGrabIndex;
|
||||
OldBrushColor: TColor;
|
||||
g: TGrabIndex;
|
||||
Diff: TPoint;
|
||||
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
|
||||
if not DC.RectVisible(RLeft, RTop, RRight, RBottom) then Exit;
|
||||
if not RestoreBrush then
|
||||
begin
|
||||
DC.Save;
|
||||
with DC.Canvas do begin
|
||||
OldBrushColor:=Brush.Color;
|
||||
Brush.Color:=GrabberColor;
|
||||
with DC.Canvas do
|
||||
begin
|
||||
OldBrushColor := Brush.Color;
|
||||
Brush.Color := GrabberColor;
|
||||
end;
|
||||
RestoreBrush:=true;
|
||||
RestoreBrush := True;
|
||||
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)));
|
||||
end;
|
||||
|
||||
begin
|
||||
if (Count=0) or (FForm=nil) or LookupRootSelected
|
||||
or OnlyInvisiblePersistentsSelected then exit;
|
||||
if (Count=0) or (FForm=nil) or LookupRootSelected or
|
||||
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;
|
||||
for g:=Low(TGrabIndex) to High(TGrabIndex) do
|
||||
RestoreBrush := False;
|
||||
for g := Low(TGrabIndex) to High(TGrabIndex) do
|
||||
FillRect(
|
||||
FGrabbers[g].Left-Diff.X
|
||||
,FGrabbers[g].Top-Diff.Y
|
||||
,FGrabbers[g].Left-Diff.X+FGrabbers[g].Width
|
||||
,FGrabbers[g].Top-Diff.Y+FGrabbers[g].Height
|
||||
);
|
||||
Include(FStates,cssGrabbersPainted);
|
||||
Include(FStates, cssGrabbersPainted);
|
||||
|
||||
if RestoreBrush then
|
||||
begin
|
||||
DC.Canvas.Brush.Color:=OldBrushColor;
|
||||
DC.Restore;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TControlSelection.DrawMarkerAt(DC: TDesignerDeviceContext;
|
||||
@ -2208,11 +2213,12 @@ var
|
||||
procedure FillRect(RLeft, RTop, RRight, RBottom: integer);
|
||||
begin
|
||||
if not DC.RectVisible(RLeft, RTop, RRight, RBottom) then exit;
|
||||
if not RestoreBrush then begin
|
||||
if not RestoreBrush then
|
||||
begin
|
||||
DC.Save;
|
||||
OldBrushColor:=DC.Canvas.Brush.Color;
|
||||
DC.Canvas.Brush.Color:=MarkerColor;
|
||||
RestoreBrush:=true;
|
||||
RestoreBrush := True;
|
||||
end;
|
||||
DC.Canvas.FillRect(Rect(RLeft,RTop,RRight,RBottom));
|
||||
end;
|
||||
@ -2225,7 +2231,10 @@ begin
|
||||
FillRect(ALeft+AWidth-MarkerSize,ATop+AHeight-MarkerSize
|
||||
,ALeft+AWidth,ATop+AHeight);
|
||||
if RestoreBrush then
|
||||
begin
|
||||
DC.Canvas.Brush.Color:=OldBrushColor;
|
||||
DC.Restore;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TControlSelection.DrawMarkers(DC: TDesignerDeviceContext);
|
||||
@ -2360,8 +2369,10 @@ var
|
||||
DrawRubberLine(x1,y2,x2,y2);
|
||||
DrawRubberLine(x1,y1,x1,y2);
|
||||
DrawRubberLine(x2,y1,x2,y2);
|
||||
if RestorePen then begin
|
||||
if RestorePen then
|
||||
begin
|
||||
DC.Canvas.Pen.Color:=OldPenColor;
|
||||
DC.Restore;
|
||||
Include(FStates,cssRubberbandPainted);
|
||||
end;
|
||||
end;
|
||||
@ -2997,7 +3008,11 @@ begin
|
||||
end;
|
||||
|
||||
if RestorePen then
|
||||
begin
|
||||
DC.Canvas.Pen.Color:=OldPenColor;
|
||||
DC.Restore;
|
||||
end;
|
||||
DC.Restore;
|
||||
Include(FStates,cssGuideLinesPainted);
|
||||
end;
|
||||
|
||||
|
@ -1202,7 +1202,7 @@ begin
|
||||
if TheMessage.DC <> 0 then begin
|
||||
Include(FFlags,dfNeedPainting);
|
||||
|
||||
DDC.SetDC(Form, TheMessage.DC);
|
||||
DDC.SetDC(Form, Sender as TWinControl, TheMessage.DC);
|
||||
{$IFDEF VerboseDesignerDraw}
|
||||
writeln('TDesigner.PaintControl D ',Sender.Name,':',Sender.ClassName,
|
||||
' DC=',DbgS(DDC.DC,8),
|
||||
@ -2570,6 +2570,7 @@ begin
|
||||
if (ControlSelection.Count > 1) and IsSelected then
|
||||
ControlSelection.DrawMarkerAt(aDDC,
|
||||
ItemLeft, ItemTop, NonVisualCompWidth, NonVisualCompWidth);
|
||||
aDDC.Restore;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
@ -2585,11 +2586,11 @@ begin
|
||||
if (Form=nil) or (not Form.HandleAllocated) then exit;
|
||||
|
||||
//writeln('TDesigner.DrawDesignerItems B painting');
|
||||
DesignerDC:=GetDesignerDC(Form.Handle);
|
||||
DDC.SetDC(Form,DesignerDC);
|
||||
DesignerDC := GetDesignerDC(Form.Handle);
|
||||
DDC.SetDC(Form, Form, DesignerDC);
|
||||
DoPaintDesignerItems;
|
||||
DDC.Clear;
|
||||
ReleaseDesignerDC(Form.Handle,DesignerDC);
|
||||
ReleaseDesignerDC(Form.Handle, DesignerDC);
|
||||
end;
|
||||
|
||||
procedure TDesigner.CheckFormBounds;
|
||||
@ -2623,22 +2624,23 @@ end;
|
||||
procedure TDesigner.DoPaintDesignerItems;
|
||||
begin
|
||||
// marker (multi selection markers)
|
||||
if (ControlSelection.SelectionForm=Form)
|
||||
and (ControlSelection.Count>1) then begin
|
||||
if (ControlSelection.SelectionForm = Form) and (ControlSelection.Count > 1) then
|
||||
begin
|
||||
ControlSelection.DrawMarkers(DDC);
|
||||
end;
|
||||
// non visual component icons
|
||||
DrawNonVisualComponents(DDC);
|
||||
// guidelines and grabbers
|
||||
if (ControlSelection.SelectionForm=Form) then begin
|
||||
if (ControlSelection.SelectionForm=Form) then
|
||||
begin
|
||||
if EnvironmentOptions.ShowGuideLines then
|
||||
ControlSelection.DrawGuideLines(DDC);
|
||||
ControlSelection.DrawGrabbers(DDC);
|
||||
end;
|
||||
// rubberband
|
||||
if ControlSelection.RubberBandActive
|
||||
and ((ControlSelection.SelectionForm=Form)
|
||||
or (ControlSelection.SelectionForm=nil)) then begin
|
||||
if ControlSelection.RubberBandActive and
|
||||
((ControlSelection.SelectionForm = Form) or (ControlSelection.SelectionForm = nil)) then
|
||||
begin
|
||||
ControlSelection.DrawRubberBand(DDC);
|
||||
end;
|
||||
end;
|
||||
|
@ -49,6 +49,7 @@ type
|
||||
private
|
||||
FCanvas: TCanvas;
|
||||
FDC: HDC;
|
||||
FDCControl: TWinControl;
|
||||
FDCOrigin: TPoint; // DC origin on desktop
|
||||
FFlags: TDesignerDCFlags;
|
||||
FFormClientOrigin: TPoint; // Form client origin on desktop
|
||||
@ -63,7 +64,7 @@ type
|
||||
public
|
||||
constructor Create;
|
||||
destructor Destroy; override;
|
||||
procedure SetDC(AForm: TCustomForm; aDC: HDC);
|
||||
procedure SetDC(AForm: TCustomForm; ADCControl: TWinControl; ADC: HDC);
|
||||
procedure Clear;
|
||||
procedure Save;
|
||||
procedure Restore;
|
||||
@ -71,11 +72,9 @@ type
|
||||
property Canvas: TCanvas read FCanvas;
|
||||
property DC: HDC read FDC;
|
||||
property Form: TCustomForm read FForm;
|
||||
property FormOrigin: TPoint
|
||||
read GetFormOrigin;// DC origin relative to designer Form
|
||||
property FormOrigin: TPoint read GetFormOrigin;// DC origin relative to designer Form
|
||||
property DCOrigin: TPoint read GetDCOrigin; // DC origin on Desktop
|
||||
property FormClientOrigin: TPoint
|
||||
read GetFormClientOrigin;// Form Client Origin on desktop
|
||||
property FormClientOrigin: TPoint read GetFormClientOrigin;// Form Client Origin on desktop
|
||||
property DCSize: TPoint read GetDCSize;
|
||||
end;
|
||||
|
||||
@ -330,12 +329,13 @@ var
|
||||
CurFormClientOrigin: TPoint;
|
||||
CurFormOrigin: TPoint;
|
||||
begin
|
||||
if not (ddcDCOriginValid in FFlags) then begin
|
||||
CurFormClientOrigin:=FormClientOrigin;
|
||||
CurFormOrigin:=FormOrigin;
|
||||
FDCOrigin.X:=CurFormOrigin.X-CurFormClientOrigin.X;
|
||||
FDCOrigin.Y:=CurFormOrigin.Y-CurFormClientOrigin.Y;
|
||||
Include(FFlags,ddcDCOriginValid);
|
||||
if not (ddcDCOriginValid in FFlags) then
|
||||
begin
|
||||
CurFormClientOrigin := FormClientOrigin;
|
||||
CurFormOrigin := FormOrigin;
|
||||
FDCOrigin.X := CurFormOrigin.X - CurFormClientOrigin.X;
|
||||
FDCOrigin.Y := CurFormOrigin.Y - CurFormClientOrigin.Y;
|
||||
Include(FFlags, ddcDCOriginValid);
|
||||
end;
|
||||
Result:=FDCOrigin;
|
||||
end;
|
||||
@ -353,20 +353,41 @@ end;
|
||||
function TDesignerDeviceContext.GetFormClientOrigin: TPoint;
|
||||
// returns the Form Client Origin on desktop
|
||||
begin
|
||||
if not (ddcFormClientOriginValid in FFlags) then begin
|
||||
FFormClientOrigin:=FForm.ClientOrigin;
|
||||
Include(FFlags,ddcFormClientOriginValid);
|
||||
if not (ddcFormClientOriginValid in FFlags) then
|
||||
begin
|
||||
FFormClientOrigin := FForm.ClientOrigin;
|
||||
Include(FFlags, ddcFormClientOriginValid);
|
||||
end;
|
||||
Result:=FFormClientOrigin;
|
||||
Result := FFormClientOrigin;
|
||||
end;
|
||||
|
||||
function TDesignerDeviceContext.GetFormOrigin: TPoint;
|
||||
// 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
|
||||
var
|
||||
AControlOrigin: TPoint;
|
||||
begin
|
||||
if not (ddcFormOriginValid in FFlags) then
|
||||
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);
|
||||
// DebugLn(['New origin: ', FFormOrigin.X, ':', FFormOrigin.Y]);
|
||||
end;
|
||||
@ -385,11 +406,12 @@ begin
|
||||
inherited Destroy;
|
||||
end;
|
||||
|
||||
procedure TDesignerDeviceContext.SetDC(AForm: TCustomForm; aDC: HDC);
|
||||
procedure TDesignerDeviceContext.SetDC(AForm: TCustomForm; ADCControl: TWinControl; ADC: HDC);
|
||||
begin
|
||||
Clear;
|
||||
FDC:=aDC;
|
||||
FForm:=AForm;
|
||||
FDC := ADC;
|
||||
FDCControl := ADCControl;
|
||||
FForm := AForm;
|
||||
end;
|
||||
|
||||
procedure TDesignerDeviceContext.Clear;
|
||||
|
Loading…
Reference in New Issue
Block a user