View Issue Details

IDProjectCategoryView StatusLast Update
0037129LazarusLCLpublic2020-05-29 02:01
Reporterjamie philbrook Assigned Towp  
PrioritynormalSeverityminorReproducibilityalways
Status confirmedResolutionopen 
Product Version2.0.8 
Summary0037129: Comboboxes in csSimple will not size in the designer and leaves trailing unpainted areas in the drop down list.
DescriptionFirst, I can randomly get to size the csSimple combobox at design time. it seems this is random but when it does work it will work for the remainder of the session until I restart laz. After that , 90% of the time I can not expand the height of the edit box to show the list box which is a static viewable list box in csSimple mode..

 At runtime I can force the control to show the list but I've also noticed there is a window behind it that is taller than the actual combobox coming from the OS. If you put a csSimple on a form with its list showing and then cover it via a form resize and then reshow it, you can observe the region that does not get covered by the OS part of the combobox. This region belongs to the Combobox control because it receives mouse messages.
Steps To Reproduce
Drop a csSimple on a form, expand it to shows its list box if you can, if not, do it at runtime and you can see the list box then by setting the height property of the control

 Drag the form size small enough to cover the control and then drag it back open again, you will see there is two controls there, a windows in the back and the actual ComboBox from the OS, they don't match their heights.

 I have played with the Height property and I can get a perfect multiple where it will not show this band of black so there Is an issue obviously in the Widget.. (Win32/Win64);

Please take a look at this, to problem seems to be widget related and looks to be like it was custom created..

 All of this works perfectly fine in my Old Delphi and current Delphi 10.x
TagsNo tags attached.
Fixed in Revision
LazTarget-
WidgetsetWin32/Win64
Attached Files

Activities

jamie philbrook

2020-05-23 20:49

reporter   ~0123020

After some more debugging, I've found if you drop a combobox on the form. Set the style := csSimple.. at this point you are not able to size it
from the IDE.
   
   Save the project you are doing this in, close the project. reopen the project and don't change the style settings.

  Now you can resize the combobox in the IDE with the grippers.

  It seems you have to go through this process to force the IDE to accept the fact that you want to size the csSimple combobox at design time.

 Also, with the garbage displaying at the bottom of the list for the csSimple... This is due to the host window being taller than the actual list box itself.
 
  I overroad the CreateParams and added this to the Style member.
  CBS_NOINTEGRALHEIGHT

 I do this only if the csSimple is in play, otherwise it stays as is..
  
I was going to adjust the host window height to fit the OS determined height in the Createhandle code but i got thinking that could cause issues with Dragging the size in the IDE.

 What do you think of this issue this far ?

jamie philbrook

2020-05-24 15:33

reporter   ~0123034

I will try to get setup for proper patches, but the last time I tried this it was a hora show.. Things just wasn't going well on my end..

I Added this to the Combobox.CreateParams method in the Combobox.inc file.
 {$IFDEF Windows} //Added JP.
  if (Params.Style and CBS_SIMPLE)<>0 Then
   Begin
    Include(FWinControlFlags, wcfEraseBackground);
    Params.Style:= Params.Style or $400; //CBS_NOINTEGRALHEIGHT
   End
  Else
   Exclude(FWinControlFlags, wcfEraseBackground);
 {$IFEND}
 This is placed at the bottom of the Method call.
This corrects the garbage drawing of the csSimple combobox because it needs to have its background erased and it also needs to be in Non-integral height mode because it too also generates a white background at the bottom depending on height.

This code only effects the csSimple, all other styles still work as they are now.

I still haven't found the issue with the designer but I can tell you how to make it work..

 It appears you need to set the style of the combo box to csSimple for what at this time you still can not size the box.

 save the project, close it, reopen the project. The settings are still csSimple but now you can resize the csSimple on the form using the OI..

That has me puzzled ? working with your project from there on will keep the box sizeable until you toggle the styles again. Then you need to reload the project.

wp

2020-05-28 16:47

developer   ~0123109

I am adding a demo project which shows the "garbage" at the bottom of the csSimple combo (left most combobox - the other one is just for reference to a csDropdown combobox). To verify click the "Height = 162" button and then several times the "Dec Height by 10".
37129.png (6,278 bytes)   
37129.png (6,278 bytes)   

wp

2020-05-28 16:59

developer   ~0123110

