WM_KEYDOWN

DSP, Plugin and Host development discussion.
Post Reply New Topic
RELATED
PRODUCTS

Post

I have nearly finished my first VST effect and GUI. One problem though. I create and display an "EDIT" control for text-entry, but it does not receive any WM_KEYDOWN messages. Obviously Cubase is intercepting all key presses. However, I know it must be possible to get these messages as CTextEdit handles WM_KEYDOWN in the VSTGUI API. Any ideas?

Thanks for reading.

Post

take a look at the source code for the VST GUI to see how they did it.

there is a function in vstcontrols.cpp:
LONG WINAPI WindowProcEdit (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)

this handles WM_KEYDOWN messages and dispatches them to CTextEdit.
It looks like some of the other messages are related and important in getting this working.

Post

Thanks for the prompt reply.

I have looked through the code and cannot see anything obvious that I haven't done. I have already copied the WM_GETDLGCODE handler, thinking that that must be the solution, but that made no difference.

I know that Cubase is intercepting all the keys as they are still controlling the transport etc. I know that I have the opportunity to handle them through onKeyDown and onKeyUp in AEffEditor, but I don't fancy having to convert the codes back into a format suitable for WM_KEY... messages to send to the "EDIT" control. And besides, it's clearly possible to get the messages directly... somehow.

Post

I think the problem is
that the host "owns" the editor window so any message
to it can´t be intercepted.

You´ll have to create a window in the window and
then do the same thing with that one and it should work....

If you get it to work then tell me because I haven´t
tried this but I would really like keyboard support
in my plugs (all win32 based editors).

//Daniel :)

Post

gyeadon wrote: I know that I have the opportunity to handle them through onKeyDown and onKeyUp in AEffEditor, but I don't fancy having to convert the codes back into a format suitable for WM_KEY... messages to send to the "EDIT" control.
No you haven't onKeyDown and onKeyUp are just callbacks for the messages your frame receives. Therefore, since Cubase intercepts certain key events, even they won't be called.

My suggestion would be to re-check if you did everything the CTextEdit control does, maybe you have forgotten something. (CTextEdit can't do magic, right?)

Another approach would be installing a "hook" for keyboard events. But that's a rather dirty method, I figure. See "SetWindowsHookEx" Win32 API function.

Best,
Stefan
http://www.stefan-kuhn.net
Home of Vivaldi MX and Ganymed

Post

ddummer wrote: You´ll have to create a window in the window and
then do the same thing with that one and it should work....
Unfortunately no. When you create a window in the window (which Jewel does) you still get no KBD, because in Windoze, the main (app) window gets keyboard events *first*, before unprocessed key events get dispatched down to child windows. :-(

Best,
Stefan
http://www.stefan-kuhn.net
Home of Vivaldi MX and Ganymed

Post

Thanks Daniel. I agree. I would assume that all the WM_KEY... messages are translated in Cubase's message pump and therefore can't get to my window. However, the fact the the VSTGUI handles WM_KEYDOWN makes me think otherwise.

(ps England should have beaten France)

Post

You could try to respond "0" to effKeysRequired and get your keys from effEditKey, but I assume that you need strange keycodes and that's why you're asking this question =)

CTextEdit gets keyboard input by taking the focus. Look at the CTextEdit::takeFocus to look at the complication involved =)

When you get the key commands, remember to pass along things you don't need to your parent window's message handler, otherwise you're going to break your host when you take focus. (check out how CTextEdit does this in Windows, it doesn't return from case WM_KEYDOWN)

Post

I have looked through takeFocus and can't see anything that I'm not doing. Also, the text input works in VSTHost (available here somewhere) so I know the basic processing is sound - I just don't know how to get the WM_KEY... messages. I will try playing with the effKeysRequired thing out of desparation.

Post

Ok, a slightly different question: Has anybody implemented textual input in their editor? If so, how?

Post

I'm just talking to myself now, but I suppose this may be useful to someone one day.

It turns out that I do get WM_KEY... messages when Cubase doesn't want them, but as Cubase maps nearly everything that's not too useful. My new focus of attention is on this WM_GETDLGCODE message, which I'm not getting. I believe it has something to do with the fact that I sub-class the edit control....

Post

gyeadon wrote:I'm just talking to myself now, but I suppose this may be useful to someone one day.

It turns out that I do get WM_KEY... messages when Cubase doesn't want them, but as Cubase maps nearly everything that's not too useful. My new focus of attention is on this WM_GETDLGCODE message, which I'm not getting. I believe it has something to do with the fact that I sub-class the edit control....
Well like I said earlier, Cubase's main window gets and processes all key events it wants *first*. Even if you create another stack of ten nested child windows, you still won't get the key events Cubase has already taken out of the message queue.

VSTGUI creates an EDIT control using CreateWindow() in takeFocus. Do you do the same? Or do you try to create another type of control / window?
I'm asking because it might be that the EDIT control installs a keyboard hook upon creation to be able to intercept all key events before the main window gets them.

I'm very interested in this, because my Jewel framework needs full keyboard input, too. I haven't had time to try yet, but figured I would do it like in the VSTGUI CTextEdit. If that doesn't work (as it seems) then I'll go for the SetWindowsHookEx() approach... ;)
http://www.stefan-kuhn.net
Home of Vivaldi MX and Ganymed

Post

Another idea:

(Though I almost don't dare to mention...)

You *could* search for the Apps main window and replace the window's windowProc by calling SetWindowLong() with your own one. Then you'd intercept all you WM_KEY* messages you need and otherwise call the original proc.

Dirty, but should work.

Plus, you only need to do it, while your edit control is active.

(I didn't write this.) :oops:
http://www.stefan-kuhn.net
Home of Vivaldi MX and Ganymed

Post

Well, I have fixed it. My advice to anyone with the same problem would be to copy from VSTGUI CTextEdit. I will go on to explain why my original version didn't work; I don't expect you to read on.

Basically, I was sub-classing the edit control as follows: I first obtained a reference to the "EDIT" window proc using GetClassInfoEx. I then had my own window class and window proc that essentially forwarded everything to the "EDIT" window proc with CallWindowProc.

The solution was to create the window using the "EDIT" window class and *then* replace the window proc using SetWindowLong. If anyone can tell me why this should work differently (when I can guarantee that I forwarded *all* messages to the "EDIT" window proc), I would be very interested to know. My first thought is that CreateWindow may behave differently for common control window classes?

Anyway, I suspect that the EDIT control does install a keyboard hook, as stefankuhn wisely suggested, and somehow I was preventing it from doing so. Er, the end.

Post Reply

Return to “DSP and Plugin Development”