我正在尝试使用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窗口代码,因此我无法实现自定义消息或类似内容。
答案 0 :(得分: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);
}