mirror of
https://github.com/Xevion/easy7zip.git
synced 2025-12-06 15:14:59 -06:00
23.01
This commit is contained in:
@@ -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
|
||||
(lpstrInitialDir) : the initial directory.
|
||||
DOCs: the algorithm for selecting the initial directory varies on different platforms:
|
||||
{
|
||||
LPTSTR Buf;
|
||||
unsigned Size;
|
||||
public:
|
||||
CDoubleZeroStringListA(LPSTR buf, unsigned size): Buf(buf), Size(size) {}
|
||||
bool Add(LPCSTR s) throw();
|
||||
void Finish() { *Buf = 0; }
|
||||
};
|
||||
Win2000/XP/Vista:
|
||||
1. If lpstrFile contains a path, that path is the initial directory.
|
||||
2. Otherwise, lpstrInitialDir specifies the initial directory.
|
||||
|
||||
bool CDoubleZeroStringListA::Add(LPCSTR s) throw()
|
||||
{
|
||||
unsigned len = MyStringLen(s) + 1;
|
||||
if (len >= Size)
|
||||
return false;
|
||||
MyStringCopy(Buf, s);
|
||||
Buf += len;
|
||||
Size -= len;
|
||||
return true;
|
||||
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);
|
||||
}
|
||||
|
||||
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;
|
||||
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;
|
||||
}
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user