The issue was discussed in the forum (https://forum.lazarus.freepascal.org/index.php/topic,49911.0.html). Jamie provided there a modified version of the Win32 widgetset file win32wsstdctrls.pp from which I created the attached patch. It is essentially jamie's idea to deactivate the integral listbox height feature, but transferred into the win32 widgetset (in the other widgetsets the csSimple combobox does not show a stationary listbox).

This modified version does resolve the "garbage" issue, but leaves other issues:
- When the height of the csSimple combobox is set by code (button "Height = 162") an explicit call to Combobox.Invalidate is required (check "call Invalidate after click"), otherwise the stationary listbox will not be painted fully.
- AutoSize is not operational: Once the height of the csSimple combobox has been changed it cannot be reset to its original height by setting AutoSize to true (Click "Height=162" and then "AutoSize" --> no change).
- As already mentioned by jamie here, the height of a csSimple combobox cannot be changed at designtime after the combobox has been dropped onto the form. It is required to save the form and reload it to make the height changeable.
win32wsstdctrls.pp.patch (2,414 bytes)   
Index: lcl/interfaces/win32/win32wsstdctrls.pp
===================================================================
--- lcl/interfaces/win32/win32wsstdctrls.pp	(revision 63239)
+++ lcl/interfaces/win32/win32wsstdctrls.pp	(working copy)
@@ -400,6 +400,14 @@
           Exit(CallDefaultWindowProc(Window, Msg, WParam, LParam));
         end;
       end;
+    WM_SIZE: { issue #37129: Correct painting of static listview when height is increased like in Delphi }
+       begin
+          WindowInfo := GetWin32WindowInfo(Window);
+         If TCustomcombobox(WindowInfo^.WinControl).Style = csSimple Then
+         Begin
+           InvalidateRect(Window,Nil,true);
+         end;
+       end;
     WM_PAINT,
     WM_ERASEBKGND:
       begin
@@ -956,7 +964,7 @@
   const ACustomComboBox: TCustomComboBox): TWin32ComboBoxStringList;
 begin
   Result := nil;
-  if ACustomComboBox.Style <> csSimple then
+  // if ACustomComboBox.Style <> csSimple then   // removed for issue #37129
     Result := TWin32ComboBoxStringList(GetWin32WindowInfo(ACustomComboBox.Handle)^.List);
 end;
 
@@ -975,6 +983,15 @@
     pSubClassName := LCLComboboxClsName;
     SubClassWndProc := @ComboBoxWindowProc;
   end;
+
+  // issue #37129: Show of static listview when height is increased (like in Delphi)
+  if (CBS_SIMPLE and Params.flags) <> 0 Then 
+  begin
+    Params.Flags := Params.Flags or CBS_NOINTEGRALHEIGHT;
+    Include(TWinControlAccess(AWinControl).FWinControlFlags, wcfEraseBackground);
+  end else
+    Exclude(TWinControlAccess(AWinControl).FWinControlFlags, wcfEraseBackground);
+
   // create window
   FinishCreateWindow(AWinControl, Params, False, True);
 
@@ -1015,7 +1032,7 @@
 var
   StringList: TWin32ComboBoxStringList;
 begin
-  if TCustomComboBox(AWinControl).Style = csSimple then Exit;
+  // if TCustomComboBox(AWinControl).Style = csSimple then Exit;  // removed for issue #37129
   StringList := GetStringList(TCustomComboBox(AWinControl));
   if Assigned(StringList) then
     Height := StringList.ComboHeight;
@@ -1026,7 +1043,9 @@
   WithThemeSpace: Boolean);
 begin
   PreferredHeight := 0;
-  if (AWinControl.HandleAllocated) and (TCustomComboBox(AWinControl).Style <> csSimple) then
+  if (AWinControl.HandleAllocated) and 
+    (not (csDesigning in AWinControl.ComponentState) or (TCustomComboBox(AWinControl).Style <> csSimple)) 
+  then
     PreferredHeight := AWinControl.Height;
 end;
 
win32wsstdctrls.pp.patch (2,414 bytes)   

jamie philbrook

2020-05-28 19:33

reporter   ~0123111

I had to revert the

GetPreferredSize back to its original state because it is causing the size change of the combobox to be limited to ~ 50 or so times, after that changing the Height has no effect.

 So I put it back as it was before so if it is csSimple it returns 0 as the preferred size for now..

wp

2020-05-29 00:25

developer   ~0123116

After spending more time on this topic than I did before and comparing the state before and after the patch, it looks to me as if the initial idea with the integral line height has led you onto the wrong path, and this hides the real root cause of incorrect erasing the background of the stationary listbox - as if the WM_ERASEBKGND message does not reach the stationary listbox or is not property handled by it.

jamie philbrook

2020-05-29 01:59

reporter   ~0123117

Last edited: 2020-05-29 02:01

View 2 revisions

OK, I'll go with that for the time being..

But where is the code that draws the borders? Changing a windows setting in the control seems to correct the inner bevel or outline depending if you are using themes or not to force the correct size for the outline..
 
  You can get the rectangle size of the listbox from Windows but I thinking that maybe some how the size of the font is being used.

 If the LCL is responsible for the border drawing I would like to know where to look.. that I have been searching ..

Actually I don't know why we don't have a Property for integralHeight anyways ? Its in both Listbox and Combos.

Issue History

Date Modified Username Field Change
2020-05-22 16:33 jamie philbrook New Issue
2020-05-23 20:49 jamie philbrook Note Added: 0123020
2020-05-24 15:33 jamie philbrook Note Added: 0123034
2020-05-27 13:45 wp Assigned To => wp
2020-05-27 13:45 wp Status new => assigned
2020-05-27 13:45 wp Status assigned => confirmed
2020-05-27 13:45 wp LazTarget => -
2020-05-28 16:47 wp Note Added: 0123109
2020-05-28 16:47 wp File Added: 37129.png
2020-05-28 16:47 wp File Added: 37129 - combobox_csSimple.zip
2020-05-28 16:59 wp Note Added: 0123110
2020-05-28 16:59 wp File Added: win32wsstdctrls.pp.patch
2020-05-28 19:33 jamie philbrook Note Added: 0123111
2020-05-29 00:25 wp Note Added: 0123116
2020-05-29 01:59 jamie philbrook Note Added: 0123117
2020-05-29 02:01 jamie philbrook Note Edited: 0123117 View Revisions