2013-07-06 2 views
0

Я пытаюсь реализовать VST с помощью VSTGUI 4.0. Мой DAW использует сообщения WM_KEYDOWN и WM_KEYUP для отправки MIDI-нот на основе нажатия клавиш, так что вы можете играть в VST с помощью клавиатуры. Проблема заключается в том, что VSTGUI делает это, когда он получает сообщение WM_LBUTTONDOWN:SetFocus в родительское окно, затем обратно в дочернее окно

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() родительского окна, отправить WM_KEYUP/WM_KEYDOWN сообщения обратно к нему с помощью SendMessage(), затем 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

Мне нужно дать фокус ввода DAW, чтобы он мог отправлять события заметок с клавиатуры, чтобы играть в VST. Это действительно странно, мне нужно, чтобы DAW и VST одновременно фокусировались на клавиатуре. Даже если бы я мог просто направить фокус на колесико мыши VST, этого было бы достаточно, но, похоже, сосредоточенность на клавиатуре и мышлении одна и та же. Я не могу писать код для ручного воспроизведения MIDI-заметок в VST, потому что есть такие специфичные для DAW вещи, как октава, которую мне нужно учитывать. О, и да, код абсолютно ужасный, ха-ха, VST SDK и VSTGUI - это, наверное, худшие кодовые базы, с которыми мне приходилось работать. – superjoebob

+0

Похоже, что вы путаете фокус ввода и захватываете мышь. Первый фрагмент кода захватывает мышь, что является нарушением клавишных ускорителей и мнемоники. Это схожая, но отличная проблема от фокуса ввода. Хотя мне приходит в голову, что если проблема заключается в получении нефокусированного окна для получения сообщений прокрутки, вы можете просто обрабатывать их на сфокусированном окне и пересылать их в неконфокационное окно. В окне фактически нет необходимости иметь фокус ввода для прокрутки, ему просто нужен фокус, чтобы получать сообщения без специального вмешательства. –

ответ

0

Большое спасибо Hans Passant за это решение!

Проблема с крахом была из-за того, что моя ручка окна была ненадежной. Я перестал хранить дескриптор окна в переменной, и вместо этого я получил его на месте с помощью GetParent().

Мне также не нужно было устанавливать фокус на текущее окно, все, что мне нужно было сделать, это заменить мой SendMessage на PostMessage. Таким образом, новый код:

case WM_KEYDOWN: 
    ...code to handle modifiers like shift, ctrl, etc... 
    else 
    { 
     PostMessage(GetParent(win32Frame->getPlatformWindow()), message, wParam, lParam); 
    } 
Смежные вопросы