Question

I'm trying to implement a VST using VSTGUI 4.0. My DAW uses WM_KEYDOWN and WM_KEYUP messages to send midi notes based on keyboard presses, so that you can play VST's with the keyboard. The problem is, that VSTGUI does this when it receives a WM_LBUTTONDOWN message:

win32Frame->prevFocus = SetFocus (win32Frame->getPlatformWindow ());

CPoint where ((CCoord)((int)(short)LOWORD(lParam)), (CCoord)((int)(short)HIWORD(lParam)));
if (pFrame->platformOnMouseDown (where, buttons) == kMouseEventHandled)
    SetCapture (win32Frame->getPlatformWindow ());
return 0;

This steals focus from the DAW, and doesn't allow it to process key presses. VSTGUI needs the window focus in order to handle WM_MOUSEWHEEL and WM_KEYUP/WM_KEYDOWN events for tweaking controls. But when you're tweaking controls in the VST you obviously want to be able to play notes with the keyboard to see what they sound like, so both functionalities are important.

The only way I could figure to solve the problem was to SetFocus() to the parent window, send WM_KEYUP/WM_KEYDOWN messages back up to it using SendMessage(), then SetFocus() back to the VST window:

case WM_KEYDOWN:
    ...code to handle modifiers like shift, ctrl, etc...
    else
    {
        SetFocus(win32Frame->prevFocus);
        SendMessage(win32Frame->prevFocus, message, wParam, lParam);
        SetFocus(win32Frame->getPlatformWindow ());
    }

This works perfectly, until you click the VST and press a key at the same time, at which point undefined stuff happens (Freezes the DAW, crashes the DAW, stack overflow, etc).

So obviously I'm taking the wrong approach with this. I feel like I need to PostMessage() and wait for a callback before I return focus to the VST or something like that. Even that sounds kinda messed up though, so what exactly is the right way to deal with a problem like this?

Keep in mind I don't have access to the code of the DAW window that's passing the messages down, so I can't implement a custom message or anything like that.

Was it helpful?

Solution

Big thanks to Hans Passant for solving this!

The crash issue was due to my window handle being unreliable. I stopped storing the window handle in a variable, and instead I got it on the spot using GetParent().

I also didn't need to set focus to the current window, all I needed to do was replace my SendMessage with a PostMessage. So the new code:

case WM_KEYDOWN:
    ...code to handle modifiers like shift, ctrl, etc...
    else
    {
        PostMessage(GetParent(win32Frame->getPlatformWindow ()), message, wParam, lParam);
    }
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top