Home | History | Annotate | Download | only in Windows
      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