summaryrefslogtreecommitdiffstatshomepage
path: root/3rdparty/lzma/CPP/Windows/CommonDialog.cpp
diff options
context:
space:
mode:
author Vas Crabb <vas@vastheman.com>2023-12-06 07:58:49 +1100
committer Vas Crabb <vas@vastheman.com>2023-12-06 07:58:49 +1100
commit79bef1e23049fdac25f1fefd132e0b6c7d2cc3a1 (patch)
tree643e9313fe86f583c4022c338677cbc12b761df7 /3rdparty/lzma/CPP/Windows/CommonDialog.cpp
parent512ccf0c7c9b4f08e41038b2ed2de220e140385b (diff)
3rdparty/lzma: Updated to version 23.01.
Diffstat (limited to '3rdparty/lzma/CPP/Windows/CommonDialog.cpp')
-rw-r--r--3rdparty/lzma/CPP/Windows/CommonDialog.cpp291
1 files changed, 176 insertions, 115 deletions
diff --git a/3rdparty/lzma/CPP/Windows/CommonDialog.cpp b/3rdparty/lzma/CPP/Windows/CommonDialog.cpp
index eaaecada727..7a92d5f9b65 100644
--- a/3rdparty/lzma/CPP/Windows/CommonDialog.cpp
+++ b/3rdparty/lzma/CPP/Windows/CommonDialog.cpp
@@ -2,7 +2,7 @@
#include "StdAfx.h"
-#include "../Common/MyWindows.h"
+#include "../Common/MyBuffer.h"
#ifdef UNDER_CE
#include <commdlg.h>
@@ -14,6 +14,7 @@
#include "CommonDialog.h"
#include "Defs.h"
+// #include "FileDir.h"
#ifndef _UNICODE
extern bool g_IsNT;
@@ -21,61 +22,46 @@ extern bool g_IsNT;
namespace NWindows {
-#ifndef _UNICODE
+/*
+ GetSaveFileName()
+ GetOpenFileName()
+ OPENFILENAME
-class CDoubleZeroStringListA
-{
- LPTSTR Buf;
- unsigned Size;
-public:
- CDoubleZeroStringListA(LPSTR buf, unsigned size): Buf(buf), Size(size) {}
- bool Add(LPCSTR s) throw();
- void Finish() { *Buf = 0; }
-};
-
-bool CDoubleZeroStringListA::Add(LPCSTR s) throw()
+(lpstrInitialDir) : the initial directory.
+DOCs: the algorithm for selecting the initial directory varies on different platforms:
{
- unsigned len = MyStringLen(s) + 1;
- if (len >= Size)
- return false;
- MyStringCopy(Buf, s);
- Buf += len;
- Size -= len;
- return true;
+ Win2000/XP/Vista:
+ 1. If lpstrFile contains a path, that path is the initial directory.
+ 2. Otherwise, lpstrInitialDir specifies the initial directory.
+
+ Win7:
+ If lpstrInitialDir has the same value as was passed the first time
+ the application used an Open or Save As dialog box, the path
+ most recently selected by the user is used as the initial directory.
}
-#endif
+Win10:
+ in:
+ function supports (lpstrInitialDir) path with super prefix "\\\\?\\"
+ function supports (lpstrInitialDir) path with long path
+ function doesn't support absolute (lpstrFile) path with super prefix "\\\\?\\"
+ function doesn't support absolute (lpstrFile) path with long path
+ out: the path with super prefix "\\\\?\\" will be returned, if selected path is long
-class CDoubleZeroStringListW
-{
- LPWSTR Buf;
- unsigned Size;
-public:
- CDoubleZeroStringListW(LPWSTR buf, unsigned size): Buf(buf), Size(size) {}
- bool Add(LPCWSTR s) throw();
- void Finish() { *Buf = 0; }
-};
-
-bool CDoubleZeroStringListW::Add(LPCWSTR s) throw()
-{
- unsigned len = MyStringLen(s) + 1;
- if (len >= Size)
- return false;
- MyStringCopy(Buf, s);
- Buf += len;
- Size -= len;
- return true;
-}
+WinXP-64 and Win10: if no filters, the system shows all files.
+ but DOCs say: If all three members are zero or NULL,
+ the system does not use any filters and does not
+ show any files in the file list control of the dialog box.
+in Win7+: GetOpenFileName() and GetSaveFileName()
+ do not support pstrCustomFilter feature anymore
+*/
#ifdef UNDER_CE
-#define MY__OFN_PROJECT 0x00400000
-#define MY__OFN_SHOW_ALL 0x01000000
+#define MY_OFN_PROJECT 0x00400000
+#define MY_OFN_SHOW_ALL 0x01000000
#endif
-/* if (lpstrFilter == NULL && nFilterIndex == 0)
- MSDN : "the system doesn't show any files",
- but WinXP-64 shows all files. Why ??? */
/*
structures
@@ -89,16 +75,16 @@ contain additional members:
#endif
If we compile the source code with (_WIN32_WINNT >= 0x0500), some functions
-will not work at NT 4.0, if we use sizeof(OPENFILENAME*).
-So we use size of old version of structure. */
+will not work at NT 4.0, if we use sizeof(OPENFILENAME).
+We try to use reduced structure OPENFILENAME_NT4.
+*/
-#if defined(UNDER_CE) || defined(_WIN64) || (_WIN32_WINNT < 0x0500)
-// || !defined(WINVER)
+// #if defined(_WIN64) || (defined(_WIN32_WINNT) && _WIN32_WINNT >= 0x0500)
+#if defined(__GNUC__) && (__GNUC__ <= 9) || defined(Z7_OLD_WIN_SDK)
#ifndef _UNICODE
- #define my_compatib_OPENFILENAMEA_size sizeof(OPENFILENAMEA)
+ #define my_compatib_OPENFILENAMEA OPENFILENAMEA
#endif
- #define my_compatib_OPENFILENAMEW_size sizeof(OPENFILENAMEW)
-#else
+ #define my_compatib_OPENFILENAMEW OPENFILENAMEW
// MinGW doesn't support some required macros. So we define them here:
#ifndef CDSIZEOF_STRUCT
@@ -117,91 +103,166 @@ So we use size of old version of structure. */
#define my_compatib_OPENFILENAMEA_size OPENFILENAME_SIZE_VERSION_400A
#endif
#define my_compatib_OPENFILENAMEW_size OPENFILENAME_SIZE_VERSION_400W
+#else
+ #ifndef _UNICODE
+ #define my_compatib_OPENFILENAMEA OPENFILENAME_NT4A
+ #define my_compatib_OPENFILENAMEA_size sizeof(my_compatib_OPENFILENAMEA)
+ #endif
+ #define my_compatib_OPENFILENAMEW OPENFILENAME_NT4W
+ #define my_compatib_OPENFILENAMEW_size sizeof(my_compatib_OPENFILENAMEW)
+#endif
+/*
+#elif defined(UNDER_CE) || defined(_WIN64) || (_WIN32_WINNT < 0x0500)
+// || !defined(WINVER)
+ #ifndef _UNICODE
+ #define my_compatib_OPENFILENAMEA OPENFILENAMEA
+ #define my_compatib_OPENFILENAMEA_size sizeof(OPENFILENAMEA)
+ #endif
+ #define my_compatib_OPENFILENAMEW OPENFILENAMEW
+ #define my_compatib_OPENFILENAMEW_size sizeof(OPENFILENAMEW)
+#else
+
#endif
+*/
#ifndef _UNICODE
#define CONV_U_To_A(dest, src, temp) AString temp; if (src) { temp = GetSystemString(src); dest = temp; }
#endif
-bool MyGetOpenFileName(HWND hwnd, LPCWSTR title,
- LPCWSTR initialDir,
- LPCWSTR filePath,
- LPCWSTR filterDescription,
- LPCWSTR filter,
- UString &resPath
- #ifdef UNDER_CE
- , bool openFolder
- #endif
- )
+bool CCommonDialogInfo::CommonDlg_BrowseForFile(LPCWSTR lpstrInitialDir, const UStringVector &filters)
{
- const unsigned kBufSize = MAX_PATH * 2;
- const unsigned kFilterBufSize = MAX_PATH;
- if (!filter)
- filter = L"*.*";
- #ifndef _UNICODE
+ /* GetSaveFileName() and GetOpenFileName() could change current dir,
+ if OFN_NOCHANGEDIR is not used.
+ We can restore current dir manually, if it's required.
+ 22.02: we use OFN_NOCHANGEDIR. So we don't need to restore current dir manually. */
+ // NFile::NDir::CCurrentDirRestorer curDirRestorer;
+
+#ifndef _UNICODE
if (!g_IsNT)
{
- CHAR buf[kBufSize];
- MyStringCopy(buf, (const char *)GetSystemString(filePath));
- // OPENFILENAME_NT4A
- OPENFILENAMEA p;
+ AString tempPath;
+ AStringVector f;
+ unsigned i;
+ for (i = 0; i < filters.Size(); i++)
+ f.Add(GetSystemString(filters[i]));
+ unsigned size = f.Size() + 1;
+ for (i = 0; i < f.Size(); i++)
+ size += f[i].Len();
+ CObjArray<char> filterBuf(size);
+ // memset(filterBuf, 0, size * sizeof(char));
+ {
+ char *dest = filterBuf;
+ for (i = 0; i < f.Size(); i++)
+ {
+ const AString &s = f[i];
+ MyStringCopy(dest, s);
+ dest += s.Len() + 1;
+ }
+ *dest = 0;
+ }
+ my_compatib_OPENFILENAMEA p;
memset(&p, 0, sizeof(p));
p.lStructSize = my_compatib_OPENFILENAMEA_size;
- p.hwndOwner = hwnd;
- CHAR filterBuf[kFilterBufSize];
+ p.hwndOwner = hwndOwner;
+ if (size > 1)
{
- CDoubleZeroStringListA dz(filterBuf, kFilterBufSize);
- dz.Add(GetSystemString(filterDescription ? filterDescription : filter));
- dz.Add(GetSystemString(filter));
- dz.Finish();
p.lpstrFilter = filterBuf;
- p.nFilterIndex = 1;
+ p.nFilterIndex = (DWORD)(FilterIndex + 1);
+ }
+
+ CONV_U_To_A(p.lpstrInitialDir, lpstrInitialDir, initialDir_a)
+ CONV_U_To_A(p.lpstrTitle, lpstrTitle, title_a)
+
+ const AString filePath_a = GetSystemString(FilePath);
+ const unsigned bufSize = MAX_PATH * 8
+ + filePath_a.Len()
+ + initialDir_a.Len();
+ p.nMaxFile = bufSize;
+ p.lpstrFile = tempPath.GetBuf(bufSize);
+ MyStringCopy(p.lpstrFile, filePath_a);
+ p.Flags =
+ OFN_EXPLORER
+ | OFN_HIDEREADONLY
+ | OFN_NOCHANGEDIR;
+ const BOOL b = SaveMode ?
+ ::GetSaveFileNameA((LPOPENFILENAMEA)(void *)&p) :
+ ::GetOpenFileNameA((LPOPENFILENAMEA)(void *)&p);
+ if (!b)
+ return false;
+ {
+ tempPath.ReleaseBuf_CalcLen(bufSize);
+ FilePath = GetUnicodeString(tempPath);
+ FilterIndex = (int)p.nFilterIndex - 1;
+ return true;
}
-
- p.lpstrFile = buf;
- p.nMaxFile = kBufSize;
- CONV_U_To_A(p.lpstrInitialDir, initialDir, initialDirA);
- CONV_U_To_A(p.lpstrTitle, title, titleA);
- p.Flags = OFN_EXPLORER | OFN_HIDEREADONLY;
-
- bool res = BOOLToBool(::GetOpenFileNameA(&p));
- resPath = GetUnicodeString(buf);
- return res;
}
else
- #endif
+#endif
{
- WCHAR buf[kBufSize];
- MyStringCopy(buf, filePath);
- // OPENFILENAME_NT4W
- OPENFILENAMEW p;
+ UString tempPath;
+ unsigned size = filters.Size() + 1;
+ unsigned i;
+ for (i = 0; i < filters.Size(); i++)
+ size += filters[i].Len();
+ CObjArray<wchar_t> filterBuf(size);
+ // memset(filterBuf, 0, size * sizeof(wchar_t));
+ {
+ wchar_t *dest = filterBuf;
+ for (i = 0; i < filters.Size(); i++)
+ {
+ const UString &s = filters[i];
+ MyStringCopy(dest, s);
+ dest += s.Len() + 1;
+ }
+ *dest = 0;
+ // if ((unsigned)(dest + 1 - filterBuf) != size) return false;
+ }
+ my_compatib_OPENFILENAMEW p;
memset(&p, 0, sizeof(p));
p.lStructSize = my_compatib_OPENFILENAMEW_size;
- p.hwndOwner = hwnd;
-
- WCHAR filterBuf[kFilterBufSize];
+ p.hwndOwner = hwndOwner;
+ if (size > 1)
{
- CDoubleZeroStringListW dz(filterBuf, kFilterBufSize);
- dz.Add(filterDescription ? filterDescription : filter);
- dz.Add(filter);
- dz.Finish();
p.lpstrFilter = filterBuf;
- p.nFilterIndex = 1;
+ p.nFilterIndex = (DWORD)(FilterIndex + 1);
}
-
- p.lpstrFile = buf;
- p.nMaxFile = kBufSize;
- p.lpstrInitialDir = initialDir;
- p.lpstrTitle = title;
- p.Flags = OFN_EXPLORER | OFN_HIDEREADONLY
- #ifdef UNDER_CE
- | (openFolder ? (MY__OFN_PROJECT | MY__OFN_SHOW_ALL) : 0)
- #endif
+ unsigned bufSize = MAX_PATH * 8 + FilePath.Len();
+ if (lpstrInitialDir)
+ {
+ p.lpstrInitialDir = lpstrInitialDir;
+ bufSize += MyStringLen(lpstrInitialDir);
+ }
+ p.nMaxFile = bufSize;
+ p.lpstrFile = tempPath.GetBuf(bufSize);
+ MyStringCopy(p.lpstrFile, FilePath);
+ p.lpstrTitle = lpstrTitle;
+ p.Flags =
+ OFN_EXPLORER
+ | OFN_HIDEREADONLY
+ | OFN_NOCHANGEDIR
+ // | OFN_FORCESHOWHIDDEN // Win10 shows hidden items even without this flag
+ // | OFN_PATHMUSTEXIST
+ #ifdef UNDER_CE
+ | (OpenFolderMode ? (MY_OFN_PROJECT | MY_OFN_SHOW_ALL) : 0)
+ #endif
;
-
- bool res = BOOLToBool(::GetOpenFileNameW(&p));
- resPath = buf;
- return res;
+ const BOOL b = SaveMode ?
+ ::GetSaveFileNameW((LPOPENFILENAMEW)(void *)&p) :
+ ::GetOpenFileNameW((LPOPENFILENAMEW)(void *)&p);
+ /* DOCs: lpstrFile :
+ if the buffer is too small, then:
+ - the function returns FALSE
+ - the CommDlgExtendedError() returns FNERR_BUFFERTOOSMALL
+ - the first two bytes of the lpstrFile buffer contain the
+ required size, in bytes or characters. */
+ if (!b)
+ return false;
+ {
+ tempPath.ReleaseBuf_CalcLen(bufSize);
+ FilePath = tempPath;
+ FilterIndex = (int)p.nFilterIndex - 1;
+ return true;
+ }
}
}