From a7706f24a3f76c56a44eafe16ccd0618c07ce831 Mon Sep 17 00:00:00 2001 From: JP Cimalando Date: Sat, 20 Jul 2019 09:44:14 +0200 Subject: [PATCH] Add simple file selection for Windows (#152) * Add simple file selection for Windows * Fake async for Windows file dialogs --- Makefile.base.mk | 2 +- dgl/src/Window.cpp | 56 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+), 1 deletion(-) diff --git a/Makefile.base.mk b/Makefile.base.mk index ea4d0547..6c7d17aa 100644 --- a/Makefile.base.mk +++ b/Makefile.base.mk @@ -213,7 +213,7 @@ DGL_SYSTEM_LIBS += -framework Cocoa endif ifeq ($(WINDOWS),true) -DGL_SYSTEM_LIBS += -lgdi32 +DGL_SYSTEM_LIBS += -lgdi32 -lcomdlg32 endif ifneq ($(HAIKU_OR_MACOS_OR_WINDOWS),true) diff --git a/dgl/src/Window.cpp b/dgl/src/Window.cpp index 0eec7972..b5dc1715 100644 --- a/dgl/src/Window.cpp +++ b/dgl/src/Window.cpp @@ -777,6 +777,14 @@ struct Window::PrivateData { } #endif +#if defined(DISTRHO_OS_WINDOWS) && !defined(DGL_FILE_BROWSER_DISABLED) + if (fSelectedFile.isNotEmpty()) + { + fView->fileSelectedFunc(fView, fSelectedFile.buffer()); + fSelectedFile.clear(); + } +#endif + if (fModal.enabled && fModal.parent != nullptr) fModal.parent->idle(); } @@ -1098,6 +1106,9 @@ struct Window::PrivateData { #if defined(DISTRHO_OS_WINDOWS) HWND hwnd; HWND hwndParent; +# ifndef DGL_FILE_BROWSER_DISABLED + String fSelectedFile; +# endif #elif defined(DISTRHO_OS_MAC) bool fNeedsIdle; NSView* mView; @@ -1281,6 +1292,51 @@ bool Window::openFileBrowser(const FileBrowserOptions& options) // show return (x_fib_show(pData->xDisplay, pData->xWindow, /*options.width*/0, /*options.height*/0) == 0); +# elif defined(DISTRHO_OS_WINDOWS) + // the old and compatible dialog API + OPENFILENAMEW ofn; + memset(&ofn, 0, sizeof(ofn)); + + ofn.lStructSize = sizeof(ofn); + ofn.hwndOwner = pData->hwnd; + + // set initial directory in UTF-16 coding + std::vector startDirW; + if (options.startDir) + { + startDirW.resize(strlen(options.startDir) + 1); + if (MultiByteToWideChar(CP_UTF8, 0, options.startDir, -1, startDirW.data(), startDirW.size())) + ofn.lpstrInitialDir = startDirW.data(); + } + + // set title in UTF-16 coding + std::vector titleW; + if (options.title) + { + titleW.resize(strlen(options.title) + 1); + if (MultiByteToWideChar(CP_UTF8, 0, options.title, -1, titleW.data(), titleW.size())) + ofn.lpstrTitle = titleW.data(); + } + + // prepare a buffer to receive the result + std::vector fileNameW(32768); // the Unicode maximum + ofn.lpstrFile = fileNameW.data(); + ofn.nMaxFile = (DWORD)fileNameW.size(); + + // TODO synchronous only, can't do better with WinAPI native dialogs. + // threading might work, if someone is motivated to risk it. + if (GetOpenFileNameW(&ofn)) + { + // back to UTF-8 + std::vector fileNameA(4 * 32768); + if (WideCharToMultiByte(CP_UTF8, 0, fileNameW.data(), -1, fileNameA.data(), (int)fileNameA.size(), nullptr, nullptr)) + { + // handle it during the next idle cycle (fake async) + pData->fSelectedFile = fileNameA.data(); + } + } + + return true; # else // not implemented return false;