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