Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / lazarus / 2003-08

ComboBox problems

17 messages · 6 people ·

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Marc Weustink
to Mattias Gaertner: On Thu, 14 Aug 2003 22:22:11 -0300 I ment the general problem, that the interface does…

+ From: Mattias Gaertner
+ Sent: vrijdag 15 augustus 2003 9:05
+
+ On Thu, 14 Aug 2003 22:22:11 -0300
+ Karl Brandt wrote:
+
+ > Mattias Gaertner wrote:
+ > > On Thu, 14 Aug 2003 14:02:11 -0300
+ > > Karl Brandt wrote:
+ > >
+ > >
+ > >>Mattias Gaertner wrote:
+ > >>
+ > >>>Karl Brandt wrote:
+ > >>>
+ > >>>
+ > >>>> Height is set to 100
+ > >>>> WM_SIZE message with parameter = 100
+ > >>>> Default window proc is called
+ > >>>> Height is modified to 21
+ > >>>> a new WM_SIZE message is sent with parameter = 21
+ > >>>> LCL is updated with Height = 21
+ > >>>> Default window proc finishes and returns to WindowProc
+ > >>>> LCL is updated with Height = 100
+ > >>>> Now we have diferents sizes between LCL and win32
+ > >>>> with TWin32Object.SetComboMinDropDownSize the height
+ > >>>> goes to more then 1000 easily. This is not noted
+ > >>>> because win32 ignores it and adjust the dropdown
+ > >>>> according to the number of items
+ > >>>>
+ > >>>>I see the following solutions
+ > >>>>1) Call DefWindowproc after sending the message to LCL
+ > >>>> But this can affect other messages/controls
+ > >>>>2) Implements a TCustomComboBox.WMSize proc that retrieves the
+ > >>>> current/real size from interface and call inherited with
+ > >>>> updated value
+ > >>>>3) sends a WM_SIZE message with correct value -> did in the patch
+ > >>>
+ > >>>
+ > >>>The 3) is right. Whenever the LCL or the interface changes
+ > >>>the height, a WM_SIZE message should be sent to tell the other.
+ > >>>
+ > >>
+ > >>The downside of this approach is that the LCL is asked
+ > >>three times to change the height each time the size is updated in
+ > >>interface.
+ > >>In the above example changes to 21 -> 100 -> 21
+ > >>What do you,and other developers, think about 1) and 2)?
+ > >
+ > >
+ > > 2) is combobox specific. The problem exists for all controls. I think,
+ > > TWinControl should be advanced.
+ >
+ > AFAIK it's related only for ComboBox
+
+ I ment the general problem, that the interface does not always follow the
+ resizing requests of the LCL. For example: Under gtk you can not
+ change the width of a vertical scrollbar.
+
+
+ > I was thinking about something like this:
+ > procedure TCustomComboBox.WMSize(var Message: TLMSize);
+ > begin
+ > GetWindowSize(FHandle,Message.Width,Message.Height);
+ > Inherited;
+ > end;
+
+ I'm not sure, if I can follow you.
+ The WMSIZE messages are notifications, that a control has been resized. If
+ the WMSIZE message comes from the interface, it should already contain the
+ correct values. Other sources should use SetBounds.

Indeed, the win32interface itself can IMO makeup what it is sending as WM_SIZE messages to the LCL. The Interface knows what the correct size is of a widget. IMO it is a BadThing to modify TCustomComboBox for that. If the win32interface exacly knows what the heigt of a combo would be I have no problem that the interface send a WM_SIZE message 3 times with the same height. Caution, be sure you know ther height, its change may be valid as a result of font and or theme change.

[snip]

+ > Back with combo: DefWindowProc for comboboxes in win32 resizes the
+ > control and call the control windowproc that,for your time, call LCL.
+ > what is happening now:
+ > first LCL receives right value from the nested WindowProc(called by
+ > DefWindowProc)
+
+ But it lacks the information, that the height is fixed and the width is
+ variable. So, how can the LCL know, that there are some constraints? +
+
+ > then LCL receives invalid value overriding the previous one +
+ Who is sending the wrong values?
+
+
+ > If the cited order is inverted then LCL will receive the right size at
+ > last
+ >
+ > >
+ > > What about this:
+ > > TWinControl already uses DoConstrainedResize before resizing.
+ > > We can add
+ > > a function, which asks the interface to apply interface specific
+ > > constraints, before resizing occurs.

I think the interface doesn't always know this, so there should be a general "handling" anyhow. In case of a working general handling, I don't see the need for extra case specific functionality in the LCL.

Again, I think poking around in the LCL to solve interface specifig things should be avoided. If a interface sends a "wrong" value, it shouldn't be solved in the LCL, it should be solved in the interface. So I prefer option 3, with the correct sizes.

Marc

Reply by email

Micha Nelissen
to Karl Brandt: In the last week i looked at the problems with ComboBox height/positioning and noticed…
Mattias Gaertner wrote
Adding lines to TWin32ListStringList.Insert, removing them, adding them. I hope you and Micha will finally find a solution for a six lines method. :)

Yeah, the problem is, sometimes there are multiple ways to fix something and it is difficult to see which one is best, so some experimentation has taken place :).

