PopupMenu.Change event

On the Mac side, if someone pops up a menu and navigates it with the keyboard, the Change event fires after they hit return or click or otherwise choose a new item.

On the Windows side, the Change event fires for every item the user passes over. So if the menu contains four items and it’s initially on the first, using the down arrow to get to the last will trigger Change three times. This is causing a headache.

Is there a way to determine if the menu is still popped or otherwise behave as it does on the Mac side?

With @Jeremy Cowgar 's help, we found a solution. This function was implemented within a PopupMenu subclass that also handles when to raise the Change event. I’m not posting the whole subclass here, just the relevant function.

Private Function IsPopped() As Boolean
  #if TargetWin32 then
    Declare Function SendMessageA Lib "User32" ( hwnd as Integer, msg as Integer, wParam as Integer, lParam as Integer ) as Integer
    
    const CB_GETDROPPEDSTATE = &h157
    
    return (SendMessageA(me.Handle, CB_GETDROPPEDSTATE, 0, 0) = 1)
    
  #else
    return false
  #endif
  
End Function

What happens if you open it change via arrow keys then shift focus elsewhere (like to an edit field) without pressing return ?

It reverts to its former value without firing Change.

The reason I asked is I’ve seen this in the IDE as well and what you describe as reverting is incorrect platform behaviour
It should change

The part you describe is exactly how the unmodified, stock Xojo PopupMenu works. You change selection (via keys), then press escape or click somewhere else and it returns to it’s previous selection state. That is what we used as the model, the Xojo control is wrong in this regard?

both are correct & I really need to not just quickly scan a thread :stuck_out_tongue:
I’m reading popupmenu & thinking combobox

my mistake

I’ll go back to work now :stuck_out_tongue:

However I might file a bug report about this
A popup when navigated by keyboard should require a return / enter I think before firing a change
And I think we can tell the difference
I know we can for comboboxes

Norman, I’m really interested in knowing if the Xojo PopupMenu behavior of sending a Change notification with each selection change is proper or not? i.e. You click the PopupMenu control, and the list appears. Press the down arrow key once and the Change event fires. You start typing text to move the selection to a new entry, and the change event could fire 50 times. Finally when the user makes the final selection by pressing Enter, the change event does not fire because the selection didn’t actually change with that keypress. It just closed the menu.

It seems like a bug. The Mac side of things works as you’d expect. The Change event fires once, when the menu closes, i.e. the selection is finalized.

[quote=200951:@Norman Palardy]However I might file a bug report about this
A popup when navigated by keyboard should require a return / enter I think before firing a change
And I think we can tell the difference
I know we can for comboboxes[/quote]

Yup, sorry about that. Posted while you were and didn’t see it until after the fact.

Thanks Norman!

On Windows, each time the up or down arrows are punched, it also changes the ListIndex. So effectively, there is a change.

On Mac, moving up and down the dropdown nothing happens.

But it’s left changed when the user “locks in” the choice, or reverted if the user clicks elsewhere or escapes. In the former, Change should only fire once, and the latter, not at all. Until the user makes up their mind, there really hasn’t been a “change”.

Indeed it should work the same under Mac and Windows.

BTW,

<https://xojo.com/issue/17732>

[quote=200982:@Kem Tekinay]BTW,

<https://xojo.com/issue/17732>[/quote]

I just checked, the arrow key change is the same on PopupMenu and ComboBox.

In VB. Net the SelectedValueChanged event fires only when the selection is validated by the closing of the drop down.

In both types of controls? I can see the case for it behaving like that for a ComboBox.

just try the function on my application and it work beautifully on my subclassed Combobox. I always wonder how to find out when the dropdown part is showed.

In VB, ComboBox is both what we know under that name, and what we call PopupMenu depending on its DropDownStyle property.

Another interesting aspect of VB is that there is an event for when the drop down menu is shown or not.