diff --git a/lcl/interfaces/qt/qtwidgets.pas b/lcl/interfaces/qt/qtwidgets.pas index c67c6ee22d..ffedbb3e91 100644 --- a/lcl/interfaces/qt/qtwidgets.pas +++ b/lcl/interfaces/qt/qtwidgets.pas @@ -156,6 +156,7 @@ type procedure ShowMaximized; function getActionByIndex(AIndex: Integer): QActionH; function getClientBounds: TRect; virtual; + function getClientOffset: TPoint; function getEnabled: Boolean; function getFocusPolicy: QtFocusPolicy; function getFrameGeometry: TRect; @@ -402,6 +403,7 @@ type TQtMainWindow = class(TQtWidget) private LayoutWidget: QBoxLayoutH; + FCWEventHook: QObject_hookH; protected function CreateWidget(const AParams: TCreateParams):QWidgetH; override; public @@ -411,7 +413,6 @@ type ToolBar: TQtToolBar; StatusBar: TQtStatusBar; destructor Destroy; override; - function getClientBounds: TRect; override; function getText: WideString; override; function getTextStatic: Boolean; override; procedure setText(const W: WideString); override; @@ -421,6 +422,10 @@ type procedure OffsetMousePos(APoint: PQtPoint); override; procedure SlotWindowStateChange; cdecl; procedure setShowInTaskBar(AValue: Boolean); + public + procedure AttachEvents; override; + procedure DetachEvents; override; + function CWEventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl; end; { TQtHintWindow } @@ -1197,6 +1202,7 @@ begin inherited Create; FOwner := nil; + FCentralWidget := nil; FOwnWidget := True; // Initializes the properties FProps := nil; @@ -1215,6 +1221,7 @@ begin FOwner := nil; FOwnWidget := False; + FCentralWidget := nil; // Initializes the properties FProps := niL; LCLObject := AWinControl; @@ -2210,8 +2217,8 @@ begin Msg.PaintStruct^.hdc := FContext; - with getClientBounds do - SetWindowOrgEx(Msg.DC, -Left, -Top, nil); + with getClientOffset do + SetWindowOrgEx(Msg.DC, -X, -Y, nil); // send paint message try @@ -2344,10 +2351,10 @@ end; procedure TQtWidget.OffsetMousePos(APoint: PQtPoint); begin - with getClientBounds do + with getClientOffset do begin - dec(APoint^.x, Left); - dec(APoint^.y, Top); + dec(APoint^.x, x); + dec(APoint^.y, y); end; end; @@ -2546,7 +2553,17 @@ end; function TQtWidget.getClientBounds: TRect; begin - QWidget_contentsRect(Widget, @Result); + QWidget_contentsRect(getContainerWidget, @Result); +end; + +function TQtWidget.getClientOffset: TPoint; +var + P: TQtPoint; + R: TRect; +begin + QWidget_pos(GetContainerWidget, @P); + R := getClientBounds; + Result := Point(P.x + R.Left, P.y + R.Top); end; procedure TQtWidget.grabMouse; @@ -3649,20 +3666,6 @@ begin inherited Destroy; end; -function TQtMainWindow.getClientBounds: TRect; -var - R: TRect; -begin - Result := inherited getClientBounds; - if (MenuBar <> nil) and (MenuBar.getVisible) and - not (TCustomForm(LCLObject).FormStyle in [fsMDIForm, fsMDIChild]) then - begin - R := MenuBar.getGeometry; - if TCustomForm(LCLObject).FormStyle <> fsMDIChild then - inc(Result.Top, R.Bottom - R.Top); - end; -end; - function TQtMainWindow.getText: WideString; begin WindowTitle(@Result); @@ -3779,6 +3782,46 @@ begin end; end; +procedure TQtMainWindow.AttachEvents; +var + Method: TMethod; +begin + inherited AttachEvents; + + if FCentralWidget <> nil then + begin + FCWEventHook := QObject_hook_create(FCentralWidget); + TEventFilterMethod(Method) := @CWEventFilter; + QObject_hook_hook_events(FCWEventHook, Method); + end; +end; + +procedure TQtMainWindow.DetachEvents; +begin + if FCWEventHook <> nil then + begin + QObject_hook_destroy(FCWEventHook); + FCWEventHook := nil; + end; + + inherited DetachEvents; +end; + +function TQtMainWindow.CWEventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl; +begin + Result := False; + if LCLObject <> nil then + begin + case QEvent_type(Event) of + QEventResize: + begin + LCLObject.InvalidateClientRectCache(true); + LCLObject.DoAdjustClientRectChange; + end; + end; + end; +end; + { TQtStaticText } function TQtStaticText.CreateWidget(const AParams: TCreateParams): QWidgetH; @@ -7389,7 +7432,10 @@ end; function TQtAbstractScrollArea.GetContainerWidget: QWidgetH; begin - Result := viewport.Widget; + if ClassType = TQtAbstractScrollArea then + Result := viewport.Widget + else + Result := Widget; end; function TQtAbstractScrollArea.getClientBounds: TRect; @@ -8188,8 +8234,8 @@ begin Msg.PaintStruct^.hdc := FDesignContext; - with getClientBounds do - SetWindowOrgEx(Msg.DC, -Left, -Top, nil); + with getClientOffset do + SetWindowOrgEx(Msg.DC, -X, -Y, nil); // send paint message try diff --git a/lcl/interfaces/qt/qtwinapi.inc b/lcl/interfaces/qt/qtwinapi.inc index 4e7f7741e3..97c5782797 100644 --- a/lcl/interfaces/qt/qtwinapi.inc +++ b/lcl/interfaces/qt/qtwinapi.inc @@ -148,20 +148,14 @@ end; function TQtWidgetSet.ClientToScreen(Handle: HWND; var P: TPoint) : Boolean; var APoint: TQtPoint; - R: TRect; begin - Result := True; - if Handle <> 0 then + Result := Handle <> 0; + if Result then begin - APoint.x := P.X; - APoint.y := P.Y; + APoint := QtPoint(P.X, P.Y); - QWidget_mapToGlobal(TQtWidget(Handle).Widget, @APoint, @APoint); - P.X := APoint.x; - P.Y := APoint.y; - R := TQtWidget(Handle).getClientBounds; - inc(P.X, R.Left); - inc(P.Y, R.Top); + QWidget_mapToGlobal(TQtWidget(Handle).GetContainerWidget, @APoint, @APoint); + P := Point(APoint.x, APoint.y); end; end; @@ -1806,7 +1800,6 @@ begin {$endif} ARect := TQtWidget(handle).getClientBounds; - Result := True; end; @@ -1826,9 +1819,8 @@ begin WriteLn('[WinAPI GetClientRect]'); {$endif} - ARect := TQtWidget(handle).getClientBounds; + GetClientBounds(Handle, ARect); OffsetRect(ARect, -ARect.Left, -ARect.Top); - //WriteLn('ClientRect: ', dbgsName(TQtWidget(handle).LCLObject), ' Width = ', ARect.Right, ' Height = ', ARect.Bottom); Result := True; end; @@ -3102,6 +3094,7 @@ function TQtWidgetSet.GetWindowRect(Handle: HWND; var ARect: TRect): Integer; var APos: TQtPoint; AParent: QWidgetH; + R1: TRect; begin {$ifdef VerboseQtWinAPI} WriteLn('[WinAPI GetWindowRect]'); @@ -3122,10 +3115,15 @@ begin if AParent <> nil then QWidget_mapToGlobal(AParent, @APos, @APos); + R1 := TQtWidget(Handle).getFrameGeometry; + ARect.Left := APos.x; ARect.Top := APos.y; - ARect.Bottom := ARect.Top + TQtWidget(Handle).getHeight; - ARect.Right := ARect.Left + TQtWidget(Handle).getWidth; + with R1 do + begin + ARect.Right := ARect.Left + (Right - Left); + ARect.Bottom := ARect.Top + (Bottom - Top); + end; Result := -1; end; @@ -3165,10 +3163,11 @@ begin WriteLn('[WinAPI GetWindowSize]'); {$endif} - Result := False; - - Height := TQtWidget(Handle).getHeight; - Width := TQtWidget(Handle).getWidth; + with TQtWidget(Handle).getSize do + begin + Height := cy; + Width := cx; + end; Result := True; @@ -3446,8 +3445,6 @@ end; ------------------------------------------------------------------------------} function TQtWidgetSet.InvalidateRect(aHandle: HWND; Rect: pRect; bErase: Boolean): Boolean; -var - R: TRect; begin {$ifdef VerboseQtWinAPI} WriteLn('[WinAPI Invalidate Rect]'); @@ -3455,8 +3452,8 @@ begin if Rect <> nil then begin - R := TQtWidget(aHandle).getClientBounds; - OffsetRect(Rect^, R.Left, R.Top); + with TQtWidget(aHandle).getClientOffset do + OffsetRect(Rect^, x, y); // no need to handle bErase. Qt automatically erase rect on paint event according to docs TQtWidget(aHandle).Update(Rect); end else @@ -3822,19 +3819,13 @@ end; function TQtWidgetSet.ScreenToClient(Handle : HWND; var P : TPoint) : Integer; var APoint: TQtPoint; - R: TRect; begin Result := 0; if Handle <> 0 then begin - APoint.x := P.X; - APoint.y := P.Y; - QWidget_mapFromGlobal(TQtWidget(Handle).Widget, @APoint, @APoint); - P.X := APoint.x; - P.Y := APoint.y; - R := TQtWidget(Handle).getClientBounds; - dec(P.X, R.Left); - dec(P.Y, R.Top); + APoint := QtPoint(P.X, P.Y); + QWidget_mapFromGlobal(TQtWidget(Handle).GetContainerWidget, @APoint, @APoint); + P := Point(APoint.x, APoint.y); Result := 1; end; end; @@ -4687,8 +4678,7 @@ var Widget: QWidgetH; APoint: TQtPoint; begin - APoint.x := Point.x; - APoint.y := Point.y; + APoint := QtPoint(Point.x, Point.y); Widget := QApplication_widgetAt(@APoint); if Widget <> nil then begin diff --git a/lcl/interfaces/qt/qtwscontrols.pp b/lcl/interfaces/qt/qtwscontrols.pp index ab61455ab3..ed037a4155 100644 --- a/lcl/interfaces/qt/qtwscontrols.pp +++ b/lcl/interfaces/qt/qtwscontrols.pp @@ -416,23 +416,27 @@ class procedure TQtWSWinControl.PaintTo(const AWinControl: TWinControl; ADC: HDC; X, Y: Integer); var Context: TQtDeviceContext absolute ADC; + Widget: TQtWidget; Pixmap: TQtPixmap; DCSize: TSize; APoint: TQtPoint; - ARect: TRect; + ARect, GRect: TRect; begin if not WSCheckHandleAllocated(AWincontrol, 'PaintTo') or (ADC = 0) then Exit; - with DCSize, TQtWidget(AWinControl.Handle) do + Widget := TQtWidget(AWinControl.Handle); + ARect := Widget.getFrameGeometry; + GRect := Widget.getGeometry; + with DCSize, ARect do begin - cx := getWidth; - cy := getHeight; + cx := Right - Left; + cy := Bottom - Top; end; Pixmap := TQtPixmap.Create(@DCSize); - Pixmap.grabWidget(TQtWidget(AWinControl.Handle).Widget, 0, 0); - APoint.x := X; - APoint.Y := Y; + OffsetRect(GRect, -ARect.Left, -ARect.Top); + Pixmap.grabWidget(Widget.Widget, 0, 0); + APoint := QtPoint(X + GRect.Left, Y + GRect.Top); ARect := Rect(0, 0, Pixmap.getWidth, Pixmap.getHeight); Context.drawPixmap(@APoint, Pixmap.Handle, @ARect); Pixmap.Free;