BTW: the log shows 'fixed combobox height from Vincent', which Karl may or may not like ;).

Micha.

Reply by email

Vincent Snijders
to Karl Brandt: In the last week i looked at the problems with ComboBox height/positioning and noticed…

Micha, Karl and others: congratulations.
This evening I started lazarus on windows and could do something.

Show quoted text 13 lines
Mattias Gaertner wrote: > Adding lines to TWin32ListStringList.Insert, removing them, adding > them. I hope you and Micha will finally find a solution for a six > lines method. :) Yeah, the problem is, sometimes there are multiple ways to fix something and it is difficult to see which one is best, so some experimentation has taken place :). BTW: the log shows 'fixed combobox height from Vincent', which Karl may or may not like ;).

I don't want to have anything to do with these seemingly random patches ;-).

Also Revision 1.84 of winobject.inc:
fixed sizing from Vincent
I only reported the bug, but don't want be associated with its fix. ;-)

Vincent.

Reply by email

Marc Weustink
to Mattias Gaertner: On Fri, 15 Aug 2003 11:25:46 +0200 You are right. There is no real need. It is only for…

+ From: Mattias Gaertner
+ Sent: vrijdag 15 augustus 2003 12:29
+
+ On Fri, 15 Aug 2003 11:25:46 +0200
+ "Marc Weustink" wrote:
+
+ > + > Mattias Gaertner wrote:

[big snip]

+ > + > > What about this:
+ > + > > TWinControl already uses DoConstrainedResize before resizing.
+ > + > > We can add a function, which asks the interface to apply
+ > + > > interface specific constraints, before resizing occurs.
+ >
+ > I think the interface doesn't always know this, so there should be a
+ > general"handling" anyhow. In case of a working general handling, I don't
+ > see the need for extra case specific functionality in the LCL. +
+ You are right. There is no real need.
+ It is only for optimization and avoiding circles.
+ For example, when the user changes the width of a vertical
+ scrollbar to 20, the LCL will automatcially resize all
+ aligned controls and then it sends the setsize message to
+ the interface. The gtk ignores the width change and sets
+ the width to say 14 and sends a size message back.
+ Then the LCL resizes the aligned controls again.

Hmm... that makes sense. I didn't realize that alligning will be done before the interface knows about it.

+ If we add an interface constraint function, the SetBounds (ChangeBounds)
+ method would first ask the interface to apply some constraints. The gtk
+ interface knows in this case, that a vertical scrollbar has a fixed size and
+ will change the width. Then the auto aligning of the LCL occurs. And only
+ once.
+ Under the gtk interface you will not see any acceleration, because of the
+ caching. But it will surely make it easier for the win32 intf and
+ other yet to come interfaces.
+ So, although this function is rarely used and it is not really needed, it
+ reduces some overhead.

OK, good idea. I see the fun of it.

Marc

Reply by email

Mattias Gaertner
to Karl Brandt: In the last week i looked at the problems with ComboBox height/positioning and noticed…
Show quoted text 46 lines
Mattias Gaertner wrote: > On Thu, 14 Aug 2003 14:02:11 -0300 > Karl Brandt wrote: > > >>Mattias Gaertner wrote: >> >>>Karl Brandt wrote: >>> >>> >>>> Height is set to 100 >>>> WM_SIZE message with parameter = 100 >>>> Default window proc is called >>>> Height is modified to 21 >>>> a new WM_SIZE message is sent with parameter = 21 >>>> LCL is updated with Height = 21 >>>> Default window proc finishes and returns to WindowProc >>>> LCL is updated with Height = 100 >>>> Now we have diferents sizes between LCL and win32 >>>>with TWin32Object.SetComboMinDropDownSize the height goes to more >then >>>1000 easily. This is not noted because win32 ignores it and >adjust the >>>dropdown according to the number of items >>>> >>>>I see the following solutions >>>>1) Call DefWindowproc after sending the message to LCL >>>> But this can affect other messages/controls >>>>2) Implements a TCustomComboBox.WMSize proc that retrieves the >>>>current/real size from interface and call inherited with updated value >>>>3) sends a WM_SIZE message with correct value -> did in the patch >>> >>> >>>The 3) is right. Whenever the LCL or the interface changes the height, >a>>WM_SIZE message should be sent to tell the other. >>> >> >>The downside of this approach is that the LCL is asked >> three times to change the height each time the size is updated in >>interface. >>In the above example changes to 21 -> 100 -> 21 >>What do you,and other developers, think about 1) and 2)? > > > 2) is combobox specific. The problem exists for all controls. I think, > TWinControl should be advanced. AFAIK it's related only for ComboBox

I ment the general problem, that the interface does not always follow the resizing requests of the LCL. For example: Under gtk you can not change the width of a vertical scrollbar.

Show quoted text 6 lines
I was thinking about something like this: procedure TCustomComboBox.WMSize(var Message: TLMSize); begin GetWindowSize(FHandle,Message.Width,Message.Height); Inherited; end;

I'm not sure, if I can follow you.
The WMSIZE messages are notifications, that a control has been resized. If the WMSIZE message comes from the interface, it should already contain the correct values. Other sources should use SetBounds.

