From 99c433c0ee7ace818f530133d475ccf48d0df3ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=BDeljan=20Rikalo?= Date: Wed, 1 Feb 2023 16:09:55 +0100 Subject: [PATCH] Qt5: fixed clientrect size of TCustomForm with main menu. Patch by rich2014, small modification by me. --- lcl/interfaces/qt5/qtwidgets.pas | 73 +++++++++++++++++++++++++++++- lcl/interfaces/qt5/qtwinapi.inc | 15 ++++-- lcl/interfaces/qt5/qtwscontrols.pp | 30 +----------- 3 files changed, 85 insertions(+), 33 deletions(-) diff --git a/lcl/interfaces/qt5/qtwidgets.pas b/lcl/interfaces/qt5/qtwidgets.pas index aff2d34222..6d0613227e 100644 --- a/lcl/interfaces/qt5/qtwidgets.pas +++ b/lcl/interfaces/qt5/qtwidgets.pas @@ -326,6 +326,8 @@ type property Widget: QWidgetH read GetWidget write SetWidget; property WidgetColorRole: QPaletteColorRole read FWidgetColorRole write FWidgetColorRole; property WidgetState: TQtWidgetStates read FWidgetState write FWidgetState; + public + class procedure ConstraintsChange(const AWinControl: TWinControl); end; { TQtAbstractSlider , inherited by TQtScrollBar, TQtTrackBar } @@ -682,6 +684,7 @@ type procedure UpdateRegion(ARgn: QRegionH); override; procedure Repaint(ARect: PRect = nil); override; + function GetClientRectFix(): TSize; procedure Resize(ANewWidth, ANewHeight: Integer); override; procedure setText(const W: WideString); override; procedure setMenuBar(AMenuBar: QMenuBarH); @@ -4318,6 +4321,7 @@ var {$ENDIF} B: Boolean; AQtClientRect: TRect; + mainWin: TQtMainWindow; begin {$ifdef VerboseQt} WriteLn('TQtWidget.SlotResize'); @@ -4382,6 +4386,16 @@ begin end; end; + // when resizing a form, need to adjust the height that will be sent to LCL + if (ClassType = TQtMainWindow) {$IFDEF QTSCROLLABLEFORMS} or (ClassType = TQtWindowArea){$ENDIF} then + begin + if ClassType = TQtMainWindow then + mainWin:= TQtMainWindow(self) + else + mainWin:= TQtMainWindow(LCLObject.Handle); + dec(NewSize.cy, mainWin.GetClientRectFix.cy); + end; + {keep LCL value while designing pageControl} if (csDesigning in LCLObject.ComponentState) and InUpdate and ((Self is TQtPage) or (Self is TQtTabWidget)) then @@ -7413,8 +7427,21 @@ begin inherited Repaint(ARect); end; +// currently only handles the adjustments that MainMenu needs to make +function TQtMainWindow.GetClientRectFix(): TSize; +begin + if Assigned(FMenuBar) and (not IsMdiChild) then + begin + FMenuBar.sizeHint(@Result); + if Result.Height<10 then Result.Height:=0; + end else + Result:= TSize.Create(0,0); +end; + procedure TQtMainWindow.Resize(ANewWidth, ANewHeight: Integer); begin + inc( ANewHeight, GetClientRectFix.cy ); + if not IsMDIChild and not IsFrameWindow and (TCustomForm(LCLObject).BorderStyle in [bsDialog, bsNone, bsSingle]) and not (csDesigning in LCLObject.ComponentState) then @@ -7428,12 +7455,55 @@ begin setWindowTitle(@W); end; +// move from qtwscontrls.pp +// to avoid unit circular references +class procedure TQtWidget.ConstraintsChange(const AWinControl: TWinControl); +const + QtMaxContraint = $FFFFFF; +var + AWidget: TQtWidget; + MW, MH: Integer; + cy: Integer; +begin + if (AWinControl is TCustomForm) then + cy:= TQtMainWindow(AWinControl.Handle).GetClientRectFix.cy + else + cy:= 0; + + AWidget := TQtWidget(AWinControl.Handle); + with AWinControl do + begin + MW := Constraints.MinWidth; + MH := Constraints.MinHeight; + + if MW <= QtMinimumWidgetSize then + MW := 0; + if MH <= QtMinimumWidgetSize then + MH := 0 + else + inc(MH, cy); + AWidget.setMinimumSize(MW, MH); + + MW := Constraints.MaxWidth; + MH := Constraints.MaxHeight; + + if MW = 0 then + MW := QtMaxContraint; + if MH = 0 then + MH := QtMaxContraint + else + inc(MH, cy); + AWidget.setMaximumSize(MW, MH); + end; +end; + procedure TQtMainWindow.setMenuBar(AMenuBar: QMenuBarH); begin if IsMainForm then QMainWindow_setMenuBar(QMainWindowH(Widget), AMenuBar) else QLayout_setMenuBar(LayoutWidget, AMenuBar); + TQtWidget.ConstraintsChange(LCLObject); end; {------------------------------------------------------------------------------ @@ -7934,6 +8004,7 @@ begin Msg.Width := Word(getWidth); Msg.Height := Word(getHeight); end; + dec( Msg.Height, GetClientRectFix.cy ); DeliverMessage(Msg); end; @@ -19763,7 +19834,7 @@ begin WidgetToNotify := QApplication_widgetAt(@p); if (WidgetToNotify <> nil) then begin - if TQtMainWindow(Self).FMenuBar.Widget <> nil then + if Assigned(TQtMainWindow(Self).FMenuBar) and (TQtMainWindow(Self).FMenuBar.Widget <> nil) then begin QMouseEvent_Pos(QMouseEventH(Event), @p); QWidget_geometry(TQtMainWindow(Self).FMenuBar.Widget, @R); diff --git a/lcl/interfaces/qt5/qtwinapi.inc b/lcl/interfaces/qt5/qtwinapi.inc index dac533c8db..d2527df0b4 100644 --- a/lcl/interfaces/qt5/qtwinapi.inc +++ b/lcl/interfaces/qt5/qtwinapi.inc @@ -4527,6 +4527,7 @@ function TQtWidgetSet.GetWindowSize(Handle: hwnd; var Width, Height: Integer ): boolean; var ASize: TSize; + ARect: TRect; begin {$ifdef VerboseQtWinAPI} WriteLn('[WinAPI GetWindowSize]'); @@ -4534,9 +4535,17 @@ begin if Handle = 0 then Exit(False); - ASize := TQtWidget(Handle).getSize; - Height := ASize.cy; - Width := ASize.cx; + if (TQtWidget(Handle) is TQtMainWindow) and (not TQtMainWindow(Handle).IsMdiChild) then + begin + GetClientRect(Handle, ARect); + Width := ARect.Width; + Height := ARect.Height; + end else + begin + ASize := TQtWidget(Handle).getSize; + Width := ASize.cx; + Height := ASize.cy; + end; Result := True; diff --git a/lcl/interfaces/qt5/qtwscontrols.pp b/lcl/interfaces/qt5/qtwscontrols.pp index a01180e403..477f7e708b 100644 --- a/lcl/interfaces/qt5/qtwscontrols.pp +++ b/lcl/interfaces/qt5/qtwscontrols.pp @@ -401,38 +401,10 @@ begin end; class procedure TQtWSWinControl.ConstraintsChange(const AWinControl: TWinControl); -const - QtMaxContraint = $FFFFFF; -var - Widget: TQtWidget; - MW, MH: Integer; begin if not WSCheckHandleAllocated(AWincontrol, 'ConstraintsChange') then Exit; - - Widget := TQtWidget(AWinControl.Handle); - with AWinControl do - begin - MW := Constraints.MinWidth; - MH := Constraints.MinHeight; - - if MW < QtMinimumWidgetSize then - MW := 0; - if MH < QtMinimumWidgetSize then - MH := 0; - - Widget.setMinimumSize(MW, MH); - - if Constraints.MaxWidth = 0 then - MW := QtMaxContraint - else - MW := Constraints.MaxWidth; - if Constraints.MaxHeight = 0 then - MH := QtMaxContraint - else - MH := Constraints.MaxHeight; - Widget.setMaximumSize(MW, MH); - end; + TQtWidget.ConstraintsChange(AWinControl); end; class procedure TQtWSWinControl.PaintTo(const AWinControl: TWinControl;