Setting PopupMenu Height

  1. ‹ Older
  2. 2 years ago

    Julian S

    12 Jul 2017 Pre-Release Testers, Xojo Pro UK
    Edited 2 years ago

    By default, PopupMenus/ComboBoxes are dependent on the size of the font but the size of them should be able to be changed with

    SendNotifyMessageW(PopupMenu1.Handle, CB_SETITEMHEIGHT, -1, 50) which sets the height of the base control to 50

    It looks to be a bug that its not taking the size from the Height parameter in the IDE.

    From an initial test, Xojo are using the correct system to resize the control, but they are doing it at the wrong time. It seems like they are setting the height when the control is clicked (but only to the default height) and not when its opened.

    If you place the following code into the Popup.Open

    Const CB_SETITEMHEIGHT = &h0153
    Declare Function SendMessageW Lib "User32" (hWnd As Integer, Msg As UInt32, wParam As UInteger, lParam As Integer) As Integer
    Call SendMessageW(PopupMenu1.Handle, CB_SETITEMHEIGHT, -1, 50)

    You see that it correctly sets the height to 50. As soon you click on the control it changes height again (bug?), I assume that Xojo is doing something behind the scenes here when it shouldn't be, probably firing another SendMessageW at the control which should actually be firing at the open, and not the click.

    You can see this happening if you copy the above code into PopupMenu.Open and PopupMenu.MouseDown, when you click the control a few times and the initial popup has rendered and closed, it then works for all future updates.

    Michel would have to chip in here to let us know how he got around that, I could probably find out with a bit of trial and error but it would be quicker if he wants to chip in, I dont know if he wants to as he might want to protect the IP in his control.

  3. Jon O

    12 Jul 2017 Pre-Release Testers, Xojo Pro Chicago Area USA

    OK. Glad I'm not seeing things. It seems this is a recent bug then as Windows was always able to adjust the height of pop-up menus. OS X is not so easy to do (you have to do it in declares and then never again poll the height property).

    Now in Mitch's code, he's just setting it like one would normally expect. And it's working! That's what's driving me nuts. I did a simple test app and his resizing works, mine doesn't and I don't understand why.

  4. Julian S

    12 Jul 2017 Pre-Release Testers, Xojo Pro UK

    I dont know about rubber views Jon, I just downloaded the latest trial from Michels site, I set the PopupMenu1 with the word "Effects" in the middle of the form to 50 height and it came out as default height. However his resize when the form is resized works but he's probably doing something that I'm not because he's spent more time researching it :) I don't know, I found three bugs in rubberviews in the 2 minutes I've been playing with it =\ I'm just a bug magnet, hehe.

  5. Julian S

    12 Jul 2017 Pre-Release Testers, Xojo Pro UK
    Edited 2 years ago

    Just had a little play around, I think Michel does it by calling:

    PopupMenu1.TextSize = 50 (or whatever size he calculates to be the scaling factor to fit the size he needs)

    in the open. That auto-sizes the control to fit the text and increases its overall size. It's not the correct way of doing it, but its the Xojo way. If you change that in the IDE (using the gear on inspector) it doesnt even alter the size of the control correctly (bug) until you go back into the form, then the selectable area of the control isnt right (bug).

    Call SendMessageW(PopupMenu1.Handle, CB_SETITEMHEIGHT, -1, 50)

    That call should work, it does, to a fashion, but there's a load of problems going on with the control not doing things correctly. Eg, I can size it correctly, and fire this at it:

    Call SendMessageW(PopupMenu1.Handle, CB_SHOWDROPDOWN, 1, 0)

    which opens the popup via code and works perfectly, but the second I click the popup with the mouse it breaks and resets the size of the control. There's so many redundant or incorrectly placed calls going on. I'm actually amazed that anything works as it should to be honest.

    The control needs a huge bug report, there's so much wrong with it it'll take me a long time to document and prove all the problems, which is why I'm not putting in bug reports at the moment, I just cant face putting the effort in at the moment for it to be forgotten about for 6-12 months and not fixed.

  6. Jon O

    12 Jul 2017 Pre-Release Testers, Xojo Pro Chicago Area USA

    Julian,

    Forgive me but is there a code module some place that has the SendMessageW function?

  7. Julian S

    12 Jul 2017 Pre-Release Testers, Xojo Pro UK

    I just shut my computer off (on my iPad) so I had to copy this from a xojo blog

    Declare Sub SendMessageW Lib "User32" (hwnd As Integer, msg As Integer, wParam As Integer, lParam As Integer)

    Just place that somewhere above the call.

    You can find the vales for CB_* just google them, wine usually have records of the .h they are in.

  8. Jon O

    13 Jul 2017 Pre-Release Testers, Xojo Pro Chicago Area USA

    @Julian S Just had a little play around, I think Michel does it by calling:

    PopupMenu1.TextSize = 50 (or whatever size he calculates to be the scaling factor to fit the size he needs)

    in the open. That auto-sizes the control to fit the text and increases its overall size. It's not the correct way of doing it, but its the Xojo way. If you change that in the IDE (using the gear on inspector) it doesnt even alter the size of the control correctly (bug) until you go back into the form, then the selectable area of the control isnt right (bug).

    Call SendMessageW(PopupMenu1.Handle, CB_SETITEMHEIGHT, -1, 50)

    That call should work, it does, to a fashion, but there's a load of problems going on with the control not doing things correctly. Eg, I can size it correctly, and fire this at it:

    Call SendMessageW(PopupMenu1.Handle, CB_SHOWDROPDOWN, 1, 0)

    which opens the popup via code and works perfectly, but the second I click the popup with the mouse it breaks and resets the size of the control. There's so many redundant or incorrectly placed calls going on. I'm actually amazed that anything works as it should to be honest.

    The control needs a huge bug report, there's so much wrong with it it'll take me a long time to document and prove all the problems, which is why I'm not putting in bug reports at the moment, I just cant face putting the effort in at the moment for it to be forgotten about for 6-12 months and not fixed.

    It looks like if you set the height twice with SendMessageW that it becomes permanent. I see exactly what you mean when you say you set it but then as soon as you touch it, it reverts. But if you set it again, it stays. So there's definitely something odd going on.

    Also, maybe it's the way the controls are in Windows itself but there are specific heights that the PopUpMenu can be set to. It doesn't seem they are all that granular.

  9. Julian S

    13 Jul 2017 Pre-Release Testers, Xojo Pro UK

    @Jon O It looks like if you set the height twice with SendMessageW that it becomes permanent.

    Nice

    @Jon O Also, maybe it's the way the controls are in Windows itself but there are specific heights that the PopUpMenu can be set to.

    Nope, I tried it in another language and it stuck first time.

    I'm glad you got something working at least. :)

  10. Jon O

    13 Jul 2017 Pre-Release Testers, Xojo Pro Chicago Area USA

    Well, it's weird.

    First it is granular. The heights are specific. So that's good.

    But it's like you have to touch the control first before sending the second message will make it stick. So it's somewhat odd. I'm trying to figure out exactly what you need to do and if I can somehow simulate a touch in Xojo code but I haven't figured it out yet...

    But once it's been "touched" and you send a second message, then it sticks...

  11. Julian S

    13 Jul 2017 Pre-Release Testers, Xojo Pro UK

    Yeah, thats what I was seeing, I had a separate button to force the size again and it would work fine once the dropdown had been shown.

    Bugs :(

    The control could also use a .DroppedDown boolean property to force it open/closed in code which would just be a call to:

    SendMessageW(PopupMenu1.Handle, CB_SHOWDROPDOWN, 1, 0)

    in windows.

  12. Jon O

    13 Jul 2017 Pre-Release Testers, Xojo Pro Chicago Area USA
    Edited 2 years ago

    It's a little frustrating because if a user touches the control for the first time and makes a selection to the listbox, I can call SendMessageW from the change event. However, if the user touches the control but then doesn't change the selection, the change event does not fire. MouseExit doesn't seem to work reliably here as the mouse is generally already away from the control if there is no selection made. The resize happens AFTER the menu closes. But there is no event for that.

    I thought maybe I could use SendMessageW to show the menu and control it myself but while that shows it, it seems like it doesn't stay open.

    [EDIT]

    OK - The ShowDropdown message works fine. I was trying to send it in the MouseDown event of the control and then return True so I could handle things myself. But that is what doesn't seem to work right. ARGH! :(

  13. Julian S

    13 Jul 2017 Pre-Release Testers, Xojo Pro UK

    Yeah, I've tried a few different combinations too, couldn't get a satisfactory result here either :(

  14. Jon O

    13 Jul 2017 Pre-Release Testers, Xojo Pro Chicago Area USA

    I think I may have figured it out. I can't try it for a bit as I have to take my daughter to swim practice.

    1.) Set the height of the control the first time
    2.) Show the menu using SendMessageW. Doing this causes the control to resize.
    3.) set the list index to some value. Then set it to -1
    4.) in the change event have the SendMessageW code to set the height

    I think that may do it.

  15. Jon O

    13 Jul 2017 Pre-Release Testers, Xojo Pro Chicago Area USA
    Edited 2 years ago

    OK. This seems to do the trick:

    Const CB_SHOWDROPDOWN AS Integer = &H14F
    
    Declare Sub SendMessageW Lib "User32" (hwnd As Integer, msg As Integer, wParam As Integer, lParam As Integer)
    
    Call SendMessageW(PopupMenu1.Handle, CB_SHOWDROPDOWN, 1, 0)
    PopupMenu1.ListIndex = 1
    PopupMenu1.ListIndex = -1

    In the change event of the popupmenu:

    Const CB_SETITEMHEIGHT As Integer = &h0153
    Declare Sub SendMessageW Lib "User32" (hwnd As Integer, msg As Integer, wParam As Integer, lParam As Integer)
    Call SendMessageW(me.Handle, CB_SETITEMHEIGHT, -1, 13)

    13 is the height I was looking to use for the control. So that would be whatever height is wanted.

    So showing the dropdown does force the resize. Once that is done, then changing the list index works to reset the size correctly. It isn't enough to call the menu and then do the resize. Seems like you actually have to change the listindex to get it to work right.

  16. Jon O

    13 Jul 2017 Pre-Release Testers, Xojo Pro Chicago Area USA
    Edited 2 years ago

    OK. Further refinements...

    I have this in the Open event for the PopupMenu. It seems to work:

    Sub Open(index as Integer) Handles Open
      
      Me.addrow ""   // Add a blank row for resizing purposes.
      
    // Set the size
      Const CB_SETITEMHEIGHT As Integer = &h0153 
      Declare Sub SendMessageW Lib "User32" (hwnd As Integer, msg As Integer, wParam As Integer, lParam As Integer)
     Call SendMessageW(Me.Handle, CB_SETITEMHEIGHT, -1, 13)
    
    // Show the dropdown - This resets the size.
      Const CB_SHOWDROPDOWN As Integer = &H14F
      Call SendMessageW(me.Handle, CB_SHOWDROPDOWN, 1, 0)
      
    // Now change the listindex to our dummy row.
    // This forces the resize as we have the same declare in the change event 
      me.ListIndex = 1
      me.ListIndex = -1
      
    // Close the menu - Seems like we need to do this in the open event otherwise the menu stays open.
      Call SendMessageW(me.Handle, CB_SHOWDROPDOWN, 0, 0)
    
    // Remove our dummy row
      me.RemoveRow(0)
      
    // Add in whatever rows you want...
      For i As Integer = 0 To 10
        Me.addrow Str(i)
      Next
    
    End Sub

    The only other thing I am thinking of doing is subclassing this and adding a "sized" property. The change event checks to see if the sized property is false. If it is false, then it runs the declare, otherwise it skips it. I don't know which takes more CPU cycles - to just run the declare or to evaluate if you need to run it...

  17. Jon O

    13 Jul 2017 Pre-Release Testers, Xojo Pro Chicago Area USA

    So sorry for the blog, but maybe this will help someone...

    Doing all this works fine. However, when you have a large number of pop-ups to open on a window, it takes quite a bit of time actually. With one or two, you don't notice it. But if you have 15 or 20, it becomes much too long to wait. :(

  18. Andre K

    13 Jul 2017 Pre-Release Testers

    If i see it right, you build and use the same popupmenu again and again, why not build one popupmenu and place in every row a picture of the popupmenu. As soon as someone selects a cell with a picture reposition the popupmenu to that cell and use the selected option + the row of the selected cell. IMHO that should be almost instantaneous.

  19. Jon O

    13 Jul 2017 Pre-Release Testers, Xojo Pro Chicago Area USA

    Yes, they are a control set. But each one is likely set to different list indexes. So it would be a lot of effort to re-paint it all as I would have to set the list index for each instance of the control and then paint that specific item, etc.

    I am probably going to go back to what I had been doing as it appears that it worked good enough. I had set the text size of the listbox to 9 points. Then I set the height to 6. That works - You just don't have very granular control of the listbox. But even setting the height manually, I'm still not getting the height that I want to really use with it that will properly fit where I'm trying to embed it (I have to make my row spacing larger than ideal).

    It would be nice if Xojo just had Windows controls that worked properly.

  20. 2 months ago

    Dave S

    Aug 14 San Diego, California USA

    Is there any update on this..... I am trying to get a 28px tall popupmenu with 18pt text...

  21. Norman P

    Aug 14 Pre-Release Testers, Xojo Pro great-white-software.com/blog

    just tried setting a combobox to 28 pixels tall in VB 6 as well and it doesnt work either
    except as you noted elsewhere by using a different font & font size
    which is a damned hard way to control the size

or Sign Up to reply!