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: 29 CDoubleZeroStringListA(LPSTR buf, unsigned size): Buf(buf), Size(size) {} 30 bool Add(LPCSTR s) throw(); 31 void Finish() { *Buf = 0; } 32 }; 33 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: 52 CDoubleZeroStringListW(LPWSTR buf, unsigned size): Buf(buf), Size(size) {} 53 bool Add(LPCWSTR s) throw(); 54 void Finish() { *Buf = 0; } 55 }; 56 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 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