summaryrefslogtreecommitdiffstats
path: root/other-licenses/7zstub/src/CPP/Windows/CommonDialog.cpp
blob: 8b3828cf76e177b9486f0bfbbbc7537c1d3e4a20 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
// Windows/CommonDialog.cpp

#include "StdAfx.h"

#include "../Common/MyWindows.h"

#ifdef UNDER_CE
#include <commdlg.h>
#endif

#ifndef _UNICODE
#include "../Common/StringConvert.h"
#endif

#include "CommonDialog.h"
#include "Defs.h"

#ifndef _UNICODE
extern bool g_IsNT;
#endif

namespace NWindows {

#ifndef _UNICODE

class CDoubleZeroStringListA
{
  LPTSTR Buf;
  unsigned Size;
public:
  CDoubleZeroStringListA(LPSTR buf, unsigned size): Buf(buf), Size(size) {}
  bool Add(LPCSTR s) throw();
  void Finish() { *Buf = 0; }
};

bool CDoubleZeroStringListA::Add(LPCSTR s) throw()
{
  unsigned len = MyStringLen(s) + 1;
  if (len >= Size)
    return false;
  MyStringCopy(Buf, s);
  Buf += len;
  Size -= len;
  return true;
}

#endif

class CDoubleZeroStringListW
{
  LPWSTR Buf;
  unsigned Size;
public:
  CDoubleZeroStringListW(LPWSTR buf, unsigned size): Buf(buf), Size(size) {}
  bool Add(LPCWSTR s) throw();
  void Finish() { *Buf = 0; }
};

bool CDoubleZeroStringListW::Add(LPCWSTR s) throw()
{
  unsigned len = MyStringLen(s) + 1;
  if (len >= Size)
    return false;
  MyStringCopy(Buf, s);
  Buf += len;
  Size -= len;
  return true;
}

#define MY__OFN_PROJECT  0x00400000
#define MY__OFN_SHOW_ALL 0x01000000

/* if (lpstrFilter == NULL && nFilterIndex == 0)
  MSDN : "the system doesn't show any files",
  but WinXP-64 shows all files. Why ??? */

/*
structures
  OPENFILENAMEW
  OPENFILENAMEA
contain additional members:
#if (_WIN32_WINNT >= 0x0500)
  void *pvReserved;
  DWORD dwReserved;
  DWORD FlagsEx;
#endif

If we compile the source code with (_WIN32_WINNT >= 0x0500), some functions
will not work at NT 4.0, if we use sizeof(OPENFILENAME*).
So we use size of old version of structure. */

#if defined(UNDER_CE) || defined(_WIN64) || (_WIN32_WINNT < 0x0500)
// || !defined(WINVER)
  #define my_compatib_OPENFILENAMEA_size sizeof(OPENFILENAMEA)
  #define my_compatib_OPENFILENAMEW_size sizeof(OPENFILENAMEW)
#else
  #define my_compatib_OPENFILENAMEA_size OPENFILENAME_SIZE_VERSION_400A
  #define my_compatib_OPENFILENAMEW_size OPENFILENAME_SIZE_VERSION_400W
#endif

#define CONV_U_To_A(dest, src, temp) AString temp; if (src) { temp = GetSystemString(src); dest = temp; }

bool MyGetOpenFileName(HWND hwnd, LPCWSTR title,
    LPCWSTR initialDir,
    LPCWSTR filePath,
    LPCWSTR filterDescription,
    LPCWSTR filter,
    UString &resPath
    #ifdef UNDER_CE
    , bool openFolder
    #endif
    )
{
  const unsigned kBufSize = MAX_PATH * 2;
  const unsigned kFilterBufSize = MAX_PATH;
  if (!filter)
    filter = L"*.*";
  #ifndef _UNICODE
  if (!g_IsNT)
  {
    CHAR buf[kBufSize];
    MyStringCopy(buf, (const char *)GetSystemString(filePath));
    // OPENFILENAME_NT4A
    OPENFILENAMEA p;
    memset(&p, 0, sizeof(p));
    p.lStructSize = my_compatib_OPENFILENAMEA_size;
    p.hwndOwner = hwnd;
    CHAR filterBuf[kFilterBufSize];
    {
      CDoubleZeroStringListA dz(filterBuf, kFilterBufSize);
      dz.Add(GetSystemString(filterDescription ? filterDescription : filter));
      dz.Add(GetSystemString(filter));
      dz.Finish();
      p.lpstrFilter = filterBuf;
      p.nFilterIndex = 1;
    }
    
    p.lpstrFile = buf;
    p.nMaxFile = kBufSize;
    CONV_U_To_A(p.lpstrInitialDir, initialDir, initialDirA);
    CONV_U_To_A(p.lpstrTitle, title, titleA);
    p.Flags = OFN_EXPLORER | OFN_HIDEREADONLY;

    bool res = BOOLToBool(::GetOpenFileNameA(&p));
    resPath = GetUnicodeString(buf);
    return res;
  }
  else
  #endif
  {
    WCHAR buf[kBufSize];
    MyStringCopy(buf, filePath);
    // OPENFILENAME_NT4W
    OPENFILENAMEW p;
    memset(&p, 0, sizeof(p));
    p.lStructSize = my_compatib_OPENFILENAMEW_size;
    p.hwndOwner = hwnd;
    
    WCHAR filterBuf[kFilterBufSize];
    {
      CDoubleZeroStringListW dz(filterBuf, kFilterBufSize);
      dz.Add(filterDescription ? filterDescription : filter);
      dz.Add(filter);
      dz.Finish();
      p.lpstrFilter = filterBuf;
      p.nFilterIndex = 1;
    }
        
    p.lpstrFile = buf;
    p.nMaxFile = kBufSize;
    p.lpstrInitialDir = initialDir;
    p.lpstrTitle = title;
    p.Flags = OFN_EXPLORER | OFN_HIDEREADONLY
        #ifdef UNDER_CE
        | (openFolder ? (MY__OFN_PROJECT | MY__OFN_SHOW_ALL) : 0)
        #endif
        ;

    bool res = BOOLToBool(::GetOpenFileNameW(&p));
    resPath = buf;
    return res;
  }
}

}