No popup event when using shortcuts in context menu

C

Claes Bergefall

Appearantly a ContextMenu doesn't fire its Popup event
when invoking a menu item with a shortcut.

This kind of makes the Popup event useless for enabling
or disabling menu items (if you're using shortcuts)!?

Example:

Suppose you have two menu items in a context menu
and that they have the keyboard shortcuts F2 and F3.

Using the popup event you now enable or disable
the menu items according to some set of rules each time
the menu is shown (as recommended by the documentation).

Let's say that the menu item with shortcut F2 became
disabled. Now, pressing F2 has no effect anymore since it's
disabled. And since the popup event isn't fired we have
no way of telling the system that it should be enabled
again! Only way to enable it again is by physically
showing the context menu.



On a regular menu (MainMenu) this problem doesn't exist
since you always have a visible top menu item (e.g. File or Edit)
that will fire the popup event for you when you press a
shortcut key (unless you have disabled the top menu item)

I would like to enable/disable a menu item when the user
tries to invoke it (or showing the context menu) just like
you do on the main menu.

Any ideas on how to handle this in a context menu?


/claes
 
J

Jeffrey Tan[MSFT]

For this issue I will spend some time on it and reply to you ASAP. Thanks
for your understanding.

Best regards,
Jeffrey Tan
Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security
This posting is provided "as is" with no warranties and confers no rights.
 
J

Jeffrey Tan[MSFT]

Hi claes,

Sorry for letting you wait for so long.

Based on your statement below:
"On a regular menu (MainMenu) this problem doesn't exist since you always
have a visible top menu item (e.g. File or Edit) that will fire the popup
event for you when you press a shortcut key (unless you have disabled the
top menu item)"

I do not think this is a correct behavior. If in a main menu, there are 2
menu items, with short cut keys F2 and F3. Once upon a time, F2 is disabled
because of a certain mainmanu popup. But after this, if we press F2 key in
our application, I think main menu will not pop up, the same behavior as
the context menu. Unless we explicitly invoke this main menu, and letting
the pop up code executes again, this F2 key should not work for main menu.

Anyway, if I mis-understand you, please feel free to tell me, thanks.
====================================================
Thank you for your patience and cooperation. If you have any questions or
concerns, please feel free to post it in the group. I am standing by to be
of assistance.

Best regards,
Jeffrey Tan
Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security
This posting is provided "as is" with no warranties and confers no rights.
 
C

Claes Bergefall

Maybe I explained it wrong
Take a main menu like this:

File
MenuItem 1 F2
MenuItem 2 F3

(The main menu has a top level menu item called "File" and under
that are two menu items called "MenuItem 1" and "MenuItem 2")
If you disable MenuItem 1 and then press F2 the popup event
for File will still fire


Now take a context menu that looks like this:

MenuItem 1 F2
MenuItem 2 F3

(The context menu has two menu items called "MenuItem 1"
and "MenuItem 2")
If you disable MenuItem 1 and then press F2 the popup event
for the context menu will NOT fire. This is the problem.


Take a look at the ShortcutClick method in the MenuItem class:

internal virtual bool ShortcutClick()
{
if (this.menu is MenuItem)
{
MenuItem item1 = (MenuItem) this.menu;
if (!item1.ShortcutClick() || (this.menu != item1))
{
return false;
}
}
if ((this.data.State & 3) != 0)
{
return false;
}
if (this.itemCount > 0)
{
this.OnPopup(EventArgs.Empty);
}
else
{
this.OnClick(EventArgs.Empty);
}
return true;
}

In the case of the main menu I described above the parent of MenuItem 1
is the menu item File. When pressing F2 the ShortcutClick method is invoked
for MenuItem 1. This method sees that MenuItem 1 has a parent that is
a MenuItem (File) and call its ShortcutClick method. Since File is not
disabled
its OnPopup method will be invoked and thus firing the Popup event
So in this case all we need is to handle the popup event for the File menu
item
and we can enable or disable the menu items on that menu without any
problems.

In the case of the context menu I described above the parent of MenuItem 1
is a ContextMenu. As before the ShortcutClick method is invoked for MenuItem
1
when pressing F2. Bu since its parent isn't a MenuItem it jumps directly to
check if the menu item is disabled (the "...this.data.State & 3..."
statement).
Since it is it simply exits without firing the popup event and allowing me
to
enable it.

I think the ShortcutClick method should really look something like this
instead:

internal virtual bool ShortcutClick()
{
if (this.menu is MenuItem)
{
MenuItem item1 = (MenuItem) this.menu;
if (!item1.ShortcutClick() || (this.menu != item1))
{
return false;
}
}
elseif (this.menu is ContextMenu)
{
ContextMenu menu1 = (ContextMenu) this.menu;
menu1.OnPopup(EventArgs.Empty)
}
if ((this.data.State & 3) != 0)
{
return false;
}
if (this.itemCount > 0)
{
this.OnPopup(EventArgs.Empty);
}
else
{
this.OnClick(EventArgs.Empty);
}
return true;
}

I realize that the ContextMenu.OnPopup method is protected so
you can't really call it like this, but you should get the idea anyway

At the moment we have worked around this prblem by using a
IMessageFilter and trapping all WM_KEYDOWN and
WM_SYSKEYDOWN messages. Unfortunately this is
not a very elegant solution so any other ideas are most welcome.

/claes

"Jeffrey Tan[MSFT]" said:
Hi claes,

Sorry for letting you wait for so long.

Based on your statement below:
"On a regular menu (MainMenu) this problem doesn't exist since you always
have a visible top menu item (e.g. File or Edit) that will fire the popup
event for you when you press a shortcut key (unless you have disabled the
top menu item)"

I do not think this is a correct behavior. If in a main menu, there are 2
menu items, with short cut keys F2 and F3. Once upon a time, F2 is disabled
because of a certain mainmanu popup. But after this, if we press F2 key in
our application, I think main menu will not pop up, the same behavior as
the context menu. Unless we explicitly invoke this main menu, and letting
the pop up code executes again, this F2 key should not work for main menu.

Anyway, if I mis-understand you, please feel free to tell me, thanks.
====================================================
Thank you for your patience and cooperation. If you have any questions or
concerns, please feel free to post it in the group. I am standing by to be
of assistance.

Best regards,
Jeffrey Tan
Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security
This posting is provided "as is" with no warranties and confers no rights.
 
J

Jeffrey Tan[MSFT]

Hi Claes,

Thanks very much for your details feedback!!

Yes, I have writen a sample for this and reproduced out your issue. The
mainmenu and contextmenu really function different on short cut key.
Currently, I still can not find a very good workaround for this issue, but
I think your workaround of using IMessageFilter may be a suitable one,
although not very elegant.

Also, IMessageFilter is pre process before the normal translate/dispatch
cycle of the message pump, it will only see posted messages. For the
messages that are all pass to the Windows procedure through SendMessage
method, they will not be placed in the message pump. So the IMessageFilter
can not intercept them.

Hope this information helps.
==================================
Thank you for your patience and cooperation. If you have any questions or
concerns, please feel free to post it in the group. I am standing by to be
of assistance.

Best regards,
Jeffrey Tan
Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security
This posting is provided "as is" with no warranties and confers no rights.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top