aboutsummaryrefslogtreecommitdiff
path: root/backends/dialogs
diff options
context:
space:
mode:
authorSupSuper2018-11-25 17:35:01 +0000
committerThierry Crozat2018-12-16 10:48:13 +0000
commit9aef3dd8a7988b94d9e5cae6dae11a9ec6320930 (patch)
treecf4fd5805d9d454474ccd9a832fd6fa5c276e680 /backends/dialogs
parent93695a9dcff544707ba1a02321c4a20034effc99 (diff)
downloadscummvm-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.cpp95
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;
}