@PeterJones said in Handling Ctrl+C in a c++ plugin dialog:
I interpreted as wanting to have a keyboard shortcut specific to an action inside the dialog.
[…]
It would very much surprise me if it weren’t possible for a plugin to do that (though I cannot think of any off the top of my head that do so). But whether “subclassing” or some other strategy is the right way to implement the shortcut capture is beyond me.
(Following based on theory/understanding. I have not actually tried to do this.)
Subclassing the NPP window would be horrific way to go about this (if it would even work at all). Making shortcuts work specifically in a plugin window is a bit of an awkward problem, because (as far as I can tell) there is only one accelerator table for an entire running program — and Notepad++ already “owns” that table.
In a modal dialog or a non-modal window that was registered with NPPM_MODELESSDIALOG it wouldn’t work at all, because messages for those don’t go through TranslateAccelerator. The message would get sent to the window/dialog. This is actually the right way to go, but subclassing the main NPP window would be irrelevant, because the message would never get to that window; it would be dispatched to the plugin window or one of its controls.
For a non-modal window without NPPM_MODELESSDIALOG, the shortcut key would still send whatever menu command was assigned to it. In that case, a subclass procedure could check whether the keyboard focus is in a window belonging to the plugin. If it is, process it; if it isn’t, pass it through normally. But note that you’d be catching the command, not the shortcut. Your command would always take over from the NPP command, regardless of whether it was by menu, by tool button, or by whatever shortcut key the user assigned to the NPP function.
For modeless dialogs that don’t register, NPP now works around this for cut, copy and paste by sending WM_CUT, WM_COPY and WM_PASTE to the window/control with keyboard focus when one of those commands is invoked and focus is not in an NPP-managed window or control. Note that if you change the shortcut for one of those commands, the dialog will respond to the new shortcut. (It will respond to the “normal” shortcut as well if and only if that shortcut isn’t assigned to a Notepad++ command. Scintilla assignments don’t count; that’s why the problem didn’t show up until the shortcuts were moved from Scintilla to Notepad++.)
So to get it right, you have to register the window if it is modeless, and you have to pick up the key combination in your plugin code. How to pick it up is a bit of a pain in the butt, because usually the main window (typically a dialog box) won’t have focus, so the keystrokes will go to whatever control does have focus — unless the dialog manager captures it and applies its own logic (such as it does for the tab key and for Alt+ accelerators).
I still haven’t found a clear and complete description of what the dialog manager does when the message loop calls IsDialogMessage. Part of it is bound up with WM_GETDLGCODE, which is sent to controls — not the dialog procedure — which further complicates things. Subclassing every control which could have focus when you want your key combination to work would probably be necessary. I suspect some key combinations cannot be captured, but I don’t know that for a fact.
It’s messy. Finding another way — like adding a button for your action and then underlining a letter so that Alt+letter will activate it — is likely to be a lot easier and less fragile. (If the action is control-based, rather than independent of which control in your plugin has focus, then of course the way you did it is correct.)