diff --git a/distrho/src/DistrhoPluginJACK.cpp b/distrho/src/DistrhoPluginJACK.cpp index f9423543..9f85875c 100644 --- a/distrho/src/DistrhoPluginJACK.cpp +++ b/distrho/src/DistrhoPluginJACK.cpp @@ -907,6 +907,36 @@ int main(int argc, char* argv[]) return runSelfTests() ? 0 : 1; #endif +#if defined(DISTRHO_OS_WINDOWS) && DISTRHO_PLUGIN_HAS_UI + /* the code below is based on + * https://www.tillett.info/2013/05/13/how-to-create-a-windows-program-that-works-as-both-as-a-gui-and-console-application/ + */ + bool hasConsole = false; + + HANDLE consoleHandleOut, consoleHandleError; + + if (AttachConsole(ATTACH_PARENT_PROCESS)) + { + // Redirect unbuffered STDOUT to the console + consoleHandleOut = GetStdHandle(STD_OUTPUT_HANDLE); + if (consoleHandleOut != INVALID_HANDLE_VALUE) + { + freopen("CONOUT$", "w", stdout); + setvbuf(stdout, NULL, _IONBF, 0); + } + + // Redirect unbuffered STDERR to the console + consoleHandleError = GetStdHandle(STD_ERROR_HANDLE); + if (consoleHandleError != INVALID_HANDLE_VALUE) + { + freopen("CONOUT$", "w", stderr); + setvbuf(stderr, NULL, _IONBF, 0); + } + + hasConsole = true; + } +#endif + jack_status_t status = jack_status_t(0x0); jack_client_t* client = jackbridge_client_open(DISTRHO_PLUGIN_NAME, JackNoStartServer, &status); @@ -950,9 +980,19 @@ int main(int argc, char* argv[]) d_stderr("Failed to create the JACK client, cannot continue!"); #if defined(DISTRHO_OS_WINDOWS) && DISTRHO_PLUGIN_HAS_UI + // make sure message box is high-dpi aware + if (const HMODULE user32 = LoadLibrary("user32.dll")) + { + typedef BOOL(WINAPI* SPDA)(void); + if (const SPDA SetProcessDPIAware = (SPDA)GetProcAddress(user32, "SetProcessDPIAware")) + SetProcessDPIAware(); + FreeLibrary(user32); + } + const String win32error = "Failed to create JACK client, reason was:\n" + errorString; MessageBoxA(nullptr, win32error.buffer(), "", MB_ICONERROR); #endif + return 1; } @@ -992,6 +1032,34 @@ int main(int argc, char* argv[]) const PluginJack p(client); +#if defined(DISTRHO_OS_WINDOWS) && DISTRHO_PLUGIN_HAS_UI + /* the code below is based on + * https://www.tillett.info/2013/05/13/how-to-create-a-windows-program-that-works-as-both-as-a-gui-and-console-application/ + */ + + // Send "enter" to release application from the console + // This is a hack, but if not used the console doesn't know the application has + // returned. The "enter" key only sent if the console window is in focus. + if (hasConsole && (GetConsoleWindow() == GetForegroundWindow() || SetFocus(GetConsoleWindow()) != nullptr)) + { + INPUT ip; + // Set up a generic keyboard event. + ip.type = INPUT_KEYBOARD; + ip.ki.wScan = 0; // hardware scan code for key + ip.ki.time = 0; + ip.ki.dwExtraInfo = 0; + + // Send the "Enter" key + ip.ki.wVk = 0x0D; // virtual-key code for the "Enter" key + ip.ki.dwFlags = 0; // 0 for key press + SendInput(1, &ip, sizeof(INPUT)); + + // Release the "Enter" key + ip.ki.dwFlags = KEYEVENTF_KEYUP; // KEYEVENTF_KEYUP for key release + SendInput(1, &ip, sizeof(INPUT)); + } +#endif + return 0; #ifndef DPF_RUNTIME_TESTING