]> git.saurik.com Git - wxWidgets.git/blobdiff - src/msw/stdpaths.cpp
Enable variadic macros for VC9 and later.
[wxWidgets.git] / src / msw / stdpaths.cpp
index 707c30e38341a92e4cb91a387ace6c9b0be411df..a4a016c85b5454aa75ed516af2f2281a3cd65f39 100644 (file)
@@ -1,12 +1,12 @@
 ///////////////////////////////////////////////////////////////////////////////
 ///////////////////////////////////////////////////////////////////////////////
-// Name:        msw/stdpaths.cpp
+// Name:        src/msw/stdpaths.cpp
 // Purpose:     wxStandardPaths implementation for Win32
 // Author:      Vadim Zeitlin
 // Modified by:
 // Created:     2004-10-19
 // RCS-ID:      $Id$
 // Copyright:   (c) 2004 Vadim Zeitlin <vadim@wxwindows.org>
 // Purpose:     wxStandardPaths implementation for Win32
 // Author:      Vadim Zeitlin
 // Modified by:
 // Created:     2004-10-19
 // RCS-ID:      $Id$
 // Copyright:   (c) 2004 Vadim Zeitlin <vadim@wxwindows.org>
-// License:     wxWindows license
+// Licence:     wxWindows licence
 ///////////////////////////////////////////////////////////////////////////////
 
 // ============================================================================
 ///////////////////////////////////////////////////////////////////////////////
 
 // ============================================================================
 
 #if wxUSE_STDPATHS
 
 
 #if wxUSE_STDPATHS
 
+#include "wx/stdpaths.h"
+
 #ifndef WX_PRECOMP
 #ifndef WX_PRECOMP
-    #include "wx/app.h"
+    #include "wx/utils.h"
 #endif //WX_PRECOMP
 
 #include "wx/dynlib.h"
 #include "wx/filename.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"
 
 #include "wx/msw/private.h"
 #include "wx/msw/wrapshl.h"
 
@@ -50,7 +50,7 @@ typedef HRESULT (WINAPI *SHGetSpecialFolderPath_t)(HWND, LPTSTR, int, BOOL);
 // ----------------------------------------------------------------------------
 
 // used in our wxLogTrace messages
 // ----------------------------------------------------------------------------
 
 // used in our wxLogTrace messages
-static const wxChar *TRACE_MASK = _T("stdpaths");
+#define TRACE_MASK wxT("stdpaths")
 
 #ifndef CSIDL_APPDATA
     #define CSIDL_APPDATA         0x001a
 
 #ifndef CSIDL_APPDATA
     #define CSIDL_APPDATA         0x001a
@@ -68,6 +68,10 @@ static const wxChar *TRACE_MASK = _T("stdpaths");
     #define CSIDL_PROGRAM_FILES   0x0026
 #endif
 
     #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_CURRENT
     #define SHGFP_TYPE_CURRENT 0
 #endif
@@ -80,6 +84,9 @@ static const wxChar *TRACE_MASK = _T("stdpaths");
 // module globals
 // ----------------------------------------------------------------------------
 
 // module globals
 // ----------------------------------------------------------------------------
 
+namespace
+{
+
 struct ShellFunctions
 {
     ShellFunctions()
 struct ShellFunctions
 {
     ShellFunctions()
@@ -98,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
 // 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
 // ----------------------------------------------------------------------------
 
 
 // ----------------------------------------------------------------------------
 // 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
 
     // 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)
     // 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
 #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
 
 #else // !Unicode
     static const char UNICODE_SUFFIX = 'A';
 #endif // Unicode/!Unicode
 
-    wxString funcname(_T("SHGetFolderPath"));
+    wxString funcname(wxT("SHGetFolderPath"));
     gs_shellFuncs.pSHGetFolderPath =
     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 )
     {
 
     // then for SHGetSpecialFolderPath (shell32.dll 4.71)
     if ( !gs_shellFuncs.pSHGetFolderPath )
     {
-        funcname = _T("SHGetSpecialFolderPath");
+        funcname = wxT("SHGetSpecialFolderPath");
         gs_shellFuncs.pSHGetSpecialFolderPath = (SHGetSpecialFolderPath_t)
         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),
     }
 
     // finally we fall back on SHGetSpecialFolderLocation (shell32.dll 4.0),
@@ -144,8 +162,11 @@ static void ResolveShellFunctions()
     // because we also link to it statically, so it's ok
 
     gs_shellFuncs.initialized = true;
     // because we also link to it statically, so it's ok
 
     gs_shellFuncs.initialized = true;
+#endif
 }
 
 }
 
