X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/ce336c6d76d8c513487af08857c1cd3cbe806d30..69d31e313035d5e22d9400ec946f6007f710910c:/src/msw/stdpaths.cpp diff --git a/src/msw/stdpaths.cpp b/src/msw/stdpaths.cpp index dcb164a576..3667c1e954 100644 --- a/src/msw/stdpaths.cpp +++ b/src/msw/stdpaths.cpp @@ -24,15 +24,17 @@ #pragma hdrstop #endif +#if wxUSE_STDPATHS + +#include "wx/stdpaths.h" + #ifndef WX_PRECOMP - #include "wx/app.h" + #include "wx/utils.h" #endif //WX_PRECOMP #include "wx/dynlib.h" #include "wx/filename.h" -#include "wx/stdpaths.h" - #include "wx/msw/private.h" #include "wx/msw/wrapshl.h" @@ -48,7 +50,11 @@ typedef HRESULT (WINAPI *SHGetSpecialFolderPath_t)(HWND, LPTSTR, int, BOOL); // ---------------------------------------------------------------------------- // used in our wxLogTrace messages -static const wxChar *TRACE_MASK = _T("stdpaths"); +#define TRACE_MASK wxT("stdpaths") + +#ifndef CSIDL_APPDATA + #define CSIDL_APPDATA 0x001a +#endif #ifndef CSIDL_LOCAL_APPDATA #define CSIDL_LOCAL_APPDATA 0x001c @@ -62,10 +68,25 @@ static const wxChar *TRACE_MASK = _T("stdpaths"); #define CSIDL_PROGRAM_FILES 0x0026 #endif +#ifndef CSIDL_PERSONAL + #define CSIDL_PERSONAL 0x0005 +#endif + +#ifndef SHGFP_TYPE_CURRENT + #define SHGFP_TYPE_CURRENT 0 +#endif + +#ifndef SHGFP_TYPE_DEFAULT + #define SHGFP_TYPE_DEFAULT 1 +#endif + // ---------------------------------------------------------------------------- // module globals // ---------------------------------------------------------------------------- +namespace +{ + struct ShellFunctions { ShellFunctions() @@ -84,43 +105,54 @@ struct ShellFunctions // in spite of using a static variable, this is MT-safe as in the worst case it // results in initializing the function pointer several times -- but this is // harmless -static ShellFunctions gs_shellFuncs; +ShellFunctions gs_shellFuncs; // ---------------------------------------------------------------------------- // private functions // ---------------------------------------------------------------------------- -static void ResolveShellFunctions() +void ResolveShellFunctions() { - // don't give errors if the functions are unavailable, we're ready to deal - // with this - wxLogNull noLog; +#if wxUSE_DYNLIB_CLASS // start with the newest functions, fall back to the oldest ones - +#ifdef __WXWINCE__ + wxString shellDllName(wxT("coredll")); +#else // first check for SHGetFolderPath (shell32.dll 5.0) - wxDynamicLibrary dllShell32(_T("shell32")); - if ( !dllShell32.IsLoaded() ) + wxString shellDllName(wxT("shell32")); +#endif + + wxDynamicLibrary dllShellFunctions( shellDllName ); + if ( !dllShellFunctions.IsLoaded() ) { - wxLogTrace(TRACE_MASK, _T("Failed to load shell32.dll")); + wxLogTrace(TRACE_MASK, wxT("Failed to load %s.dll"), shellDllName.c_str() ); } + // don't give errors if the functions are unavailable, we're ready to deal + // with this + wxLogNull noLog; + #if wxUSE_UNICODE - static const wchar_t UNICODE_SUFFIX = L'W'; + #ifdef __WXWINCE__ + static const wchar_t UNICODE_SUFFIX = L''; // WinCE SH functions don't seem to have 'W' + #else + static const wchar_t UNICODE_SUFFIX = L'W'; + #endif #else // !Unicode static const char UNICODE_SUFFIX = 'A'; #endif // Unicode/!Unicode - wxString funcname(_T("SHGetFolderPath")); + wxString funcname(wxT("SHGetFolderPath")); gs_shellFuncs.pSHGetFolderPath = - (SHGetFolderPath_t)dllShell32.GetSymbol(funcname + UNICODE_SUFFIX); + (SHGetFolderPath_t)dllShellFunctions.GetSymbol(funcname + UNICODE_SUFFIX); // then for SHGetSpecialFolderPath (shell32.dll 4.71) if ( !gs_shellFuncs.pSHGetFolderPath ) { - funcname = _T("SHGetSpecialFolderPath"); + funcname = wxT("SHGetSpecialFolderPath"); gs_shellFuncs.pSHGetSpecialFolderPath = (SHGetSpecialFolderPath_t) - dllShell32.GetSymbol(funcname + UNICODE_SUFFIX); + dllShellFunctions.GetSymbol(funcname + UNICODE_SUFFIX); } // finally we fall back on SHGetSpecialFolderLocation (shell32.dll 4.0), @@ -130,8 +162,11 @@ static void ResolveShellFunctions() // because we also link to it statically, so it's ok gs_shellFuncs.initialized = true; +#endif } +} // anonymous namespace + // ============================================================================ // wxStandardPaths implementation // ============================================================================ @@ -216,13 +251,103 @@ wxString wxStandardPaths::DoGetDirectory(int csidl) return dir; } +wxString wxStandardPaths::GetAppDir() const +{ + if ( m_appDir.empty() ) + { + m_appDir = wxFileName(wxGetFullModuleName()).GetPath(); + } + + return m_appDir; +} + +wxString wxStandardPaths::GetDocumentsDir() const +{ + return DoGetDirectory(CSIDL_PERSONAL); +} + +// ---------------------------------------------------------------------------- +// MSW-specific functions +// ---------------------------------------------------------------------------- + +void wxStandardPaths::IgnoreAppSubDir(const wxString& subdirPattern) +{ + wxFileName fn = wxFileName::DirName(GetAppDir()); + + if ( !fn.GetDirCount() ) + { + // no last directory to ignore anyhow + return; + } + + const wxString lastdir = fn.GetDirs().Last().Lower(); + if ( lastdir.Matches(subdirPattern.Lower()) ) + { + fn.RemoveLastDir(); + + // store the cached value so that subsequent calls to GetAppDir() will + // reuse it instead of using just the program binary directory + m_appDir = fn.GetPath(); + } +} + +void wxStandardPaths::IgnoreAppBuildSubDirs() +{ + IgnoreAppSubDir("debug"); + IgnoreAppSubDir("release"); + + wxString compilerPrefix; +#ifdef __VISUALC__ + compilerPrefix = "vc"; +#elif defined(__GNUG__) + compilerPrefix = "gcc"; +#elif defined(__BORLANDC__) + compilerPrefix = "bcc"; +#elif defined(__DIGITALMARS__) + compilerPrefix = "dmc"; +#elif defined(__WATCOMC__) + compilerPrefix = "wat"; +#else + return; +#endif + + IgnoreAppSubDir(compilerPrefix + "_msw*"); +} + +void wxStandardPaths::DontIgnoreAppSubDir() +{ + // this will force the next call to GetAppDir() to use the program binary + // path as the application directory + m_appDir.clear(); +} + +/* static */ +wxString wxStandardPaths::MSWGetShellDir(int csidl) +{ + return DoGetDirectory(csidl); +} + // ---------------------------------------------------------------------------- // public functions // ---------------------------------------------------------------------------- +wxStandardPaths::wxStandardPaths() +{ + // under MSW it's common to use both the applicatio nand vendor + UseAppInfo(AppInfo_AppName | AppInfo_VendorName); + + // make it possible to run uninstalled application from the build directory + IgnoreAppBuildSubDirs(); +} + +wxString wxStandardPaths::GetExecutablePath() const +{ + return wxGetFullModuleName(); +} + wxString wxStandardPaths::GetConfigDir() const { - return AppendAppName(DoGetDirectory(CSIDL_COMMON_APPDATA)); + return AppendAppInfo(DoGetDirectory(CSIDL_COMMON_APPDATA)); } wxString wxStandardPaths::GetUserConfigDir() const @@ -232,25 +357,28 @@ wxString wxStandardPaths::GetUserConfigDir() const wxString wxStandardPaths::GetDataDir() const { - return AppendAppName(DoGetDirectory(CSIDL_PROGRAM_FILES)); + // under Windows each program is usually installed in its own directory and + // so its datafiles are in the same directory as its main executable + return GetAppDir(); } wxString wxStandardPaths::GetUserDataDir() const { - return AppendAppName(GetUserConfigDir()); + return AppendAppInfo(GetUserConfigDir()); } wxString wxStandardPaths::GetUserLocalDataDir() const { - return AppendAppName(DoGetDirectory(CSIDL_LOCAL_APPDATA)); + return AppendAppInfo(DoGetDirectory(CSIDL_LOCAL_APPDATA)); } wxString wxStandardPaths::GetPluginsDir() const { - return wxFileName(wxGetFullModuleName()).GetPath(); + // there is no standard location for plugins, suppose they're in the same + // directory as the .exe + return GetAppDir(); } - // ============================================================================ // wxStandardPathsWin16 implementation // ============================================================================ @@ -260,10 +388,15 @@ wxString wxStandardPathsWin16::GetConfigDir() const // this is for compatibility with earlier wxFileConfig versions // which used the Windows directory for the global files wxString dir; +#ifndef __WXWINCE__ if ( !::GetWindowsDirectory(wxStringBuffer(dir, MAX_PATH), MAX_PATH) ) { - wxLogLastError(_T("GetWindowsDirectory")); + wxLogLastError(wxT("GetWindowsDirectory")); } +#else + // TODO: use CSIDL_WINDOWS (eVC4, possibly not eVC3) + dir = wxT("\\Windows"); +#endif return dir; } @@ -274,3 +407,4 @@ wxString wxStandardPathsWin16::GetUserConfigDir() const return wxGetHomeDir(); } +#endif // wxUSE_STDPATHS