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