Show quoted text 6 lines
> 1) This is to late. A SetBounds sends a WM_SIZE message after LCL > internal resizing. I think you're saying a LM_SETSIZE, that in most cases will have no effect, will not generate a WM_SIZE (because win32 ignores when you try to set the size/position with the current/actual values, which is the most of the cases)

The LCL will send LM_SETSIZE only, if the new bounds differ from the last sent bounds.

Show quoted text 5 lines
Back with combo: DefWindowProc for comboboxes in win32 resizes the control and call the control windowproc that,for your time, call LCL. what is happening now: first LCL receives right value from the nested WindowProc(called by DefWindowProc)

But it lacks the information, that the height is fixed and the width is variable. So, how can the LCL know, that there are some constraints?

then LCL receives invalid value overriding the previous one

Who is sending the wrong values?

Show quoted text 8 lines
If the cited order is inverted then LCL will receive the right size at last > > What about this: > TWinControl already uses DoConstrainedResize before resizing. We can add > a function, which asks the interface to apply interface specific > constraints, before resizing occurs.

Mattias

Reply by email

Mattias Gaertner
to Mattias Gaertner
Show quoted text 110 lines
+ From: Mattias Gaertner + Sent: vrijdag 15 augustus 2003 9:05 + + On Thu, 14 Aug 2003 22:22:11 -0300 + Karl Brandt wrote: + + > Mattias Gaertner wrote: + > > On Thu, 14 Aug 2003 14:02:11 -0300 + > > Karl Brandt wrote: + > > + > > + > >>Mattias Gaertner wrote: + > >> + > >>>Karl Brandt wrote: + > >>> + > >>> + > >>>> Height is set to 100 + > >>>> WM_SIZE message with parameter = 100 + > >>>> Default window proc is called + > >>>> Height is modified to 21 + > >>>> a new WM_SIZE message is sent with parameter = 21 + > >>>> LCL is updated with Height = 21 + > >>>> Default window proc finishes and returns to WindowProc + > >>>> LCL is updated with Height = 100 + > >>>> Now we have diferents sizes between LCL and win32 + > >>>> with TWin32Object.SetComboMinDropDownSize the height + > >>>> goes to more then 1000 easily. This is not noted + > >>>> because win32 ignores it and adjust the dropdown + > >>>> according to the number of items + > >>>> + > >>>>I see the following solutions + > >>>>1) Call DefWindowproc after sending the message to LCL + > >>>> But this can affect other messages/controls + > >>>>2) Implements a TCustomComboBox.WMSize proc that retrieves the + > >>>> current/real size from interface and call inherited with + > >>>> updated value + > >>>>3) sends a WM_SIZE message with correct value -> did in the patch + > >>> + > >>> + > >>>The 3) is right. Whenever the LCL or the interface changes + > >>>the height, a WM_SIZE message should be sent to tell the other. + > >>> + > >> + > >>The downside of this approach is that the LCL is asked + > >>three times to change the height each time the size is updated in + > >>interface. + > >>In the above example changes to 21 -> 100 -> 21 + > >>What do you,and other developers, think about 1) and 2)? + > > + > > + > > 2) is combobox specific. The problem exists for all controls. I think,+ > > TWinControl should be advanced. + > + > AFAIK it's related only for ComboBox + + I ment the general problem, that the interface does not always follow the+ resizing requests of the LCL. For example: Under gtk you can not + change the width of a vertical scrollbar. + + + > I was thinking about something like this: + > procedure TCustomComboBox.WMSize(var Message: TLMSize); + > begin + > GetWindowSize(FHandle,Message.Width,Message.Height); + > Inherited; + > end; + + I'm not sure, if I can follow you. + The WMSIZE messages are notifications, that a control has been resized. If+ the WMSIZE message comes from the interface, it should already contain the+ correct values. Other sources should use SetBounds. Indeed, the win32interface itself can IMO makeup what it is sending as WM_SIZE messages to the LCL. The Interface knows what the correct size is of a widget. IMO it is a BadThing to modify TCustomComboBox for that. If the win32interface exacly knows what the heigt of a combo would be I have no problem that the interface send a WM_SIZE message 3 times with the same height. Caution, be sure you know ther height, its change may be valid as a result of font and or theme change. [snip] + > Back with combo: DefWindowProc for comboboxes in win32 resizes the + > control and call the control windowproc that,for your time, call LCL. + > what is happening now: + > first LCL receives right value from the nested WindowProc(called by + > DefWindowProc) + + But it lacks the information, that the height is fixed and the width is + variable. So, how can the LCL know, that there are some constraints? + + + > then LCL receives invalid value overriding the previous one + + Who is sending the wrong values? + + + > If the cited order is inverted then LCL will receive the right size at + > last + > + > > + > > What about this: + > > TWinControl already uses DoConstrainedResize before resizing. + > > We can add + > > a function, which asks the interface to apply interface specific + > > constraints, before resizing occurs. I think the interface doesn't always know this, so there should be a general"handling" anyhow. In case of a working general handling, I don't see the need for extra case specific functionality in the LCL.

