diff options
author | SupSuper | 2018-11-25 17:35:01 +0000 |
---|---|---|
committer | Thierry Crozat | 2018-12-16 10:48:13 +0000 |
commit | 9aef3dd8a7988b94d9e5cae6dae11a9ec6320930 (patch) | |
tree | cf4fd5805d9d454474ccd9a832fd6fa5c276e680 /backends/dialogs | |
parent | 93695a9dcff544707ba1a02321c4a20034effc99 (diff) | |
download | scummvm-rg350-9aef3dd8a7988b94d9e5cae6dae11a9ec6320930.tar.gz scummvm-rg350-9aef3dd8a7988b94d9e5cae6dae11a9ec6320930.tar.bz2 scummvm-rg350-9aef3dd8a7988b94d9e5cae6dae11a9ec6320930.zip |
WIN32: Respect browser_lastpath setting
Diffstat (limited to 'backends/dialogs')
-rw-r--r-- | backends/dialogs/win32/win32-dialogs.cpp | 95 |
1 files changed, 67 insertions, 28 deletions
diff --git a/backends/dialogs/win32/win32-dialogs.cpp b/backends/dialogs/win32/win32-dialogs.cpp index 4c2e908f3c..e34a08c07b 100644 --- a/backends/dialogs/win32/win32-dialogs.cpp +++ b/backends/dialogs/win32/win32-dialogs.cpp @@ -20,8 +20,8 @@ * */ -// We cannot use common/scummsys.h directly as it will include -// windows.h and we need to do it by hand to allow excluded functions + // We cannot use common/scummsys.h directly as it will include + // windows.h and we need to do it by hand to allow excluded functions #if defined(HAVE_CONFIG_H) #include "config.h" #endif @@ -44,21 +44,21 @@ // which is included from all system headers. Thus we abuse that to detect // them. #if defined(__GNUC__) && defined(__MINGW32__) && !defined(__MINGW64_VERSION_MAJOR) - #include "backends/dialogs/win32/mingw-compat.h" +#include "backends/dialogs/win32/mingw-compat.h" #else // We use functionality introduced with Vista in this file. // To assure that including the respective system headers gives us all // required definitions we set Vista as minimum version we target. // See: https://msdn.microsoft.com/en-us/library/windows/desktop/aa383745%28v=vs.85%29.aspx#macros_for_conditional_declarations - #include <sdkddkver.h> - #undef _WIN32_WINNT - #define _WIN32_WINNT _WIN32_WINNT_VISTA - - #define WIN32_LEAN_AND_MEAN - #include <windows.h> - #if defined(ARRAYSIZE) - #undef ARRAYSIZE - #endif +#include <sdkddkver.h> +#undef _WIN32_WINNT +#define _WIN32_WINNT _WIN32_WINNT_VISTA + +#define WIN32_LEAN_AND_MEAN +#include <windows.h> +#if defined(ARRAYSIZE) +#undef ARRAYSIZE +#endif #endif #include <shlobj.h> @@ -82,6 +82,29 @@ Win32DialogManager::~Win32DialogManager() { CoUninitialize(); } +// Wrapper for old Windows versions +HRESULT winCreateItemFromParsingName(PCWSTR pszPath, IBindCtx *pbc, REFIID riid, void **ppv) { + typedef HRESULT(WINAPI *SHFunc)(PCWSTR, IBindCtx *, REFIID, void **); + + SHFunc func = (SHFunc)GetProcAddress(GetModuleHandle(TEXT("shell32.dll")), "SHCreateItemFromParsingName"); + if (func == NULL) + return E_NOTIMPL; + + return func(pszPath, pbc, riid, ppv); +} + +HRESULT getShellPath(IShellItem *item, Common::String &path) { + LPWSTR name = NULL; + HRESULT hr = item->GetDisplayName(SIGDN_FILESYSPATH, &name); + if (SUCCEEDED(hr)) { + char *str = Win32::unicodeToAnsi(name); + path = Common::String(str); + CoTaskMemFree(name); + delete[] str; + } + return hr; +} + Common::DialogManager::DialogResult Win32DialogManager::showFileBrowser(const char *title, Common::FSNode &choice, bool isDirBrowser) { DialogResult result = kDialogError; @@ -91,10 +114,10 @@ Common::DialogManager::DialogResult Win32DialogManager::showFileBrowser(const ch IFileOpenDialog *dialog = NULL; HRESULT hr = CoCreateInstance(CLSID_FileOpenDialog, - NULL, - CLSCTX_INPROC_SERVER, - IID_IFileOpenDialog, - reinterpret_cast<void **> (&(dialog))); + NULL, + CLSCTX_INPROC_SERVER, + IID_IFileOpenDialog, + reinterpret_cast<void **> (&(dialog))); if (SUCCEEDED(hr)) { // If in fullscreen mode, switch to windowed mode @@ -126,30 +149,46 @@ Common::DialogManager::DialogResult Win32DialogManager::showFileBrowser(const ch hr = dialog->SetOkButtonLabel(str); delete[] str; + if (ConfMan.hasKey("browser_lastpath")) { + str = Win32::ansiToUnicode(ConfMan.get("browser_lastpath").c_str()); + IShellItem *item = NULL; + hr = winCreateItemFromParsingName(str, NULL, IID_IShellItem, reinterpret_cast<void **> (&(item))); + if (SUCCEEDED(hr)) { + hr = dialog->SetDefaultFolder(item); + } + delete[] str; + } + // Show dialog hr = dialog->Show(_window->getHwnd()); if (SUCCEEDED(hr)) { - IShellItem *selectedItem = NULL; - LPWSTR path = NULL; - // Get the selection from the user + IShellItem *selectedItem = NULL; hr = dialog->GetResult(&selectedItem); - if (SUCCEEDED(hr)) { - hr = selectedItem->GetDisplayName(SIGDN_FILESYSPATH, &path); - + Common::String path; + hr = getShellPath(selectedItem, path); if (SUCCEEDED(hr)) { - char *str = Win32::unicodeToAnsi(path); - choice = Common::FSNode(str); + choice = Common::FSNode(path); result = kDialogOk; - CoTaskMemFree(path); - delete[] str; } - selectedItem->Release(); } - } else if (hr == HRESULT_FROM_WIN32(ERROR_CANCELLED)) { + + // Save last path + IShellItem *lastFolder = NULL; + hr = dialog->GetFolder(&lastFolder); + if (SUCCEEDED(hr)) { + Common::String path; + hr = getShellPath(lastFolder, path); + if (SUCCEEDED(hr)) { + ConfMan.set("browser_lastpath", path); + } + lastFolder->Release(); + } + } + else if (hr == HRESULT_FROM_WIN32(ERROR_CANCELLED)) { result = kDialogCancel; } |