+} // anonymous namespace
+
 // ============================================================================
 // wxStandardPaths implementation
 // ============================================================================
 // ============================================================================
 // wxStandardPaths implementation
 // ============================================================================
@@ -230,13 +251,100 @@ wxString wxStandardPaths::DoGetDirectory(int csidl)
     return dir;
 }
 
     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
 // ----------------------------------------------------------------------------
 
 // ----------------------------------------------------------------------------
 // public functions
 // ----------------------------------------------------------------------------
 
+wxStandardPaths::wxStandardPaths()
+{
+    // make it possible to run uninstalled application from the build directory
+    IgnoreAppBuildSubDirs();
+}
+
+wxString wxStandardPaths::GetExecutablePath() const
+{
+    return wxGetFullModuleName();
+}
+
 wxString wxStandardPaths::GetConfigDir() const
 {
 wxString wxStandardPaths::GetConfigDir() const
 {
-    return AppendAppName(DoGetDirectory(CSIDL_COMMON_APPDATA));
+    return AppendAppInfo(DoGetDirectory(CSIDL_COMMON_APPDATA));
 }
 
 wxString wxStandardPaths::GetUserConfigDir() const
 }
 
 wxString wxStandardPaths::GetUserConfigDir() const
@@ -248,25 +356,26 @@ wxString wxStandardPaths::GetDataDir() const
 {
     // under Windows each program is usually installed in its own directory and
     // so its datafiles are in the same directory as its main executable
 {
     // 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 wxFileName(wxGetFullModuleName()).GetPath();
+    return GetAppDir();
 }
 
 wxString wxStandardPaths::GetUserDataDir() const
 {
 }
 
 wxString wxStandardPaths::GetUserDataDir() const
 {
-    return AppendAppName(GetUserConfigDir());
+    return AppendAppInfo(GetUserConfigDir());
 }
 
 wxString wxStandardPaths::GetUserLocalDataDir() const
 {
 }
 
 wxString wxStandardPaths::GetUserLocalDataDir() const
 {
-    return AppendAppName(DoGetDirectory(CSIDL_LOCAL_APPDATA));
+    return AppendAppInfo(DoGetDirectory(CSIDL_LOCAL_APPDATA));
 }
 
 wxString wxStandardPaths::GetPluginsDir() const
 {
 }
 
 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
 // ============================================================================
 // ============================================================================
 // wxStandardPathsWin16 implementation
 // ============================================================================
@@ -279,12 +388,11 @@ wxString wxStandardPathsWin16::GetConfigDir() const
 #ifndef __WXWINCE__
     if ( !::GetWindowsDirectory(wxStringBuffer(dir, MAX_PATH), MAX_PATH) )
     {
 #ifndef __WXWINCE__
     if ( !::GetWindowsDirectory(wxStringBuffer(dir, MAX_PATH), MAX_PATH) )
     {
-        wxLogLastError(_T("GetWindowsDirectory"));
+        wxLogLastError(wxT("GetWindowsDirectory"));
     }
 #else
     }
 #else
-    // TODO:
-    //    eVC4 - use CSIDL_WINDOWS
-    //    eVC3 - probably not possible through API
+    // TODO: use CSIDL_WINDOWS (eVC4, possibly not eVC3)
+    dir = wxT("\\Windows");
 #endif
 
     return dir;
 #endif
 
     return dir;