You are right. There is no real need.
It is only for optimization and avoiding circles.
For example, when the user changes the width of a vertical scrollbar to 20, the LCL will automatcially resize all aligned controls and then it sends the setsize message to the interface. The gtk ignores the width change and sets the width to say 14 and sends a size message back. Then the LCL resizes the aligned controls again.
If we add an interface constraint function, the SetBounds (ChangeBounds) method would first ask the interface to apply some constraints. The gtk interface knows in this case, that a vertical scrollbar has a fixed size and will change the width. Then the auto aligning of the LCL occurs. And only once.
Under the gtk interface you will not see any acceleration, because of the caching. But it will surely make it easier for the win32 intf and other yet to come interfaces.
So, although this function is rarely used and it is not really needed, it reduces some overhead.

Again, I think poking around in the LCL to solve interface specifig things should be avoided.

yep. But I think the struggle between the autosizing of the LCL and interface limits can be called interface independent.

If a interface sends a "wrong" value, it shouldn't be solved in the LCL, it should be solved in the interface.

yep

So I prefer option 3, with the correct sizes.

Mattias

Reply by email

Karl Brandt
to Karl Brandt: In the last week i looked at the problems with ComboBox height/positioning and noticed…
Mattias Gaertner wrote 14 lines
On Thu, 14 Aug 2003 22:22:11 -0300 Karl Brandt wrote: >Mattias Gaertner wrote: > >>On Thu, 14 Aug 2003 14:02:11 -0300 >>Karl Brandt wrote: >> >> >> >>>Mattias Gaertner wrote: >>> >>>

(...)

Show quoted text 17 lines
>>>The downside of this approach is that the LCL is asked >>> three times to change the height each time the size is updated in >>>interface. >>>In the above example changes to 21 -> 100 -> 21 >>>What do you,and other developers, think about 1) and 2)? >> >> >>2) is combobox specific. The problem exists for all controls. I think, >>TWinControl should be advanced. > >AFAIK it's related only for ComboBox I ment the general problem, that the interface does not always follow the resizing requests of the LCL. For example: Under gtk you can not change the width of a vertical scrollbar.

ok.

Show quoted text 15 lines
>I was thinking about something like this: >procedure TCustomComboBox.WMSize(var Message: TLMSize); >begin > GetWindowSize(FHandle,Message.Width,Message.Height); > Inherited; >end; I'm not sure, if I can follow you. The WMSIZE messages are notifications, that a control has been resized. If the WMSIZE message comes from the interface, it should already contain the correct values. Other sources should use SetBounds.

ok.
Please remember that are just suggestions.

Show quoted text 13 lines
>>1) This is to late. A SetBounds sends a WM_SIZE message after LCL >>internal resizing. > >I think you're saying a LM_SETSIZE, that in most cases will have no >effect, will not generate a WM_SIZE (because win32 ignores when you try to >set the size/position with the current/actual values, which is the most of >the cases) The LCL will send LM_SETSIZE only, if the new bounds differ from the last sent bounds.

I know.
This has effect into interface if the bounds are set in LCL, like using Width, height properties, but in the cases of callback of move or resize then this will have no effect. See the scenario:
We have a form with height=100 width=200
(In LCL height=100 width=200, In Intf height=100 width=200) Then the user resizes to Height=101
(In LCL height=100 width=200, In Intf height=101 width=200) Callback sends to LCL the intf values, updating them (In LCL height=101 width=200, In Intf height=101 width=200) Now, as the bounds differ from last bounds the LCL asks the intf to update their values (height=101 width=200), but the intf already has these values,making a additional, not necessary, step.

It's occurring because changes came from callback or LCL share the same function (SetBounds).
Maybe a way to split/diferentiate these calls could be useful.

Show quoted text 18 lines
>Back with combo: DefWindowProc for comboboxes in win32 resizes the >control and call the control windowproc that,for your time, call LCL. >what is happening now: > first LCL receives right value from the nested WindowProc(called by >DefWindowProc) But it lacks the information, that the height is fixed and the width is variable. So, how can the LCL know, that there are some constraints? > then LCL receives invalid value overriding the previous one Who is sending the wrong values?

Both comes from intf(in really win32).What occurs is that at win32 side, the first value is changed to the second(determined by win32) and at the end the control has the correct size(we can see using GetClientRect or GetWindowRect).
But, because of the order of calling the nested windowproc, as explained before, the LCL receives the first value by last.

BTW in gtk, the message notifications are sent before calling default procedures ?

What is expected by LCL? LCL handles the messages before or after the toolkit?

karl

Reply by email

Mattias Gaertner
to Karl Brandt: In the last week i looked at the problems with ComboBox height/positioning and noticed…
Show quoted text 36 lines
In the last week i looked at the problems with ComboBox height/positioning and noticed the following: --Behavior of setting combo(CS_DROPDOWN) height: When you set the height of the combo to an alleatory value (let's say 100), the DefaultWndProc (called with DefWindowProc or CallWindowProc) resizes the combo to a value based in the font of the control(in the case of DEFAULT_GUI_FONT, 21) and then sends a new WM_SIZE to control with the corrected size, which is the value we get calling GetClientRect and GetWindowRect --PropertyGrid being pushed for down when combobox was droppedown: TWin32Object.SetComboMinDropDownSize increments the height of combobox progressively each time is called. Just put some writeln in TWincontrol.WMSIZE to inspect what happen with the LCL height. But according to what i said before the LCL should receive only the correct value. But it doesn't. This is what happens Height is set to 100 WM_SIZE message with parameter = 100 Default window proc is called Height is modified to 21 a new WM_SIZE message is sent with parameter = 21 LCL is updated with Height = 21 Default window proc finishes and returns to WindowProc LCL is updated with Height = 100 Now we have diferents sizes between LCL and win32 with TWin32Object.SetComboMinDropDownSize the height goes to more then 1000 easily. This is not noted because win32 ignores it and adjust the dropdown according to the number of items I see the following solutions 1) Call DefWindowproc after sending the message to LCL But this can affect other messages/controls 2) Implements a TCustomComboBox.WMSize proc that retrieves the current/real size from interface and call inherited with updated value 3) sends a WM_SIZE message with correct value -> did in the patch

