View Issue Details
ID | Project | Category | View Status | Date Submitted | Last Update |
---|---|---|---|---|---|
0037129 | Lazarus | LCL | public | 2020-05-22 16:33 | 2020-09-01 16:14 |
Reporter | jamie philbrook | Assigned To | wp | ||
Priority | normal | Severity | minor | Reproducibility | always |
Status | closed | Resolution | fixed | ||
Product Version | 2.0.8 | ||||
Summary | 0037129: Comboboxes in csSimple will not size in the designer and leaves trailing unpainted areas in the drop down list. | ||||
Description | First, 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 | ||||
Tags | No tags attached. | ||||
Fixed in Revision | 63251 | ||||
LazTarget | 2.0.10 | ||||
Widgetset | Win32/Win64 | ||||
Attached Files |
|
|
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 ? |
|
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. |
|
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". |
|
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; |
|
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.. |
|
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. |
|
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. |
|
I had to implement the WM_SETFONT because when ever the font was set it caused windows to size its box larger than the host box so there was no scrollbar showing depending on the size of the font also cause the box length to exceed the host box.. Also I still can not remove the use of the CB_NOINTEGRALHEIGHT and of course I had to ensure the background erase was on in the LCL code... I've tested this with code sizing in all directions, anchoring etc. This works smoothing both in the designer and at runtime.. I did have an issue with tricking the system to accept a size change so it would update. It seems there is block somewhere, maybe in the LCL preventing refresh painting of the same size bounds. If you have a better solution for this it would be nice . what I have now seems to actually work and it works very nicely here. Code below.. ----- WM_SETFONT: {JP added} Begin Result := WindowProc(Window, Msg, WParam, LParam); WindowInfo := GetWin32WIndowInfo(Window); With WindowInfo^.WinControl Do Begin {LCL is blcoking the size change so we trick it} If TCustomComBoBox(WindowInfo^.WinCOntrol).Style = csSimple Then Begin SendMessage(Window,CB_SETDROPPEDWIDTH, WIdth, 0); MoveWindow(Handle, left,Top,Width, Height-1,False); {Trick the No size lock} MoveWindow(Handle, Left,Top,Width, Height+1,False);{Won't change otherwise} end; end; Exit; end; WM_SIZE: {JP added for csSimple border painting with the list in view} begin Result := WindowProc(Window, Msg, WParam, LParam);//call original firt; WindowInfo := GetWin32WindowInfo(Window); If TCustomcombobox(WindowInfo^.WinControl).Style = csSimple Then Begin InvalidateRect(WindowInfo^.WinControl.Handle,Nil,true);{border does not paint properly otherwise} end; Exit; end; {/jp} --- and the CreateHandle for the customComboBox This section as we talk about before. // create window If (CBS_SIMPLE and Params.flags)<>0 Then {JP csSimple comboboxes don't paint correctly otherwise.} begin Params.Flags := Params.Flags or CBS_NOINTEGRALHEIGHT; Include(TWinControlAccess(AWinControl).FWinControlFlags, wcfEraseBackground); end; FinishCreateWindow(AWinControl, Params, False, True); Now I just need to figure out why the designer is not allowing the csSimple to size without reloading project. |
|
Looks good! |
|
Resolved, since the issue reported is fixed now without side-effects. Thank you for your effort - great work! Please test again, and close if ok. If you should find a solution for the need to save and re-open the project to see the static listbox you should put this into a separate report. |
|
Side effect 0037670 |
|
Drop count has nothing to do with the csSimple code, I have no idea how that came about but it's most likely else where. Reverting will only make the csSimple its static list box visible unusable since all that was done was to fix a redrawing issue. There was nothing changed that had anything to do with drop down counts.. Most likely something else got changed after the fact. Please look deeper.. Also you'll note that the csSimple still has an issue with you initially put it in csSimple style in the designer, you need to reload your all and after that the box is sizeable. |
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 |
2020-05-30 03:41 | jamie philbrook | Note Added: 0123135 | |
2020-05-30 12:54 | wp | Note Added: 0123146 | |
2020-05-30 18:22 | wp | Status | confirmed => resolved |
2020-05-30 18:22 | wp | Resolution | open => fixed |
2020-05-30 18:22 | wp | Fixed in Revision | => 63251 |
2020-05-30 18:22 | wp | LazTarget | - => 2.0.10 |
2020-05-30 18:22 | wp | Widgetset | Win32/Win64 => Win32/Win64 |
2020-05-30 18:22 | wp | Note Added: 0123148 | |
2020-08-31 18:20 | mgr.inz.Player | Note Added: 0125235 | |
2020-08-31 18:54 | jamie philbrook | Note Added: 0125237 | |
2020-09-01 11:48 | wp | Relationship added | related to 0037670 |
2020-09-01 15:33 | wp | Relationship added | related to 0037679 |
2020-09-01 16:14 | jamie philbrook | Status | resolved => closed |