]> git.saurik.com Git - wxWidgets.git/blame - src/msw/stdpaths.cpp
Add support for wxSL_INVERSE flag. Also uses new inverse logic to make Mac vertical...
[wxWidgets.git] / src / msw / stdpaths.cpp
CommitLineData
40e8ee37
VZ
1///////////////////////////////////////////////////////////////////////////////
2// Name: msw/stdpaths.cpp
3// Purpose: wxStandardPaths implementation for Win32
4// Author: Vadim Zeitlin
5// Modified by:
6// Created: 2004-10-19
7// RCS-ID: $Id$
8// Copyright: (c) 2004 Vadim Zeitlin <vadim@wxwindows.org>
9// License: wxWindows license
10///////////////////////////////////////////////////////////////////////////////
11
12// ============================================================================
13// declarations
14// ============================================================================
15
16// ----------------------------------------------------------------------------
17// headers
18// ----------------------------------------------------------------------------
19
20// for compilers that support precompilation, includes "wx.h".
21#include "wx/wxprec.h"
22
23#ifdef __BORLANDC__
24 #pragma hdrstop
25#endif
26
27#ifndef WX_PRECOMP
28 #include "wx/app.h"
29#endif //WX_PRECOMP
30
31#include "wx/dynlib.h"
32#include "wx/filename.h"
33
34#include "wx/stdpaths.h"
35
36#include "wx/msw/private.h"
37#include "wx/msw/wrapshl.h"
38
39// ----------------------------------------------------------------------------
40// types
41// ----------------------------------------------------------------------------
42
43typedef HRESULT (WINAPI *SHGetFolderPath_t)(HWND, int, HANDLE, DWORD, LPTSTR);
44typedef HRESULT (WINAPI *SHGetSpecialFolderPath_t)(HWND, LPTSTR, int, BOOL);
45
46// ----------------------------------------------------------------------------
47// constants
48// ----------------------------------------------------------------------------
49
50// used in our wxLogTrace messages
51static const wxChar *TRACE_MASK = _T("stdpaths");
52
61c2afed
WS
53#ifndef CSIDL_APPDATA
54 #define CSIDL_APPDATA 0x001a
55#endif
56
40e8ee37
VZ
57#ifndef CSIDL_LOCAL_APPDATA
58 #define CSIDL_LOCAL_APPDATA 0x001c
59#endif
60
61#ifndef CSIDL_COMMON_APPDATA
62 #define CSIDL_COMMON_APPDATA 0x0023
63#endif
64
65#ifndef CSIDL_PROGRAM_FILES
66 #define CSIDL_PROGRAM_FILES 0x0026
67#endif
68
cd0c4800
WS
69#ifndef SHGFP_TYPE_CURRENT
70 #define SHGFP_TYPE_CURRENT 0
71#endif
72
73#ifndef SHGFP_TYPE_DEFAULT
74 #define SHGFP_TYPE_DEFAULT 1
75#endif
76
40e8ee37
VZ
77// ----------------------------------------------------------------------------
78// module globals
79// ----------------------------------------------------------------------------
80
81struct ShellFunctions
82{
83 ShellFunctions()
84 {
85 pSHGetFolderPath = NULL;
86 pSHGetSpecialFolderPath = NULL;
87 initialized = false;
88 }
89
90 SHGetFolderPath_t pSHGetFolderPath;
91 SHGetSpecialFolderPath_t pSHGetSpecialFolderPath;
92
93 bool initialized;
94};
95
96// in spite of using a static variable, this is MT-safe as in the worst case it
97// results in initializing the function pointer several times -- but this is
98// harmless
99static ShellFunctions gs_shellFuncs;
100
101// ----------------------------------------------------------------------------
102// private functions
103// ----------------------------------------------------------------------------
104
105static void ResolveShellFunctions()
106{
107 // don't give errors if the functions are unavailable, we're ready to deal
108 // with this
109 wxLogNull noLog;
110
111 // start with the newest functions, fall back to the oldest ones
112
113 // first check for SHGetFolderPath (shell32.dll 5.0)
114 wxDynamicLibrary dllShell32(_T("shell32"));
115 if ( !dllShell32.IsLoaded() )
116 {
117 wxLogTrace(TRACE_MASK, _T("Failed to load shell32.dll"));
118 }
119
120#if wxUSE_UNICODE
121 static const wchar_t UNICODE_SUFFIX = L'W';
122#else // !Unicode
123 static const char UNICODE_SUFFIX = 'A';
124#endif // Unicode/!Unicode
125
126 wxString funcname(_T("SHGetFolderPath"));
127 gs_shellFuncs.pSHGetFolderPath =
128 (SHGetFolderPath_t)dllShell32.GetSymbol(funcname + UNICODE_SUFFIX);
129
130 // then for SHGetSpecialFolderPath (shell32.dll 4.71)
131 if ( !gs_shellFuncs.pSHGetFolderPath )
132 {
133 funcname = _T("SHGetSpecialFolderPath");
134 gs_shellFuncs.pSHGetSpecialFolderPath = (SHGetSpecialFolderPath_t)
135 dllShell32.GetSymbol(funcname + UNICODE_SUFFIX);
136 }
137
138 // finally we fall back on SHGetSpecialFolderLocation (shell32.dll 4.0),
139 // but we don't need to test for it -- it is available even under Win95
140
141 // shell32.dll is going to be unloaded, but it still remains in memory
142 // because we also link to it statically, so it's ok
143
144 gs_shellFuncs.initialized = true;
145}
146
147// ============================================================================
148// wxStandardPaths implementation
149// ============================================================================
150
151// ----------------------------------------------------------------------------
152// private helpers
153// ----------------------------------------------------------------------------
154
155/* static */
156wxString wxStandardPaths::DoGetDirectory(int csidl)
157{
158 if ( !gs_shellFuncs.initialized )
159 ResolveShellFunctions();
160
161 wxString dir;
162 HRESULT hr = E_FAIL;
163
164 // test whether the function is available during compile-time (it must be
165 // defined as either "SHGetFolderPathA" or "SHGetFolderPathW")
166#ifdef SHGetFolderPath
167 // and now test whether we have it during run-time
168 if ( gs_shellFuncs.pSHGetFolderPath )
169 {
170 hr = gs_shellFuncs.pSHGetFolderPath
171 (
172 NULL, // parent window, not used
173 csidl,
174 NULL, // access token (current user)
175 SHGFP_TYPE_CURRENT, // current path, not just default value
176 wxStringBuffer(dir, MAX_PATH)
177 );
178
179 // somewhat incredibly, the error code in the Unicode version is
180 // different from the one in ASCII version for this function
181#if wxUSE_UNICODE
182 if ( hr == E_FAIL )
183#else
184 if ( hr == S_FALSE )
185#endif
186 {
187 // directory doesn't exist, maybe we can get its default value?
188 hr = gs_shellFuncs.pSHGetFolderPath
189 (
190 NULL,
191 csidl,
192 NULL,
193 SHGFP_TYPE_DEFAULT,
194 wxStringBuffer(dir, MAX_PATH)
195 );
196 }
197 }
198#endif // SHGetFolderPath
199
200#ifdef SHGetSpecialFolderPath
201 if ( FAILED(hr) && gs_shellFuncs.pSHGetSpecialFolderPath )
202 {
203 hr = gs_shellFuncs.pSHGetSpecialFolderPath
204 (
205 NULL, // parent window
206 wxStringBuffer(dir, MAX_PATH),
207 csidl,
208 FALSE // don't create if doesn't exist
209 );
210 }
211#endif // SHGetSpecialFolderPath
212
213 // SHGetSpecialFolderLocation should be available with all compilers and
214 // under all Win32 systems, so don't test for it (and as it doesn't exist
215 // in "A" and "W" versions anyhow, testing would be more involved, too)
216 if ( FAILED(hr) )
217 {
218 LPITEMIDLIST pidl;
219 hr = SHGetSpecialFolderLocation(NULL, csidl, &pidl);
220
221 if ( SUCCEEDED(hr) )
222 {
223 // creating this temp object has (nice) side effect of freeing pidl
224 dir = wxItemIdList(pidl).GetPath();
225 }
226 }
227
228 return dir;
229}
230
40e8ee37
VZ
231// ----------------------------------------------------------------------------
232// public functions
233// ----------------------------------------------------------------------------
234
235wxString wxStandardPaths::GetConfigDir() const
236{
237 return AppendAppName(DoGetDirectory(CSIDL_COMMON_APPDATA));
238}
239
240wxString wxStandardPaths::GetUserConfigDir() const
241{
242 return DoGetDirectory(CSIDL_APPDATA);
243}
244
245wxString wxStandardPaths::GetDataDir() const
246{
247 return AppendAppName(DoGetDirectory(CSIDL_PROGRAM_FILES));
248}
249
250wxString wxStandardPaths::GetUserDataDir() const
251{
252 return AppendAppName(GetUserConfigDir());
253}
254
255wxString wxStandardPaths::GetUserLocalDataDir() const
256{
257 return AppendAppName(DoGetDirectory(CSIDL_LOCAL_APPDATA));
258}
259
260wxString wxStandardPaths::GetPluginsDir() const
261{
262 return wxFileName(wxGetFullModuleName()).GetPath();
263}
264
265
266// ============================================================================
267// wxStandardPathsWin16 implementation
268// ============================================================================
269
270wxString wxStandardPathsWin16::GetConfigDir() const
271{
272 // this is for compatibility with earlier wxFileConfig versions
273 // which used the Windows directory for the global files
274 wxString dir;
e2072525 275#ifndef __WXWINCE__
40e8ee37
VZ
276 if ( !::GetWindowsDirectory(wxStringBuffer(dir, MAX_PATH), MAX_PATH) )
277 {
278 wxLogLastError(_T("GetWindowsDirectory"));
279 }
e2072525
WS
280#else
281 // TODO:
282 // eVC4 - use CSIDL_WINDOWS
283 // eVC3 - probably not possible through API
284#endif
40e8ee37
VZ
285
286 return dir;
287}
288
289wxString wxStandardPathsWin16::GetUserConfigDir() const
290{
291 // again, for wxFileConfig which uses $HOME for its user config file
292 return wxGetHomeDir();
293}
294