The 3) is right. Whenever the LCL or the interface changes the height, a WM_SIZE message should be sent to tell the other.

Show quoted text 6 lines
The patch fix the current (more to come) issues: diferences between Height in LCL/win32, Notebook control in ObjectInspector is aligned exactly where should do, strange effects in Enviroment options dialog, can't see more than 9 items. I hope this can be applied.

The internet is bomb safe, but not virus safe.
Finally applied. It seems "cvs commit" is ten times slower than all other cvs operations.

It's a better solution then the current.

Adding lines to TWin32ListStringList.Insert, removing them, adding them. I hope you and Micha will finally find a solution for a six lines method. :)

Mattias

Reply by email

Karl Brandt
to Karl Brandt: In the last week i looked at the problems with ComboBox height/positioning and noticed…
Micha Nelissen wrote 12 lines
Mattias Gaertner wrote: > Adding lines to TWin32ListStringList.Insert, removing them, adding > them. I > hope you and Micha will finally find a solution for a six lines > method. :) Yeah, the problem is, sometimes there are multiple ways to fix something and it is difficult to see which one is best, so some experimentation has taken place :).

This can be avoided with better comunication/integration. In really the modifications were not related to inserting items. They were related to how and where update the combo dropdownlist.

karl

Reply by email

Karl Brandt
to Karl Brandt: In the last week i looked at the problems with ComboBox height/positioning and noticed…
Mattias Gaertner wrote 43 lines
On Thu, 14 Aug 2003 14:02:11 -0300 Karl Brandt wrote: >Mattias Gaertner wrote: > >>Karl Brandt wrote: >> >> >>> Height is set to 100 >>> WM_SIZE message with parameter = 100 >>> Default window proc is called >>> Height is modified to 21 >>> a new WM_SIZE message is sent with parameter = 21 >>> LCL is updated with Height = 21 >>> Default window proc finishes and returns to WindowProc >>> LCL is updated with Height = 100 >>> Now we have diferents sizes between LCL and win32 >>>with TWin32Object.SetComboMinDropDownSize the height goes to more then >>>1000 easily. This is not noted because win32 ignores it and adjust the >>>dropdown according to the number of items >>> >>>I see the following solutions >>>1) Call DefWindowproc after sending the message to LCL >>> But this can affect other messages/controls >>>2) Implements a TCustomComboBox.WMSize proc that retrieves the >>>current/real size from interface and call inherited with updated value >>>3) sends a WM_SIZE message with correct value -> did in the patch >> >> >>The 3) is right. Whenever the LCL or the interface changes the height, a >>WM_SIZE message should be sent to tell the other. >> > >The downside of this approach is that the LCL is asked > three times to change the height each time the size is updated in >interface. >In the above example changes to 21 -> 100 -> 21 >What do you,and other developers, think about 1) and 2)? 2) is combobox specific. The problem exists for all controls. I think, TWinControl should be advanced.

AFAIK it's related only for ComboBox

I was thinking about something like this:
procedure TCustomComboBox.WMSize(var Message: TLMSize);
begin
   GetWindowSize(FHandle,Message.Width,Message.Height);
   Inherited;
end;
1) This is to late. A SetBounds sends a WM_SIZE message after LCL internal resizing.

I think you're saying a LM_SETSIZE, that in most cases will have no effect, will not generate a WM_SIZE (because win32 ignores when you try to set the size/position with the current/actual values, which is the most of the cases)

Back with combo: DefWindowProc for comboboxes in win32 resizes the control and call the control windowproc that,for your time, call LCL. what is happening now:
first LCL receives right value from the nested WindowProc(called by DefWindowProc)
then LCL receives invalid value overriding the previous one

If the cited order is inverted then LCL will receive the right size at last

Show quoted text 5 lines
What about this: TWinControl already uses DoConstrainedResize before resizing. We can add a function, which asks the interface to apply interface specific constraints, before resizing occurs.

karl

Reply by email

