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