View Issue Details

IDProjectCategoryView StatusLast Update
0033957LazarusWidgetsetpublic2018-10-25 06:48
ReporterLacaKAssigned ToLacaK 
PrioritynormalSeverityminorReproducibilityalways
Status closedResolutionfixed 
PlatformWinCEOSWinCEOS Version
Product Version1.8Product Build 
Target VersionFixed in Version2.0.1 (SVN) 
Summary0033957: Forms are not correctly centered, when used Position=poScreenCenter or poDesktopCenter
DescriptionStarting from rev.51111 forms are centered in screen taking into account client area only. So they are centered as if they does not contain title bar and borders.
Additional InformationRelated to 0027771
Tagswince
Fixed in Revision59337
LazTarget-
WidgetsetWinCE
Attached Files
  • wincewsforms.pp.patch (2,346 bytes)
    Index: lcl/interfaces/wince/wincewsforms.pp
    ===================================================================
    --- lcl/interfaces/wince/wincewsforms.pp	(revision 58471)
    +++ lcl/interfaces/wince/wincewsforms.pp	(working copy)
    @@ -147,6 +147,14 @@
     
     { TWinCEWSCustomForm }
     
    +function GetDesigningBorderStyle(const AForm: TCustomForm): TFormBorderStyle;
    +begin
    +  if csDesigning in AForm.ComponentState then
    +    Result := bsSizeable
    +  else
    +    Result := AForm.BorderStyle;
    +end;
    +
     class function TWinCEWSCustomForm.CalcBorderIconsFlags(const AForm: TCustomForm): dword;
     var
       BorderIcons: TBorderIcons;
    @@ -153,14 +161,14 @@
     begin
       Result := 0;
       BorderIcons := AForm.BorderIcons;
    -  if biSystemMenu in BorderIcons then
    +  if (biSystemMenu in BorderIcons) or (csDesigning in AForm.ComponentState) then
         Result := Result or WS_SYSMENU;
    -  if AForm.BorderStyle in [bsNone, bsSingle, bsSizeable] then
    +  if GetDesigningBorderStyle(AForm) in [bsNone, bsSingle, bsSizeable] then
       begin
         if biMinimize in BorderIcons then
    -      Result := Result or WS_MINIMIZE;
    +      Result := Result or WS_MINIMIZEBOX;
         if biMaximize in BorderIcons then
    -      Result := Result or WS_MAXIMIZE;
    +      Result := Result or WS_MAXIMIZEBOX;
       end;
     end;
     
    @@ -343,15 +351,12 @@
     class procedure TWinCEWSCustomForm.SetBounds(const AWinControl: TWinControl;
         const ALeft, ATop, AWidth, AHeight: Integer);
     var
    -  SizeRect: Windows.RECT;
    +  SizeRect, WR, CurRect: Windows.RECT;
       BorderStyle: TFormBorderStyle;
    -  WR: Windows.RECT;
     begin
    -  { User selected LCL window size }
    -  SizeRect.Top := ATop;
    -  SizeRect.Left := ALeft;
    -  SizeRect.Bottom := ATop + AHeight;
    -  SizeRect.Right := ALeft + AWidth;
    +  // the LCL defines the size of a form without border, wince with.
    +  // -> adjust size according to BorderStyle
    +  SizeRect := Bounds(ALeft, ATop, AWidth, AHeight);
     
       BorderStyle := TCustomForm(AWinControl).BorderStyle;
     
    @@ -382,7 +387,7 @@
           BorderStyle), false, BorderStyleToWinAPIFlagsEx(TCustomForm(AWinControl), BorderStyle));
     
       // rect adjusted, pass to inherited to do real work
    -  TWinCEWSWinControl.SetBounds(AWinControl, SizeRect.Left, SizeRect.Top,
    +  TWinCEWSWinControl.SetBounds(AWinControl, ALeft, ATop,
         SizeRect.Right - SizeRect.Left, SizeRect.Bottom - SizeRect.Top);
     
       {$IFDEF VerboseSizeMsg}
    
    wincewsforms.pp.patch (2,346 bytes)
  • wincewsforms.pp.2.patch (3,452 bytes)
    Index: lcl/interfaces/wince/wincewsforms.pp
    ===================================================================
    --- lcl/interfaces/wince/wincewsforms.pp	(revision 58471)
    +++ lcl/interfaces/wince/wincewsforms.pp	(working copy)
    @@ -121,6 +121,10 @@
     
     uses Winceint, wincewsmenus;
     
    +type
    +  TWinControlAccess = class(TWinControl)
    +  end;
    +
     { TWinCEWSScrollBox }
     
     class function TWinCEWSScrollBox.CreateHandle(const AWinControl: TWinControl;
    @@ -147,6 +151,14 @@
     
     { TWinCEWSCustomForm }
     
    +function GetDesigningBorderStyle(const AForm: TCustomForm): TFormBorderStyle;
    +begin
    +  if csDesigning in AForm.ComponentState then
    +    Result := bsSizeable
    +  else
    +    Result := AForm.BorderStyle;
    +end;
    +
     class function TWinCEWSCustomForm.CalcBorderIconsFlags(const AForm: TCustomForm): dword;
     var
       BorderIcons: TBorderIcons;
    @@ -153,14 +165,14 @@
     begin
       Result := 0;
       BorderIcons := AForm.BorderIcons;
    -  if biSystemMenu in BorderIcons then
    +  if (biSystemMenu in BorderIcons) or (csDesigning in AForm.ComponentState) then
         Result := Result or WS_SYSMENU;
    -  if AForm.BorderStyle in [bsNone, bsSingle, bsSizeable] then
    +  if GetDesigningBorderStyle(AForm) in [bsNone, bsSingle, bsSizeable] then
       begin
         if biMinimize in BorderIcons then
    -      Result := Result or WS_MINIMIZE;
    +      Result := Result or WS_MINIMIZEBOX;
         if biMaximize in BorderIcons then
    -      Result := Result or WS_MAXIMIZE;
    +      Result := Result or WS_MAXIMIZEBOX;
       end;
     end;
     
    @@ -343,15 +355,14 @@
     class procedure TWinCEWSCustomForm.SetBounds(const AWinControl: TWinControl;
         const ALeft, ATop, AWidth, AHeight: Integer);
     var
    -  SizeRect: Windows.RECT;
    +  AForm: TCustomForm absolute AWinControl;
    +  SizeRect, WR, CurRect: Windows.RECT;
       BorderStyle: TFormBorderStyle;
    -  WR: Windows.RECT;
    +  L, T, W, H: integer;
     begin
    -  { User selected LCL window size }
    -  SizeRect.Top := ATop;
    -  SizeRect.Left := ALeft;
    -  SizeRect.Bottom := ATop + AHeight;
    -  SizeRect.Right := ALeft + AWidth;
    +  // the LCL defines the size of a form without border, wince with.
    +  // -> adjust size according to BorderStyle
    +  SizeRect := Bounds(ALeft, ATop, AWidth, AHeight);
     
       BorderStyle := TCustomForm(AWinControl).BorderStyle;
     
    @@ -381,9 +392,33 @@
       Windows.AdjustWindowRectEx(@SizeRect, BorderStyleToWinAPIFlags(
           BorderStyle), false, BorderStyleToWinAPIFlagsEx(TCustomForm(AWinControl), BorderStyle));
     
    +  L := ALeft;
    +  T := ATop;
    +  W := SizeRect.Right - SizeRect.Left;
    +  H := SizeRect.Bottom - SizeRect.Top;
    +
    +  // we are calling setbounds in TWinControl.Initialize
    +  // if position is default it will be changed to designed. We do not want this.
    +  if wcfInitializing in TWinControlAccess(AWinControl).FWinControlFlags then
    +  begin
    +    if GetWindowRect(AForm.Handle, CurRect) then
    +    begin
    +      if AForm.Position in [poDefault, poDefaultPosOnly] then
    +      begin
    +        L := CurRect.Left;
    +        T := CurRect.Top;
    +      end;
    +
    +      if AForm.Position in [poDefault, poDefaultSizeOnly] then
    +      begin
    +        W := CurRect.Right - CurRect.Left;
    +        H := CurRect.Bottom - CurRect.Top;
    +      end;
    +    end;
    +  end;
    +
       // rect adjusted, pass to inherited to do real work
    -  TWinCEWSWinControl.SetBounds(AWinControl, SizeRect.Left, SizeRect.Top,
    -    SizeRect.Right - SizeRect.Left, SizeRect.Bottom - SizeRect.Top);
    +  TWinCEWSWinControl.SetBounds(AWinControl, L, T, W, H);
     
       {$IFDEF VerboseSizeMsg}
       DebugLn(
    
    wincewsforms.pp.2.patch (3,452 bytes)

Activities

LacaK

2018-07-09 15:49

developer  

wincewsforms.pp.patch (2,346 bytes)
Index: lcl/interfaces/wince/wincewsforms.pp
===================================================================
--- lcl/interfaces/wince/wincewsforms.pp	(revision 58471)
+++ lcl/interfaces/wince/wincewsforms.pp	(working copy)
@@ -147,6 +147,14 @@
 
 { TWinCEWSCustomForm }
 
+function GetDesigningBorderStyle(const AForm: TCustomForm): TFormBorderStyle;
+begin
+  if csDesigning in AForm.ComponentState then
+    Result := bsSizeable
+  else
+    Result := AForm.BorderStyle;
+end;
+
 class function TWinCEWSCustomForm.CalcBorderIconsFlags(const AForm: TCustomForm): dword;
 var
   BorderIcons: TBorderIcons;
@@ -153,14 +161,14 @@
 begin
   Result := 0;
   BorderIcons := AForm.BorderIcons;
-  if biSystemMenu in BorderIcons then
+  if (biSystemMenu in BorderIcons) or (csDesigning in AForm.ComponentState) then
     Result := Result or WS_SYSMENU;
-  if AForm.BorderStyle in [bsNone, bsSingle, bsSizeable] then
+  if GetDesigningBorderStyle(AForm) in [bsNone, bsSingle, bsSizeable] then
   begin
     if biMinimize in BorderIcons then
-      Result := Result or WS_MINIMIZE;
+      Result := Result or WS_MINIMIZEBOX;
     if biMaximize in BorderIcons then
-      Result := Result or WS_MAXIMIZE;
+      Result := Result or WS_MAXIMIZEBOX;
   end;
 end;
 
@@ -343,15 +351,12 @@
 class procedure TWinCEWSCustomForm.SetBounds(const AWinControl: TWinControl;
     const ALeft, ATop, AWidth, AHeight: Integer);
 var
-  SizeRect: Windows.RECT;
+  SizeRect, WR, CurRect: Windows.RECT;
   BorderStyle: TFormBorderStyle;
-  WR: Windows.RECT;
 begin
-  { User selected LCL window size }
-  SizeRect.Top := ATop;
-  SizeRect.Left := ALeft;
-  SizeRect.Bottom := ATop + AHeight;
-  SizeRect.Right := ALeft + AWidth;
+  // the LCL defines the size of a form without border, wince with.
+  // -> adjust size according to BorderStyle
+  SizeRect := Bounds(ALeft, ATop, AWidth, AHeight);
 
   BorderStyle := TCustomForm(AWinControl).BorderStyle;
 
@@ -382,7 +387,7 @@
       BorderStyle), false, BorderStyleToWinAPIFlagsEx(TCustomForm(AWinControl), BorderStyle));
 
   // rect adjusted, pass to inherited to do real work
-  TWinCEWSWinControl.SetBounds(AWinControl, SizeRect.Left, SizeRect.Top,
+  TWinCEWSWinControl.SetBounds(AWinControl, ALeft, ATop,
     SizeRect.Right - SizeRect.Left, SizeRect.Bottom - SizeRect.Top);
 
   {$IFDEF VerboseSizeMsg}
wincewsforms.pp.patch (2,346 bytes)

LacaK

2018-07-09 15:50

developer   ~0109318

Comparing WinCE and Win32 I found that this patch fixes my case.

Stephano

2018-07-10 08:30

developer   ~0109330

Last edited: 2018-07-10 10:13

View 2 revisions

I have a few concerns regarding your patch:
- You defined CurRect, but haven't used it anywhere
- You substituted SizeRect.Left, SizeRect.Top with ALeft, ATop in:
TWinCEWSWinControl.SetBounds(AWinControl, SizeRect.Left, SizeRect.Top,
Is that necessary? It will probably create a problem for dialogs (which are treated differently on WinCE and should be centered).

LacaK

2018-07-10 10:59

developer   ~0109334

Last edited: 2018-07-10 12:37

View 3 revisions

- CurRect: it is remnant from Win32 from where I copied code
- SizeRect.Left, SizeRect.Top: is also taken from Win32 and it does the trick. If I change ALeft, ATop to SizeRect.Left, SizeRect.Top then behavior is as before (because other changes are more or less cosmetical and to align to Win32 version;
with exception of WS_MINIMIZE,WS_MAXIMIZE versus WS_MINIMIZEBOX, WS_MAXIMIZEBOX which adds buttons in title bar)

I have tested both BorderStyle=bsSingle and bsDialog and results are same in my case.

LacaK

2018-07-10 11:55

developer  

wincewsforms.pp.2.patch (3,452 bytes)
Index: lcl/interfaces/wince/wincewsforms.pp
===================================================================
--- lcl/interfaces/wince/wincewsforms.pp	(revision 58471)
+++ lcl/interfaces/wince/wincewsforms.pp	(working copy)
@@ -121,6 +121,10 @@
 
 uses Winceint, wincewsmenus;
 
+type
+  TWinControlAccess = class(TWinControl)
+  end;
+
 { TWinCEWSScrollBox }
 
 class function TWinCEWSScrollBox.CreateHandle(const AWinControl: TWinControl;
@@ -147,6 +151,14 @@
 
 { TWinCEWSCustomForm }
 
+function GetDesigningBorderStyle(const AForm: TCustomForm): TFormBorderStyle;
+begin
+  if csDesigning in AForm.ComponentState then
+    Result := bsSizeable
+  else
+    Result := AForm.BorderStyle;
+end;
+
 class function TWinCEWSCustomForm.CalcBorderIconsFlags(const AForm: TCustomForm): dword;
 var
   BorderIcons: TBorderIcons;
@@ -153,14 +165,14 @@
 begin
   Result := 0;
   BorderIcons := AForm.BorderIcons;
-  if biSystemMenu in BorderIcons then
+  if (biSystemMenu in BorderIcons) or (csDesigning in AForm.ComponentState) then
     Result := Result or WS_SYSMENU;
-  if AForm.BorderStyle in [bsNone, bsSingle, bsSizeable] then
+  if GetDesigningBorderStyle(AForm) in [bsNone, bsSingle, bsSizeable] then
   begin
     if biMinimize in BorderIcons then
-      Result := Result or WS_MINIMIZE;
+      Result := Result or WS_MINIMIZEBOX;
     if biMaximize in BorderIcons then
-      Result := Result or WS_MAXIMIZE;
+      Result := Result or WS_MAXIMIZEBOX;
   end;
 end;
 
@@ -343,15 +355,14 @@
 class procedure TWinCEWSCustomForm.SetBounds(const AWinControl: TWinControl;
     const ALeft, ATop, AWidth, AHeight: Integer);
 var
-  SizeRect: Windows.RECT;
+  AForm: TCustomForm absolute AWinControl;
+  SizeRect, WR, CurRect: Windows.RECT;
   BorderStyle: TFormBorderStyle;
-  WR: Windows.RECT;
+  L, T, W, H: integer;
 begin
-  { User selected LCL window size }
-  SizeRect.Top := ATop;
-  SizeRect.Left := ALeft;
-  SizeRect.Bottom := ATop + AHeight;
-  SizeRect.Right := ALeft + AWidth;
+  // the LCL defines the size of a form without border, wince with.
+  // -> adjust size according to BorderStyle
+  SizeRect := Bounds(ALeft, ATop, AWidth, AHeight);
 
   BorderStyle := TCustomForm(AWinControl).BorderStyle;
 
@@ -381,9 +392,33 @@
   Windows.AdjustWindowRectEx(@SizeRect, BorderStyleToWinAPIFlags(
       BorderStyle), false, BorderStyleToWinAPIFlagsEx(TCustomForm(AWinControl), BorderStyle));
 
+  L := ALeft;
+  T := ATop;
+  W := SizeRect.Right - SizeRect.Left;
+  H := SizeRect.Bottom - SizeRect.Top;
+
+  // we are calling setbounds in TWinControl.Initialize
+  // if position is default it will be changed to designed. We do not want this.
+  if wcfInitializing in TWinControlAccess(AWinControl).FWinControlFlags then
+  begin
+    if GetWindowRect(AForm.Handle, CurRect) then
+    begin
+      if AForm.Position in [poDefault, poDefaultPosOnly] then
+      begin
+        L := CurRect.Left;
+        T := CurRect.Top;
+      end;
+
+      if AForm.Position in [poDefault, poDefaultSizeOnly] then
+      begin
+        W := CurRect.Right - CurRect.Left;
+        H := CurRect.Bottom - CurRect.Top;
+      end;
+    end;
+  end;
+
   // rect adjusted, pass to inherited to do real work
-  TWinCEWSWinControl.SetBounds(AWinControl, SizeRect.Left, SizeRect.Top,
-    SizeRect.Right - SizeRect.Left, SizeRect.Bottom - SizeRect.Top);
+  TWinCEWSWinControl.SetBounds(AWinControl, L, T, W, H);
 
   {$IFDEF VerboseSizeMsg}
   DebugLn(
wincewsforms.pp.2.patch (3,452 bytes)

LacaK

2018-07-10 11:57

developer   ~0109338

I have uploaded another patch (again code taken from Win32), because I have found that in case Position=poDefault "Application error" was raised.

Stephano

2018-07-28 11:20

developer   ~0109717

@Lacak,
Pls open a separate bug report for the WS_* titlebar buttons and split the patch.

LacaK

2018-10-22 10:38

developer   ~0111511

Patch applied in rev.59337

Issue History

Date Modified Username Field Change
2018-07-09 10:17 LacaK New Issue
2018-07-09 15:49 LacaK File Added: wincewsforms.pp.patch
2018-07-09 15:50 LacaK Note Added: 0109318
2018-07-10 07:45 Stephano Assigned To => Stephano
2018-07-10 07:45 Stephano Status new => assigned
2018-07-10 08:30 Stephano Note Added: 0109330
2018-07-10 10:13 Stephano Note Edited: 0109330 View Revisions
2018-07-10 10:59 LacaK Note Added: 0109334
2018-07-10 11:00 LacaK Note Edited: 0109334 View Revisions
2018-07-10 11:55 LacaK File Added: wincewsforms.pp.2.patch
2018-07-10 11:57 LacaK Note Added: 0109338
2018-07-10 12:37 LacaK Note Edited: 0109334 View Revisions
2018-07-28 11:20 Stephano Note Added: 0109717
2018-08-31 07:10 LacaK Tag Attached: wince
2018-10-22 10:38 LacaK Note Added: 0111511
2018-10-25 06:48 LacaK Fixed in Revision => 59337
2018-10-25 06:48 LacaK LazTarget => -
2018-10-25 06:48 LacaK Status assigned => resolved
2018-10-25 06:48 LacaK Fixed in Version => 2.0.1 (SVN)
2018-10-25 06:48 LacaK Resolution open => fixed
2018-10-25 06:48 LacaK Assigned To Stephano => LacaK
2018-10-25 06:48 LacaK Status resolved => closed