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