Mattias Gaertner
to Karl Brandt: In the last week i looked at the problems with ComboBox height/positioning and noticed…
Show quoted text 32 lines
Mattias Gaertner wrote: > Karl Brandt wrote: > >> Height is set to 100 >> WM_SIZE message with parameter = 100 >> Default window proc is called >> Height is modified to 21 >> a new WM_SIZE message is sent with parameter = 21 >> LCL is updated with Height = 21 >> Default window proc finishes and returns to WindowProc >> LCL is updated with Height = 100 >> Now we have diferents sizes between LCL and win32 >>with TWin32Object.SetComboMinDropDownSize the height goes to more then >>1000 easily. This is not noted because win32 ignores it and adjust the >>dropdown according to the number of items >> >>I see the following solutions >>1) Call DefWindowproc after sending the message to LCL >> But this can affect other messages/controls >>2) Implements a TCustomComboBox.WMSize proc that retrieves the >>current/real size from interface and call inherited with updated value >>3) sends a WM_SIZE message with correct value -> did in the patch > > > The 3) is right. Whenever the LCL or the interface changes the height, a > WM_SIZE message should be sent to tell the other. > The downside of this approach is that the LCL is asked three times to change the height each time the size is updated in interface. In the above example changes to 21 -> 100 -> 21 What do you,and other developers, think about 1) and 2)?

2) is combobox specific. The problem exists for all controls. I think, TWinControl should be advanced.

1) This is to late. A SetBounds sends a WM_SIZE message after LCL internal resizing.

What about this:
TWinControl already uses DoConstrainedResize before resizing. We can add a function, which asks the interface to apply interface specific constraints, before resizing occurs.

Mattias

Reply by email

Karl Brandt

In the last week i looked at the problems with ComboBox height/positioning and noticed the following:

--Behavior of setting combo(CS_DROPDOWN) height:
When you set the height of the combo to an alleatory value (let's say 100), the DefaultWndProc (called with DefWindowProc or CallWindowProc) resizes the combo to a value based in the font of the control(in the case of DEFAULT_GUI_FONT, 21) and then sends a new WM_SIZE to control with the corrected size, which is the value we get calling GetClientRect and GetWindowRect

--PropertyGrid being pushed for down when combobox was droppedown: TWin32Object.SetComboMinDropDownSize increments the height of combobox progressively each time is called. Just put some writeln in TWincontrol.WMSIZE to inspect what happen with the LCL height. But according to what i said before the LCL should receive only the correct value. But it doesn't. This is what happens Height is set to 100
WM_SIZE message with parameter = 100
Default window proc is called
Height is modified to 21
a new WM_SIZE message is sent with parameter = 21
LCL is updated with Height = 21
Default window proc finishes and returns to WindowProc LCL is updated with Height = 100
Now we have diferents sizes between LCL and win32
with TWin32Object.SetComboMinDropDownSize the height goes to more then 1000 easily. This is not noted because win32 ignores it and adjust the dropdown according to the number of items

I see the following solutions
1) Call DefWindowproc after sending the message to LCL But this can affect other messages/controls
2) Implements a TCustomComboBox.WMSize proc that retrieves the current/real size from interface and call inherited with updated value
3) sends a WM_SIZE message with correct value -> did in the patch

The patch fix the current (more to come) issues: diferences between Height in LCL/win32, Notebook control in ObjectInspector is aligned exactly where should do, strange effects in Enviroment options dialog, can't see more than 9 items.

I hope this can be applied. It's a better solution then the current.

karl

-------------- next part --------------
A non-text attachment was scrubbed...
Name: zip00028.zip
Type: application/octet-stream
Size: 2955 bytes
Desc: "comboagain.zip"
Url : http://localhost/pipermail/lazarus/attachments/20030813/632f9470/zip00028.obj

Reply by email

Karl Brandt
to Karl Brandt
Mattias Gaertner wrote 26 lines
Karl Brandt wrote: > Height is set to 100 > WM_SIZE message with parameter = 100 > Default window proc is called > Height is modified to 21 > a new WM_SIZE message is sent with parameter = 21 > LCL is updated with Height = 21 > Default window proc finishes and returns to WindowProc > LCL is updated with Height = 100 > Now we have diferents sizes between LCL and win32 >with TWin32Object.SetComboMinDropDownSize the height goes to more then >1000 easily. This is not noted because win32 ignores it and adjust the >dropdown according to the number of items > >I see the following solutions >1) Call DefWindowproc after sending the message to LCL > But this can affect other messages/controls >2) Implements a TCustomComboBox.WMSize proc that retrieves the >current/real size from interface and call inherited with updated value >3) sends a WM_SIZE message with correct value -> did in the patch The 3) is right. Whenever the LCL or the interface changes the height, a WM_SIZE message should be sent to tell the other.

The downside of this approach is that the LCL is asked three times to change the height each time the size is updated in interface.
In the above example changes to 21 -> 100 -> 21
What do you,and other developers, think about 1) and 2)?

karl

Reply by email

