1

我正在尝试使用 VSTGUI 4.0 实现 VST。我的 DAW 使用 WM_KEYDOWN 和 WM_KEYUP 消息来发送基于键盘按下的 MIDI 音符,以便您可以使用键盘演奏 VST。问题是,VSTGUI 在收到 WM_LBUTTONDOWN 消息时会执行此操作:

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;

这会从 DAW 中窃取焦点,并且不允许它处理按键。VSTGUI 需要窗口焦点来处理 WM_MOUSEWHEEL 和 WM_KEYUP/WM_KEYDOWN 事件以调整控件。但是当您在 VST 中调整控件时,您显然希望能够使用键盘弹奏音符以查看它们的声音,因此这两个功能都很重要。

我能想到解决问题的唯一方法是将 SetFocus() 发送到父窗口,使用 SendMessage() 将 WM_KEYUP/WM_KEYDOWN 消息发送回它,然后将 SetFocus() 发送回 VST 窗口:

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

这非常有效,直到您单击 VST 并同时按下一个键,此时会发生未定义的事情(冻结 DAW、使 DAW 崩溃、堆栈溢出等)。

所以很明显我对此采取了错误的方法。我觉得我需要 PostMessage() 并等待回调,然后再将焦点返回到 VST 或类似的东西。即使这听起来有点混乱,那么处理这样的问题的正确方法是什么?

请记住,我无权访问传递消息的 DAW 窗口的代码,因此我无法实现自定义消息或类似的东西。

4

1 回答 1

0

非常感谢 Hans Passant 解决了这个问题!

崩溃问题是由于我的窗口句柄不可靠。我不再将窗口句柄存储在一个变量中,而是使用 GetParent() 在现场得到它。

我也不需要将焦点设置到当前窗口,我需要做的就是用 PostMessage 替换我的 SendMessage。所以新代码:

case WM_KEYDOWN:
    ...code to handle modifiers like shift, ctrl, etc...
    else
    {
        PostMessage(GetParent(win32Frame->getPlatformWindow ()), message, wParam, lParam);
    }
于 2013-07-07T21:10:23.697 回答