1 // Windows/CommonDialog.cpp
2
3 #include "StdAfx.h"
4
5 #include "../Common/MyWindows.h"
6
7 #ifdef UNDER_CE
8 #include <commdlg.h>
9 #endif
10
11 #ifndef _UNICODE
12 #include "../Common/StringConvert.h"
13 #endif
14
15 #include "CommonDialog.h"
16 #include "Defs.h"
17
18 #ifndef _UNICODE
19 extern bool g_IsNT;
20 #endif
21
22 namespace NWindows {
23
24 #ifndef _UNICODE
25
26 class CDoubleZeroStringListA
27 {
28 LPTSTR Buf;
29 unsigned Size;
30 public:
CDoubleZeroStringListA(LPSTR buf,unsigned size)31 CDoubleZeroStringListA(LPSTR buf, unsigned size): Buf(buf), Size(size) {}
32 bool Add(LPCSTR s) throw();
Finish()33 void Finish() { *Buf = 0; }
34 };
35
Add(LPCSTR s)36 bool CDoubleZeroStringListA::Add(LPCSTR s) throw()
37 {
38 unsigned len = MyStringLen(s) + 1;
39 if (len >= Size)
40 return false;
41 MyStringCopy(Buf, s);
42 Buf += len;
43 Size -= len;
44 return true;
45 }
46
47 #endif
48
49 class CDoubleZeroStringListW
50 {
51 LPWSTR Buf;
52 unsigned Size;
53 public:
CDoubleZeroStringListW(LPWSTR buf,unsigned size)54 CDoubleZeroStringListW(LPWSTR buf, unsigned size): Buf(buf), Size(size) {}
55 bool Add(LPCWSTR s) throw();
Finish()56 void Finish() { *Buf = 0; }
57 };
58
Add(LPCWSTR s)59 bool CDoubleZeroStringListW::Add(LPCWSTR s) throw()
60 {
61 unsigned len = MyStringLen(s) + 1;
62 if (len >= Size)
63 return false;
64 MyStringCopy(Buf, s);
65 Buf += len;
66 Size -= len;
67 return true;
68 }
69
70 #define MY__OFN_PROJECT 0x00400000
71 #define MY__OFN_SHOW_ALL 0x01000000
72
73 /* if (lpstrFilter == NULL && nFilterIndex == 0)
74 MSDN : "the system doesn't show any files",
75 but WinXP-64 shows all files. Why ??? */
76
77 /*
78 structures
79 OPENFILENAMEW
80 OPENFILENAMEA
81 contain additional members:
82 #if (_WIN32_WINNT >= 0x0500)
83 void *pvReserved;
84 DWORD dwReserved;
85 DWORD FlagsEx;
86 #endif
87
88 If we compile the source code with (_WIN32_WINNT >= 0x0500), some functions
89 will not work at NT 4.0, if we use sizeof(OPENFILENAME*).
90 So we use size of old version of structure. */
91
92 #if defined(UNDER_CE) || defined(_WIN64) || (_WIN32_WINNT < 0x0500)
93 // || !defined(WINVER)
94 #define my_compatib_OPENFILENAMEA_size sizeof(OPENFILENAMEA)
95 #define my_compatib_OPENFILENAMEW_size sizeof(OPENFILENAMEW)
96 #else
97 #define my_compatib_OPENFILENAMEA_size OPENFILENAME_SIZE_VERSION_400A
98 #define my_compatib_OPENFILENAMEW_size OPENFILENAME_SIZE_VERSION_400W
99 #endif
100
101 #define CONV_U_To_A(dest, src, temp) AString temp; if (src) { temp = GetSystemString(src); dest = temp; }
102
MyGetOpenFileName(HWND hwnd,LPCWSTR title,LPCWSTR initialDir,LPCWSTR filePath,LPCWSTR filterDescription,LPCWSTR filter,UString & resPath,bool openFolder)103 bool MyGetOpenFileName(HWND hwnd, LPCWSTR title,
104 LPCWSTR initialDir,
105 LPCWSTR filePath,
106 LPCWSTR filterDescription,
107 LPCWSTR filter,
108 UString &resPath
109 #ifdef UNDER_CE
110 , bool openFolder
111 #endif
112 )
113 {
114 const unsigned kBufSize = MAX_PATH * 2;
115 const unsigned kFilterBufSize = MAX_PATH;
116 if (!filter)
117 filter = L"*.*";
118 #ifndef _UNICODE
119 if (!g_IsNT)
120 {
121 CHAR buf[kBufSize];
122 MyStringCopy(buf, (const char *)GetSystemString(filePath));
123 // OPENFILENAME_NT4A
124 OPENFILENAMEA p;
125 memset(&p, 0, sizeof(p));
126 p.lStructSize = my_compatib_OPENFILENAMEA_size;
127 p.hwndOwner = hwnd;
128 CHAR filterBuf[kFilterBufSize];
129 {
130 CDoubleZeroStringListA dz(filterBuf, kFilterBufSize);
131 dz.Add(GetSystemString(filterDescription ? filterDescription : filter));
132 dz.Add(GetSystemString(filter));
133 dz.Finish();
134 p.lpstrFilter = filterBuf;
135 p.nFilterIndex = 1;
136 }
137
138 p.lpstrFile = buf;
139 p.nMaxFile = kBufSize;
140 CONV_U_To_A(p.lpstrInitialDir, initialDir, initialDirA);
141 CONV_U_To_A(p.lpstrTitle, title, titleA);
142 p.Flags = OFN_EXPLORER | OFN_HIDEREADONLY;
143
144 bool res = BOOLToBool(::GetOpenFileNameA(&p));
145 resPath = GetUnicodeString(buf);
146 return res;
147 }
148 else
149 #endif
150 {
151 WCHAR buf[kBufSize];
152 MyStringCopy(buf, filePath);
153 // OPENFILENAME_NT4W
154 OPENFILENAMEW p;
155 memset(&p, 0, sizeof(p));
156 p.lStructSize = my_compatib_OPENFILENAMEW_size;
157 p.hwndOwner = hwnd;
158
159 WCHAR filterBuf[kFilterBufSize];
160 {
161 CDoubleZeroStringListW dz(filterBuf, kFilterBufSize);
162 dz.Add(filterDescription ? filterDescription : filter);
163 dz.Add(filter);
164 dz.Finish();
165 p.lpstrFilter = filterBuf;
166 p.nFilterIndex = 1;
167 }
168
169 p.lpstrFile = buf;
170 p.nMaxFile = kBufSize;
171 p.lpstrInitialDir = initialDir;
172 p.lpstrTitle = title;
173 p.Flags = OFN_EXPLORER | OFN_HIDEREADONLY
174 #ifdef UNDER_CE
175 | (openFolder ? (MY__OFN_PROJECT | MY__OFN_SHOW_ALL) : 0)
176 #endif
177 ;
178
179 bool res = BOOLToBool(::GetOpenFileNameW(&p));
180 resPath = buf;
181 return res;
182 }
183 }
184
185 }
186