Mattias Gaertner
to Karl Brandt: In the last week i looked at the problems with ComboBox height/positioning and noticed…
Show quoted text 80 lines
Mattias Gaertner wrote: > On Thu, 14 Aug 2003 22:22:11 -0300 > Karl Brandt wrote: > > >>Mattias Gaertner wrote: >> >>>On Thu, 14 Aug 2003 14:02:11 -0300 >>>Karl Brandt wrote: >>> >>> >>> >>>>Mattias Gaertner wrote: >>>> >>>> (...) >>>>The downside of this approach is that the LCL is asked >>>> three times to change the height each time the size is updated in >>>>interface. >>>>In the above example changes to 21 -> 100 -> 21 >>>>What do you,and other developers, think about 1) and 2)? >>> >>> >>>2) is combobox specific. The problem exists for all controls. I think, >>>TWinControl should be advanced. >> >>AFAIK it's related only for ComboBox > > > I ment the general problem, that the interface does not always follow > the resizing requests of the LCL. For example: Under gtk you can not > change the width of a vertical scrollbar. > ok. > > >>I was thinking about something like this: >>procedure TCustomComboBox.WMSize(var Message: TLMSize); >>begin >> GetWindowSize(FHandle,Message.Width,Message.Height); >> Inherited; >>end; > > > I'm not sure, if I can follow you. > The WMSIZE messages are notifications, that a control has been resized. > If the WMSIZE message comes from the interface, it should already > contain the correct values. Other sources should use SetBounds. > ok. Please remember that are just suggestions. > >>>1) This is to late. A SetBounds sends a WM_SIZE message after LCL >>>internal resizing. >> >>I think you're saying a LM_SETSIZE, that in most cases will have no >>effect, will not generate a WM_SIZE (because win32 ignores when you try >to>set the size/position with the current/actual values, which is the >most of>the cases) > > > The LCL will send LM_SETSIZE only, if the new bounds differ from the > last sent bounds. > I know. This has effect into interface if the bounds are set in LCL, like using Width, height properties, but in the cases of callback of move or resize then this will have no effect. See the scenario: We have a form with height=100 width=200 (In LCL height=100 width=200, In Intf height=100 width=200) Then the user resizes to Height=101 (In LCL height=100 width=200, In Intf height=101 width=200) Callback sends to LCL the intf values, updating them (In LCL height=101 width=200, In Intf height=101 width=200) Now, as the bounds differ from last bounds the LCL asks the intf to update their values (height=101 width=200), but the intf already has these values,making a additional, not necessary, step.

Now I'm sure that I can't follow you.
If the win32 intf has already the same bounds, why does it not ignore the LCL request?

BTW,
When the users resizes and the win32 intf sends the 200,101, TWinControl.WMSize updates the FBoundsRealized variable. So, if nothing special happens the LCL will not send the 200,101.

It's occurring because changes came from callback or LCL share the same function (SetBounds). Maybe a way to split/diferentiate these calls could be useful.

There is already a difference: win32 intf uses WMSize as entry point to the LCL.

Show quoted text 24 lines
>>Back with combo: DefWindowProc for comboboxes in win32 resizes the >>control and call the control windowproc that,for your time, call LCL. >>what is happening now: >> first LCL receives right value from the nested WindowProc(called by >>DefWindowProc) > > > But it lacks the information, that the height is fixed and the width is > variable. So, how can the LCL know, that there are some constraints? > > > >> then LCL receives invalid value overriding the previous one > > > Who is sending the wrong values? > Both comes from intf(in really win32).What occurs is that at win32 side, the first value is changed to the second(determined by win32) and at the end the control has the correct size(we can see using GetClientRect or GetWindowRect). But, because of the order of calling the nested windowproc, as explained before, the LCL receives the first value by last.

Hmm. I think, I need a deeper look. Can you send me an example program please?

BTW in gtk, the message notifications are sent before calling default procedures ?

The gtk/X has a very different resize mechanism. For example it uses queued resize requests. You can get the following:
gtk intf sends to gtk Width=100
gtk intf sends to gtk Width=200
gtk intf sends to gtk Width=300
gtk sends to gtk intf Width=100
gtk sends to gtk intf Width=200
gtk sends to gtk intf Width=300

What is expected by LCL? LCL handles the messages before or after the toolkit?

The message handling and order depends too much on the interface to specify an exact order. This implies: When the LCL sends a SetSize message to the interface, it does neither expect, that it is applied immediately, nor that the intf applies the coordinates. This also implies that the intf and the LCL are not always in sync. Therefore the LCL tries to avoid asking the interface about the current size of a window/widget. It is up to the intf to update the LCL.

Mattias

Reply by email

Karl Brandt
to Karl Brandt: In the last week i looked at the problems with ComboBox height/positioning and noticed…

Mattias Gaertner wrote:

(...)

Show quoted text 5 lines
Now I'm sure that I can't follow you. If the win32 intf has already the same bounds, why does it not ignore the LCL request?

Good question.

Show quoted text 5 lines
BTW, When the users resizes and the win32 intf sends the 200,101, TWinControl.WMSize updates the FBoundsRealized variable. So, if nothing special happens the LCL will not send the 200,101.

ok

Show quoted text 10 lines
>It's occurring because changes came from callback or LCL share the same >function (SetBounds). >Maybe a way to split/diferentiate these calls could be useful. There is already a difference: win32 intf uses WMSize as entry point to the LCL.

(...)

Show quoted text 16 lines
>>> then LCL receives invalid value overriding the previous one >> >> >>Who is sending the wrong values? >> > >Both comes from intf(in really win32).What occurs is that at win32 side, > the first value is changed to the second(determined by win32) and at >the end the control has the correct size(we can see using GetClientRect >or GetWindowRect). >But, because of the order of calling the nested windowproc, as explained >before, the LCL receives the first value by last. Hmm. I think, I need a deeper look. Can you send me an example program please?
I'm sending  a testprogram and a patch to win32 that do some trace
information. Also, add the following to Wincontrol.WMSize
   If FCompStyle = csComboBox then
     begin
     writeln('LCL is receiving height: ',Message.Height);
     writeln('LCL current height: ',Height);
     end;

