将SetFocus设置为父窗口,然后返回子窗口

时间:2013-07-06 08:35:34

标签: c++ windows vst

我正在尝试使用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窗口代码,因此我无法实现自定义消息或类似内容。

1 个答案:

答案 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);
    }