1

I want to perform some action when the user presses CTRL+S inside a modeless dialog. Accelerators would be perfect for this, except that I don't have control over the thread's message loop (think plugin), so I can't call TranslateAccelerator.

A nested message loop is not an option because the main application does a lot of processing in between calls to PeekMessage.

  • Is there some way I can 'force' the existing message loop to handle my accelerator?
  • Is there any other way besides accelerators to catch CTRL+S?

I thought about using a Window hooks on WH_GETMESSAGE, which gets called before returning from GetMessage or PeekMessage. But I'm not sure what would happen after I successfully called TranslateAcellerator, I can't let the application know I handled it. WH_MSGFILTER would require the app to implement a call to CallMsgFilter, which it doesn't from a quick glance with a debugger.

My last idea was subclassing the control which is what I'm trying to avoid. That would require some mechanism to signal the keypress event to the parent window, which I don't think is a great design. Also, if I add more controls I would have to subclass every single one.

Thanks for any hints.

pezcode
  • 5,490
  • 2
  • 24
  • 37

2 Answers2

2

This is a fairly infamous interop problem, it rears its ugly head also when using Winforms to implement UI in a native program. Microsoft's recommendation is a rough-and-tumble one: start your own thread to display the window so you can pump your own message loop. You'll need SetParent() to avoid Z-order problems. Scary stuff, do consider a modal dialog thrice before committing to this.

Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
  • The bad thing is that the plugin interface is not threadsafe so I would end up deep inside synchronization issues. I've been down that road once and pretty much eliminated it from the get-go, it simply isn't worth it just for a keyboard shortcut. – pezcode Aug 19 '11 at 16:49
  • Good, you thought twice about it. – Hans Passant Aug 19 '11 at 16:59
0

Can you use WM_GETDLGCODE? http://msdn.microsoft.com/en-us/library/ms645425(v=vs.85).aspx

Pete
  • 4,784
  • 26
  • 33
  • As I said, I could subclass the control and then handle WM_CHAR (it returns DLGC_WANTALLKEYS on WM_GETDLGCODE) so that should be possible. But it's not an optimal solution and would require subclassing every other child control if I want the shortcut to work in the whole dialog. – pezcode Aug 19 '11 at 14:40
  • Fair enough. Could you put a detour in getmessage? Little bit nasty though for a plugin to do this... – Pete Aug 19 '11 at 18:28
  • Actually that's just what WH_GETMESSAGE is for. The trouble is that I don't know if it's safe if I handle the incoming message and then the main application still calls TranslateMessage and DispatchMessage. Maybe I should be detouring these two, but then how do I know the APIs were called from the main loop, not some other modal message loop? – pezcode Aug 19 '11 at 18:40