From fa9e26c4410e78ee6e5cc1bf81ef61c1b6f9d1c7 Mon Sep 17 00:00:00 2001 From: sekelsenmat Date: Wed, 13 Feb 2008 17:26:10 +0000 Subject: [PATCH] Fixes Groupbox child control positioning and TCustomCheckBox descendents autosizing under WinCE. git-svn-id: trunk@14123 - --- lcl/interfaces/win32/win32proc.pp | 8 ++--- lcl/interfaces/wince/wincecallback.inc | 29 +++++++++------- lcl/interfaces/wince/winceproc.pp | 45 ++++++++++++++++--------- lcl/interfaces/wince/wincewscontrols.pp | 6 ++-- lcl/interfaces/wince/wincewsstdctrls.pp | 17 ++++++---- 5 files changed, 62 insertions(+), 43 deletions(-) diff --git a/lcl/interfaces/win32/win32proc.pp b/lcl/interfaces/win32/win32proc.pp index 75638f4724..4d60d7a6e5 100644 --- a/lcl/interfaces/win32/win32proc.pp +++ b/lcl/interfaces/win32/win32proc.pp @@ -864,18 +864,18 @@ begin end; if (TheWinControl is TCustomGroupBox) then begin - // The client area of a groupbox under win32 is the whole size, including + // The client area of a groupbox under winapi is the whole size, including // the frame. The LCL defines the client area without the frame. // -> Adjust the position - DC := Windows.GetDC(Handle); // add the upper frame with the caption + DC := Windows.GetDC(Handle); GetTextMetrics(DC, TM); ORect.Top := TM.TMHeight; - // add the left frame border + ReleaseDC(Handle, DC); + // add the left, right and bottom frame borders ORect.Left := 2; ORect.Right := -2; ORect.Bottom := -2; - ReleaseDC(Handle, DC); end else if TheWinControl is TCustomNoteBook then begin diff --git a/lcl/interfaces/wince/wincecallback.inc b/lcl/interfaces/wince/wincecallback.inc index b779b71753..13d0acf10a 100644 --- a/lcl/interfaces/wince/wincecallback.inc +++ b/lcl/interfaces/wince/wincecallback.inc @@ -409,12 +409,10 @@ Var end; if ParentPaintWindow <> 0 then GetWin32ControlPos(Window, ParentPaintWindow, parLeft, parTop); - if not GetLCLClientBoundsOffset(lWinControl, ORect) then - begin - ORect.Left := 0; - ORect.Top := 0; - { we don't use ORect.Right and ORect.Bottom, initialize here if needed } - end; + //Is not necessary to check the result of GetLCLClientBoundsOffset since + //the false condition (lWincontrol = nil or lWincontrol <> TWinControl) is never met + //The rect is always initialized with 0 + GetLCLClientBoundsOffset(lWinControl, ORect); PaintMsg.Msg := LM_PAINT; PaintMsg.PaintStruct := @PS; if not useDoubleBuffer then @@ -1134,12 +1132,19 @@ begin } WM_CTLCOLORMSGBOX..WM_CTLCOLORSTATIC: begin - // it's needed for winxp themes where controls send the WM_ERASEBKGND - // message to their parent to clear their background and then draw - // transparently - // only static and button controls have transparent parts - // others need to erased with their window color - // scrollbar also has buttons + { it's needed for winxp themes where controls send the WM_ERASEBKGND + message to their parent to clear their background and then draw + transparently + only static and button controls have transparent parts + others need to erased with their window color + scrollbar also has buttons + + Handling this message is the method provided to change the background + color of many Windows Standard Controls, like TGroupBox, TCheckBox, etc. + + Note that here ChildWinControl represents the control about to be + painted. A RadioButton for example. lWinControl represents the Form. + } ChildWindowInfo := GetWindowInfo(LParam); ChildWinControl := ChildWindowInfo^.WinControl; if ChildWinControl = nil then diff --git a/lcl/interfaces/wince/winceproc.pp b/lcl/interfaces/wince/winceproc.pp index 1ec8f320f9..03fce4e292 100644 --- a/lcl/interfaces/wince/winceproc.pp +++ b/lcl/interfaces/wince/winceproc.pp @@ -949,40 +949,51 @@ var Handle: HWND; TheWinControl: TWinControl; ARect: TRect; + Ignore: Integer; Begin Result:=false; if (Sender = nil) or (not (Sender is TWinControl)) then exit; TheWinControl:=TWinControl(Sender); if not TheWinControl.HandleAllocated then exit; Handle := TheWinControl.Handle; - ORect.Left := 0; - ORect.Top := 0; + FillChar(ORect, SizeOf(ORect), 0); if TheWinControl is TScrollingWinControl then with TScrollingWinControl(TheWinControl) do begin if HorzScrollBar <> nil then + begin + // left and right bounds are shifted by scroll position ORect.Left := -HorzScrollBar.Position; + ORect.Right := -HorzScrollBar.Position; + end; if VertScrollBar <> nil then + begin + // top and bottom bounds are shifted by scroll position ORect.Top := -VertScrollBar.Position; + ORect.Bottom := -VertScrollBar.Position; + end; end; - ORect.Bottom := 0; - ORect.Right := 0; - If (TheWinControl is TCustomGroupBox) Then - Begin - // The client area of a groupbox under win32 is the whole size, including + if (TheWinControl is TCustomGroupBox) then + begin + // The client area of a groupbox under winapi is the whole size, including // the frame. The LCL defines the client area without the frame. // -> Adjust the position - DC := Windows.GetDC(Handle); // add the upper frame with the caption + DC := Windows.GetDC(Handle); GetTextMetrics(DC, TM); ORect.Top := TM.TMHeight; - // add the left frame border - ORect.Left := 1; - ORect.Right := -1; - ORect.Bottom := -1; ReleaseDC(Handle, DC); - End Else - If TheWinControl is TCustomNoteBook then begin + { GetTextMetrics may not be supported on all devices, so we + have fallback to GetSystemMetrics if it doesn't work. + Also careful that SM_CYSMCAPTION returns 0 on the emulator } + if ORect.Top = 0 then ORect.Top := GetSystemMetrics(SM_CYCAPTION); + // add the left, right and bottom frame borders + ORect.Left := 2; + ORect.Right := -2; + ORect.Bottom := -2; + end else + if TheWinControl is TCustomNoteBook then + begin // Can't use complete client rect in win32 interface, top part contains the tabs Windows.GetClientRect(Handle, @ARect); ORect := ARect; @@ -991,13 +1002,13 @@ Begin Dec(ORect.Bottom, ARect.Bottom); end; { - if (Windows.GetWindowLong(Handle, GWL_EXSTYLE) and WS_EX_CLIENTEDGE) <> 0 then + if (GetWindowLong(Handle, GWL_EXSTYLE) and WS_EX_CLIENTEDGE) <> 0 then begin Dec(LeftOffset, Windows.GetSystemMetrics(SM_CXEDGE)); Dec(TopOffset, Windows.GetSystemMetrics(SM_CYEDGE)); end; } - Result:=true; + Result := True; end; function GetLCLClientBoundsOffset(Handle: HWnd; var Rect: TRect): boolean; @@ -1281,9 +1292,11 @@ begin canvasHandle := GetDC(winHandle); oldFontHandle := SelectObject(canvasHandle, Windows.SendMessage(winHandle, WM_GetFont, 0, 0)); DeleteAmpersands(Text); + tmpText := StringToPWideChar(Text); Result := Windows.GetTextExtentPoint32(canvasHandle, PWideChar(tmpText), Length(Text), @textSize); FreeMem(tmpText); + if Result then begin Width := textSize.cx; diff --git a/lcl/interfaces/wince/wincewscontrols.pp b/lcl/interfaces/wince/wincewscontrols.pp index def49f225f..c2595a7f55 100644 --- a/lcl/interfaces/wince/wincewscontrols.pp +++ b/lcl/interfaces/wince/wincewscontrols.pp @@ -175,9 +175,7 @@ begin Assert(False, 'Trace:Setting window'); if AWinControl.Parent <> nil then - begin - Parent := AWinControl.Parent.Handle; - end + Parent := AWinControl.Parent.Handle else Parent := TWinCEWidgetSet(WidgetSet).AppHandle; @@ -198,7 +196,7 @@ begin if AWinControl.TabStop then Flags := Flags or WS_TABSTOP; Assert(False, 'Trace:Setting dimentions'); - // LCLBoundsToWin32Bounds(AWinControl, Left, Top, Width, Height);//roozbeh:i dont think we need it yet + LCLBoundsToWin32Bounds(AWinControl, Left, Top, Width, Height); if AWinControl is TCustomControl then if TCustomControl(AWinControl).BorderStyle = bsSingle then FlagsEx := FlagsEx or WS_EX_CLIENTEDGE; diff --git a/lcl/interfaces/wince/wincewsstdctrls.pp b/lcl/interfaces/wince/wincewsstdctrls.pp index 75ec6a0c8d..53f3f89a0b 100644 --- a/lcl/interfaces/wince/wincewsstdctrls.pp +++ b/lcl/interfaces/wince/wincewsstdctrls.pp @@ -1164,7 +1164,6 @@ begin FinishCreateWindow(AWinControl, Params, false); FreeMem(Params.WindowTitle); Result := Params.Window; - end; class procedure TWinCEWSCustomCheckBox.GetPreferredSize(const AWinControl: TWinControl; @@ -1179,6 +1178,14 @@ begin iconHeight := GetSystemMetrics(SM_CYMENUCHECK); if iconHeight > PreferredHeight then PreferredHeight := iconHeight; + if WithThemeSpace then begin + Inc(PreferredWidth, 6); + Inc(PreferredHeight, 6); + end; + + // All TCustomCheckBox descendents were consistently too small + // on autosize, so an extra spacing is added it to fix that + Inc(PreferredWidth, 10); end; end; @@ -1238,9 +1245,6 @@ class function TWinCEWSRadioButton.CreateHandle(const AWinControl: TWinControl; const AParams: TCreateParams): HWND; var Params: TCreateWindowExParams; - hwnd: THandle; - Str: array[0..255] of WideChar; - begin {$ifdef VerboseWinCE} WriteLn('TWinCEWSRadioButton.CreateHandle'); @@ -1252,14 +1256,13 @@ begin with Params do begin pClassName := @ButtonClsName; - WindowTitle := StringToPWideChar(AWinControl.Caption); + WindowTitle := StrCaption; // BS_AUTORADIOBUTTON may hang the application, // if the radiobuttons are not consecutive controls.//roozbeh:is it so in wince? - Flags := Flags or BS_AUTORADIOBUTTON; + Flags := Flags or BS_RADIOBUTTON; end; // create window FinishCreateWindow(AWinControl, Params, false); - FreeMem(Params.WindowTitle); Result := Params.Window; end;