Link to home
Start Free TrialLog in
Avatar of npaun
npaun

asked on

How to programmatically Close/Hide a Popup menu?

How to programmatically close/hide a popup menu, in VB6?
For instance, when a menu is shown with PopupMenu mnuFloat, it closes when a user clicks on the menus or somewhere outside the menus. However, how to close it without the need for user to click on the menus or somewhere outside the menus, i.e. completely programmatically?

REMARK: Calling SetForegroundWindow MenuParentForm.hWnd, where the MenyParentForm is the form on which the menu resides, although would work, from certain reasons in my project, is not a best solution, and I need an alternative way to close the menu, using API presumably…

PS: just to mention, an approach such as mnuFloat.Visible=False, mnuFloatSubmenu1.Visible=False etc., does not work…
Avatar of Martin Liss
Martin Liss
Flag of United States of America image

I don't think it's possible. This is from Microsoft:

When you display a pop-up menu, the code following the call to the PopupMenu method isn't executed until the user either chooses a command from the menu (in which case the code for that command's Click event is executed before the code following the PopupMenu statement) or cancels the menu. In addition, only one pop-up menu can be displayed at a time; therefore, calls to this method are ignored if a pop-up menu is already displayed or if a pull-down menu is open.
Avatar of npaun
npaun

ASKER

Thank you for the comment.
That is partially true: for example, if you have a timer on a form where the menu resides, while the popup menu is shown, the code inside of the timer is not executed...

However, tests show that if you have a mouse hook in a public module, IT DOES work normally even while the menu is show, so it can catch for instance a mouse down event, which can trigger hiding of the menu, which I succeeded by using SetForegroundWindow MenuParentForm.hWnd. However, as I mentioned, that particular trick for closing a menu is not quite god for my current needs, so I would need an alternative, for Instance by calling an appropriate API for a menu with a known menu handle, or sending a message, or something like that....
What about using SendKeys("{ESC}") to close the popup?
What about using SendKeys("{ESC}") to close the popup
The popup is modal so the code after it doesn't run until the menu is closed.
The popup is modal so the code after it doesn't run until the menu is closed.
Of course you don't want to close the menu in the code after it. What would be the point of opening it in the first place?
You would call SendKeys from somewhere else.
Avatar of npaun

ASKER

huh, well yes, but that might interfere with other application(s), and it is inelegant, not to mention that SendKeys is broken on Win7... I'm hopping to find a way to properly close a menu, there has be an API way to do it...
I tried the SendKeys solution on a Win7 and it worked.
But you're right. SendKeys would send the "escape" key to whatever window has the focus at the moment.

You could use the SendMessage function to send that keystroke to your window.
Declaration of the function and some constants:
Private const WM_KEYDOWN = &H100
Private const VK_ESCAPE = &H1B
Private Declare Function SendMessage Lib "user32" Alias _
 "SendMessageW"(ByVal hwnd As Long, ByVal wMsg As Long, _
 ByVal wParam As Long, lParam As Any) As Long

Open in new window

Using it to send Escape key to this Form (even if it doesn't have focus):
SendMessage(Me.Hwnd, WM_KEYDOWN, VK_ESCAPE, 0)

Open in new window

Avatar of npaun

ASKER

There are reported some problems with VB6 SendKeys on Win7: https://www.google.com/search?num=100&site=&source=hp&q=sendkeys+windows+7+vb6
There are workarounds, but it is better to be avoided. Doesn't matter...
Tried with SendMessage as you suggested, but it doesn't seem to work for me... it might be due to the fact that the menu's parent form is "hidden" (Visible=False, ShowInTaskbar=False), just as menu container for menus to be show, I don't know...
ASKER CERTIFIED SOLUTION
Avatar of louisfr
louisfr

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of npaun

ASKER

ok, it works, Thanks!
One more thing I would need for this to be applied, if possible for this thread: how to know is the popup menu is currently displayed on the screen, supposedly based on some API call using the known hMenu handle?

(of course, it this could be partially done by directly setting an internal flag gMenuDisplayed =True when calling the PopupMenu, and then gMenuDisplayed=False inside the mnuMyPopupMenu_Click, but it is not a complete solution, as in principle the popup menu can disappear either by user clicking the menu or clicking outside of it. I would need a more direct information for that,  for instance as a reading from the menu structure itself...)
Set a flag before you call Popup, and unset the flag after the call.
As stated several times above, the instruction after the call will only be reached after the menu is closed.
Avatar of npaun

ASKER

yes, you are of course right, setting flag to false inside mnuMyPopupMenu_Click would be wrong, the code is halted and resumed when the menu is closed regardless of the way it is closed, by directly clicking on it, shifting focus to another window/app or clicking outside the menu... I jumped ahead and skipped to utilize that...

Thank you very much for the help.