Problems with WPF PushMenuMode & Win32 interop

Ribbon for WPF Forum

Posted 10 years ago by Phil Devaney
Version: 13.2.0590
Platform: .NET 4.5
Environment: Windows 7 (64-bit)
Avatar

Our application uses a ribbon & docking/MDI with floating document windows, so I have followed the advice from https://devblogs.microsoft.com/visualstudio/wpf-in-visual-studio-2010-part-3-focus-and-activation/ to prevent the ribbon taking focus away from the floating window. I have added the lines to set DefaultAcquireHwndFocusInMenuMode/DefaultRestoreFocusMode in the app's static ctor, and modified our commands to use CompositeCommand/IActiveAware from Prism to route to the right document.

This all works great when the document contains WPF content, but our application has a lot of legacy MFC/Win32 components that are interoped in. I discovered a problem were after clicking on a ribbon button all keyboard input to Win32 controls would stop working. I eventually tracked this down to a InputManager.PushMenuMode call that was missing a corresponding PopMenuMode call, leaving menu mode enabled which causes HwndSource to eat all WM_KEY messages before dispatching them.

It seems that when focus moves from WPF to Win32, the WPF element will recieve a LostKeyboardFocus event without a corresponding PreviewLostKeyboardFocus. As the ribbon calls PopMenuMode in the Preview event, this gets missed. The guidance from MS on when to call PopMenuMode isn't clear - the blog I linked mentions LostKeyboardFocus in the text, but the example code uses PreviewLostKeyboardFocus with an event handler name that suggests the non-Preview event. I've done some experiments with a standard WPF toolbar instead of a ribbon using LostKeyboardFocus and this appears to fix the problem, and I can't see any obvious other problem from using this event.

Would it be possible to get this changed? Maybe it would be OK to call PopMenuMode from both events, only doing so from LostKeyboardFocus if the Preview event is not seen first.

I have also found a couple of less important problems in this area

- When WPF keyboard focus is in a WPF control such as a TextBox, accessing the ribbon using the keyboard (e.g. Alt, H, V to select Paste) sets focus back to the main window instead of the TextBox, meaning the command is sent to the wrong control

- When a floating DocumentWindow is the active window, it is not possible to access the ribbon using the keyboard (Alt key does nothing)

[Modified 10 months ago]

Comments (1)

Posted 10 years ago by Actipro Software Support - Cleveland, OH, USA
Avatar

Hi Phil,

Thanks for sending the sample over.

I believe we already fixed the first issue (displayed in your sample) for the upcoming maintenance release. In our latest code, while pressing Paste will still move focus out of the WinForms control, clicking in the other WinForms control will work and typing works again there.

For the second problem, if I focus the WPF TextBox, do Alt, then H, then V, I see a paste in it. Try doing that first on app startup instead of putting focus in the WinForms controls and clicking ribbon buttons first. My guess is that perhaps the fix we did for the first issue from before is helping with the issue here.  With our current dev codebase, I can do Alt, then H, then V even after having interacted with the ribbon while the WinForms controls had focus.

For the third issue, that is correct.  Alt will not access the ribbon since a rafted document window is on a separate Window and key input in WPF only sticks within the currently-active Window.  Our ribbon key tip service code watches the PreviewKeyDown/PreviewKeyUp events of the ribbon's containing Window.  If you inherit DockSite, and override CreateRaftingWindow, then call the base method, you might be able to attach to those events on the RaftingWindow that is created.  Then find a way to propagate them over to your main window and raise them there so ribbon can see them.  That might get key tips working there.


Actipro Software Support

The latest build of this product (v24.1.1) was released 2 months ago, which was after the last post in this thread.

Add Comment

Please log in to a validated account to post comments.