123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146 |
- /*
- * VSTEditor.cpp
- * -------------
- * Purpose: Implementation of the custom plugin editor window that is used if a plugin provides an own editor GUI.
- * Notes : (currently none)
- * Authors: OpenMPT Devs
- * The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
- */
- #include "stdafx.h"
- #include "resource.h"
- #include "Vstplug.h"
- #include "VSTEditor.h"
- OPENMPT_NAMESPACE_BEGIN
- #ifdef MPT_WITH_VST
- BEGIN_MESSAGE_MAP(COwnerVstEditor, CAbstractVstEditor)
- ON_WM_ERASEBKGND()
- ON_WM_PAINT()
- // Messages from plugin bridge to check whether a key would be handled by OpenMPT
- // We need an offset to WM_USER because the editor window receives some spurious WM_USER messages (from MFC?) when it gets activated
- ON_MESSAGE(WM_USER + 4000 + WM_KEYDOWN - WM_KEYFIRST, &COwnerVstEditor::OnPreTranslateKeyDown)
- ON_MESSAGE(WM_USER + 4000 + WM_KEYUP - WM_KEYFIRST, &COwnerVstEditor::OnPreTranslateKeyUp)
- ON_MESSAGE(WM_USER + 4000 + WM_SYSKEYDOWN - WM_KEYFIRST, &COwnerVstEditor::OnPreTranslateSysKeyDown)
- ON_MESSAGE(WM_USER + 4000 + WM_SYSKEYUP - WM_KEYFIRST, &COwnerVstEditor::OnPreTranslateSysKeyUp)
- END_MESSAGE_MAP()
- void COwnerVstEditor::OnPaint()
- {
- CAbstractVstEditor::OnPaint();
- auto &plugin = static_cast<const CVstPlugin &>(m_VstPlugin);
- if(plugin.isBridged)
- {
- // Force redrawing for the plugin window in the bridged process.
- // Otherwise, bridged plugin GUIs will not always be refreshed properly (e.g. when restoring OpenMPT from minimized state).
- // Synth1 is a good candidate for testing this behaviour.
- CRect rect;
- if(m_plugWindow.GetUpdateRect(&rect, FALSE))
- {
- CWnd *child = m_plugWindow.GetWindow(GW_CHILD | GW_HWNDFIRST);
- if(child)
- child->RedrawWindow(&rect, nullptr, RDW_INVALIDATE | RDW_ALLCHILDREN | RDW_UPDATENOW);
- }
- } else
- {
- // For plugins that change their size without telling the host through audioMasterSizeWindow, e.g. Roland D-50
- CRect rect;
- m_plugWindow.GetClientRect(rect);
- if(rect.Width() != m_width || rect.Height() != m_height)
- {
- SetSize(rect.Width(), rect.Height());
- }
- }
- }
- void COwnerVstEditor::UpdateParamDisplays()
- {
- CAbstractVstEditor::UpdateParamDisplays();
- // We trust that the plugin GUI can update its display with a bit of idle time.
- static_cast<CVstPlugin &>(m_VstPlugin).Dispatch(Vst::effEditIdle, 0, 0, nullptr, 0.0f);
- }
- bool COwnerVstEditor::OpenEditor(CWnd *parent)
- {
- Create(IDD_PLUGINEDITOR, parent);
- // Some plugins (e.g. ProteusVX) need to be planted into another control or else they will break our window proc, making the window unusable.
- m_plugWindow.Create(nullptr, WS_CHILD | WS_VISIBLE, CRect(0, 0, 100, 100), this);
- // Set editor window size
- Vst::ERect rect{};
- Vst::ERect *pRect = nullptr;
- CVstPlugin &vstPlug = static_cast<CVstPlugin &>(m_VstPlugin);
- vstPlug.Dispatch(Vst::effEditGetRect, 0, 0, &pRect, 0);
- if(pRect) rect = *pRect;
- vstPlug.Dispatch(Vst::effEditOpen, 0, 0, m_plugWindow.m_hWnd, 0);
- vstPlug.Dispatch(Vst::effEditGetRect, 0, 0, &pRect, 0);
- if(pRect) rect = *pRect;
- if(rect.right > rect.left && rect.bottom > rect.top)
- {
- // Plugin provided valid window size.
- SetSize(rect.Width(), rect.Height());
- }
- vstPlug.Dispatch(Vst::effEditTop, 0,0, nullptr, 0.0f);
- vstPlug.Dispatch(Vst::effEditIdle, 0,0, nullptr, 0.0f);
- // Set knob mode to linear (2) instead of circular (0) for those plugins that support it (e.g. Steinberg VB-1)
- vstPlug.Dispatch(Vst::effSetEditKnobMode, 0, 2, nullptr, 0.0f);
- return CAbstractVstEditor::OpenEditor(parent);
- }
- void COwnerVstEditor::DoClose()
- {
- // Prevent some plugins from storing a bogus window size (e.g. Electri-Q)
- ShowWindow(SW_HIDE);
- if(m_isMinimized) OnNcLButtonDblClk(HTCAPTION, CPoint(0, 0));
- static_cast<CVstPlugin &>(m_VstPlugin).Dispatch(Vst::effEditClose, 0, 0, nullptr, 0.0f);
- CAbstractVstEditor::DoClose();
- }
- bool COwnerVstEditor::SetSize(int contentWidth, int contentHeight)
- {
- if(contentWidth < 0 || contentHeight < 0 || !m_hWnd)
- {
- return false;
- }
- m_width = contentWidth;
- m_height = contentHeight;
- CRect rcWnd, rcClient;
- // Get border / menu size.
- GetWindowRect(&rcWnd);
- GetClientRect(&rcClient);
- // Narrow plugin GUIs may force the number of menu bar lines (and thus the required window height) to change
- WindowSizeAdjuster adjuster(*this);
- const int windowWidth = rcWnd.Width() - rcClient.Width() + contentWidth;
- const int windowHeight = rcWnd.Height() - rcClient.Height() + contentHeight;
- SetWindowPos(NULL, 0, 0,
- windowWidth, windowHeight,
- SWP_NOZORDER | SWP_NOMOVE | SWP_NOACTIVATE);
- m_plugWindow.SetWindowPos(NULL, 0, 0,
- contentWidth, contentHeight,
- SWP_NOZORDER | SWP_NOMOVE | SWP_NOACTIVATE);
- return true;
- }
- #endif // MPT_WITH_VST
- OPENMPT_NAMESPACE_END
|