If a VST plugin has an editor, it should process the keys via
onKeyDown (VstKeyCode& keyCode)
and
onKeyUp (VstKeyCode& keyCode)
now VstKeyCode is something very specific, you’ll have to look at the steinberg header files.
a plugin editor should NOT receive WM_KEYDOWN messages and react to them.
some hosts eat up WM_KEYDOWN messages and do not transfer them at all to the VST plugin editor, but translate them into VstKeyCode and send them via those 2 functions - other hosts don’t do that.
Right, using my VSTi in Sonar 6… I get WM_KEYDOWN events in juce for the del key, the number keys, the cursor up/down keys… and for jrwyCDEGIJLKMPQRTWYZ (!) but not for the other alphabetic characters (!!) including abcdefghiklmn etc. and not the tab keys…!!!
This crazy behaviour only happens in Sonar 6… not Cubase.
The only solution I guess is some sort of keyboard hook in Juce, or a bugfix in Sonar, unless somebody tells me otherwise…?!
Haven’t look at this for a while but I remember once adding this to the juce windowproc:
switch (message)
{
case WM_GETDLGCODE:
return DLGC_WANTALLKEYS
(that is in juce\build\win32\platform_specific_code\juce_win32_Messaging.cpp )
It seemed to cure my problem then, but not sure if it is exactly the same problem as yours. At the time it was cursur up/down that seemed to not get through to the plugin, if I remember well
no, got stuck and decided to postpone it to a future version of my plugs. Also because there’s a fundamental problem too with Ableton Live wrt keystroke handling and needed a universal solution that fixes it once and for all for any host
one avenue suggested here by Jules was to create a separate popup window just-in-time every time you need to enter keystrokes in a control
I wonder if this could be done also for the entire editor window of the plugin : creating a single window that displays on top of the host-provided one. Apparently it all boils down to having your own window where the host does not interfere with the window proc.
btw, juce AlertWindows triggered from a plugin seem to capture keystrokes just fine. At least with Live - couldn’t test with Sonar, since my trial version expired.
but that’s probably little solace I guess. I agree that it’s maddening, this random host behaviour where it comes to keystroke handling
My DocumentWindow when it has the focus doesn’t get e.g. the tab key WM_KEYDOWN events… but if I pop-up a juce AlertWindow from the DocumentWindow, the AlertWindow gets the tab key as WM_KEYDOWN events!
Can somebody (Jules) explain that to me? It sounds like there might be a solution in there somewhere!
case WM_KEYDOWN:
// Hack!
lLastKeyDown = wParam;
case WM_SYSKEYDOWN:
if (doKeyDown (wParam))
return 0;
break;
case WM_KEYUP:
// Hack!
if (lLastKeyDown != wParam)
{
doKeyDown (wParam);
doKeyChar ((int) wParam, lParam);
}
case WM_SYSKEYUP:
if (doKeyUp (wParam))
return 0;
break;
This works based on the observation that Sonar consumes/absorbs the WM_KEYDOWN and WM_CHAR events for certain characters (see previous post!) but still allows-through the WM_KEYUP events.
The problem with this hack is:
it is a hack!
the lower-case chars it passes through are treated as upper-case, not the right case
the char events that are absorbed by Sonar are still used by the Sonar host, which isn’t what I want!
Anybody (Jules?) got any better ideas, or anything inspired by the way that AlertWindow works?
Right, I can see that when an alert dialog is running, and we’ve entered a modal loop, Jules’ code sits in a tight loop calling into here… (juce_win32_Messaging.cpp)
I’ve even gone so far as using WH_KEYBOARD to install a keyboard hook; and the bottom line appears that I can’t find a work-around to this. I’ve raised a bug with Sonar 6 at Cakewalk, the guts of which are as follows, and would encourage any others who have this problem to do the same; it might even get fixed one day.
… and I’ve put in place the above hack so at least some sort of sensible keyboard behaviour is possible in the plug-in (even though Sonar also absorbs these events… bah!).
Yeah, I tried a keyboard hook. I got the hook running… and got the events, but couldn’t quite figure-out exactly:
when to install/remove the hook (should be when the plug-in Window gets the keyboard focus - can’t just leave it dangling there when we don’t want it e.g. when plug-in hidden, or Sonar would lose events too!)
why my key event translation wasn’t working (e.g. always getting ‘A’ rather than ‘a’, even after calling the appopriate win32 translation function).
A better solution (if this is even feasible?) would somehow be to force my DocumentWindow to be owned by an HWND that Sonar doesn’t get the events for. I don’t know if this is even possible, as I don’t know what the scope of the Sonar bug is … e.g. HWND or Thread.
Of course ideally, Cakewalk would fix this bug pronto…! Can’t believe there aren’t more people to have encounted this problem, or are just many VSTis very light on any keyboard interaction?
I have (only!) just noticed that in Sonar 6, the VSTi host window includes a new button on the top right of its toolbar, which says on the tooltip “Give all keystrokes to Plug-in”. However, enabling this seems to make no difference at all to the plug-in behaviour… :-/
wow, Pete, you’ve been quite busy! Thanks for sharing your insights, really appreciate it.
If you’re interested I have some old code lying around where I tweaked juce_win32_messaging.cpp such that my own message hook would get access BEFORE the host message handler. What I did was to detect the presence of a host (i.e. Sonar’s or Live’s) hook and then sort of wrap it with my own, reading my own the messages first and only then passing the remainder to the host one. Beware though : this certainly also qualifies as a dirty hack!
This seemed to work okay at first (both with Live & Sonar6 I believe) , but I abandoned it later because it apparently messed with midi timing in Live. However, did not investigate that timing problem further so maybe that’s fixable when further scrutinized.
If you’d like to try that old code and don’t mind doing a manual merge with the latest juce tree, pm me with your mail address and I’ll mail it to you.