The trace will look like this:

Entering DefWindowProc with height: 21
Exiting DefWindowProc with height: 21
LCL is receiving height: 21
LCL current height: 20
LCL is receiving height: 21
LCL current height: 21
Height is set to 127 for update DropDown list size limit Entering DefWindowProc with height: 127
-> Here DefWindowProc changes height to 21 and calls WindowProc with updated value
Entering DefWindowProc with height: 21 ; Here we are in the nested WindowProc
Exiting DefWindowProc with height: 21 ;The nested windowproc notify LCL LCL is receiving height: 21
LCL current height: 21
Exiting DefWindowProc with height: 127 ;back to first Windowproc LCL is receiving height: 127
LCL current height: 21
LCL is receiving height: 127 ;??? From where this call came? LCL current height: 127 ;LM_SIZE is notified in another place?

Here we try to set Height to 12345
Same as above

Entering DefWindowProc with height: 12345
Entering DefWindowProc with height: 21
Exiting DefWindowProc with height: 21
LCL is receiving height: 21
LCL current height: 127
LCL is receiving height: 21
LCL current height: 21
Exiting DefWindowProc with height: 12345
LCL is receiving height: 12345
LCL current height: 21
LCL is receiving height: 12345 ???
LCL current height: 12345 ???

If DefWindowProc is called after notifying the LCL, the LCL will receive the correct value, but other things will not work.

I already have an idea of how to fix this inside intf, it's a question of doing it and testing it.

Show quoted text 28 lines
>BTW in gtk, the message notifications are sent before calling default >procedures ? The gtk/X has a very different resize mechanism. For example it uses queued resize requests. You can get the following: gtk intf sends to gtk Width=100 gtk intf sends to gtk Width=200 gtk intf sends to gtk Width=300 gtk sends to gtk intf Width=100 gtk sends to gtk intf Width=200 gtk sends to gtk intf Width=300 >What is expected by LCL? LCL handles the messages before or after the >toolkit? The message handling and order depends too much on the interface to specify an exact order. This implies: When the LCL sends a SetSize message to the interface, it does neither expect, that it is applied immediately, nor that the intf applies the coordinates. This also implies that the intf and the LCL are not always in sync. Therefore the LCL tries to avoid asking the interface about the current size of a window/widget. It is up to the intf to update the LCL.

ok

karl

-------------- next part --------------
A non-text attachment was scrubbed...
Name: zip00030.zip
Type: application/octet-stream
Size: 935 bytes
Desc: "testcombo.zip"
Url : http://localhost/pipermail/lazarus/attachments/20030816/a1aa06ea/zip00030.obj -------------- next part --------------
A non-text attachment was scrubbed...
Name: zip00029.zip
Type: application/octet-stream
Size: 1381 bytes
Desc: "test.zip"
Url : http://localhost/pipermail/lazarus/attachments/20030816/a1aa06ea/zip00029.obj

Reply by email

Marco van de Voort
to Mattias Gaertner: On Sat, 16 Aug 2003 17:19:02 -0300 I have fixed a few resize things in the win32 intf.…
Show quoted text 21 lines
Karl Brandt wrote: > Mattias Gaertner wrote: > > [...] > > Hmm. I think, I need a deeper look. Can you send me an example program > > please? I have fixed a few resize things in the win32 intf. But there is still a few things to do. - win32 intf: - WM_SIZE, WM_MOVE are not sent, when nothing changed - fixed WM_SIZE: LParam contains the client size, not the size - fixed WM_SIZE: updates now LCL clientrect - fixed WM_MOVE: LParam is relative to the parent origin, not the parent's client origin - fixed GetWindowSize: returns the size, not the client size - improved LCLBoundsToWin32Bounds and Win32PosToLCLPos for groupbox - fixed LM_SETSIZE: form size - improved but not comletely fixed GetWindowSize

If you need a few extra Windows Api units, check projects/contrib/winapi :-)

Reply by email

Mattias Gaertner
to Karl Brandt: In the last week i looked at the problems with ComboBox height/positioning and noticed…
Show quoted text 5 lines
Mattias Gaertner wrote: [...] > Hmm. I think, I need a deeper look. Can you send me an example program > please?

I have fixed a few resize things in the win32 intf. But there is still a few things to do.

- win32 intf:
- WM_SIZE, WM_MOVE are not sent, when nothing changed
- fixed WM_SIZE: LParam contains the client size, not the size
- fixed WM_SIZE: updates now LCL clientrect
- fixed WM_MOVE: LParam is relative to the parent origin, not the parent's client origin
- fixed GetWindowSize: returns the size, not the client size
- improved LCLBoundsToWin32Bounds and Win32PosToLCLPos for groupbox
- fixed LM_SETSIZE: form size
- improved but not comletely fixed GetWindowSize

ToDo:
- MainMenu. The form size must be adjusted (e.g. in GetWindowSize).
- combobox: didn't have the time to hope, this helps, Mattias

Reply by email