initial implementation for MSW
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@30005 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
51
include/wx/msw/stdpaths.h
Normal file
51
include/wx/msw/stdpaths.h
Normal file
@@ -0,0 +1,51 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Name: wx/msw/stdpaths.h
|
||||
// Purpose: wxStandardPaths for Win32
|
||||
// Author: Vadim Zeitlin
|
||||
// Modified by:
|
||||
// Created: 2004-10-19
|
||||
// RCS-ID: $Id$
|
||||
// Copyright: (c) 2004 Vadim Zeitlin <vadim@wxwindows.org>
|
||||
// Licence: wxWindows licence
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef _WX_MSW_STDPATHS_H_
|
||||
#define _WX_MSW_STDPATHS_H_
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// wxStandardPaths
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
class WXDLLIMPEXP_BASE wxStandardPaths : public wxStandardPathsBase
|
||||
{
|
||||
public:
|
||||
// implement base class pure virtuals
|
||||
virtual wxString GetConfigDir() const;
|
||||
virtual wxString GetUserConfigDir() const;
|
||||
virtual wxString GetDataDir() const;
|
||||
virtual wxString GetUserDataDir() const;
|
||||
virtual wxString GetUserLocalDataDir() const;
|
||||
virtual wxString GetPluginsDir() const;
|
||||
|
||||
protected:
|
||||
// append "/appname" suffix if the app name is set
|
||||
static wxString AppendAppName(const wxString& dir);
|
||||
|
||||
// get the path corresponding to the given standard CSIDL_XXX constant
|
||||
static wxString DoGetDirectory(int csidl);
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// wxStandardPathsWin16: this class is for internal use only
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// override config file locations to be compatible with the values used by
|
||||
// wxFileConfig (dating from Win16 days which explains the class name)
|
||||
class WXDLLIMPEXP_BASE wxStandardPathsWin16 : public wxStandardPaths
|
||||
{
|
||||
public:
|
||||
virtual wxString GetConfigDir() const;
|
||||
virtual wxString GetUserConfigDir() const;
|
||||
};
|
||||
|
||||
#endif // _WX_MSW_STDPATHS_H_
|
292
src/msw/stdpaths.cpp
Normal file
292
src/msw/stdpaths.cpp
Normal file
@@ -0,0 +1,292 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Name: 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>
|
||||
// License: wxWindows license
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// ============================================================================
|
||||
// declarations
|
||||
// ============================================================================
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// headers
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// for compilers that support precompilation, includes "wx.h".
|
||||
#include "wx/wxprec.h"
|
||||
|
||||
#ifdef __BORLANDC__
|
||||
#pragma hdrstop
|
||||
#endif
|
||||
|
||||
#ifndef WX_PRECOMP
|
||||
#include "wx/app.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"
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// types
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
typedef HRESULT (WINAPI *SHGetFolderPath_t)(HWND, int, HANDLE, DWORD, LPTSTR);
|
||||
typedef HRESULT (WINAPI *SHGetSpecialFolderPath_t)(HWND, LPTSTR, int, BOOL);
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// constants
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// used in our wxLogTrace messages
|
||||
static const wxChar *TRACE_MASK = _T("stdpaths");
|
||||
|
||||
#ifndef CSIDL_LOCAL_APPDATA
|
||||
#define CSIDL_LOCAL_APPDATA 0x001c
|
||||
#endif
|
||||
|
||||
#ifndef CSIDL_COMMON_APPDATA
|
||||
#define CSIDL_COMMON_APPDATA 0x0023
|
||||
#endif
|
||||
|
||||
#ifndef CSIDL_PROGRAM_FILES
|
||||
#define CSIDL_PROGRAM_FILES 0x0026
|
||||
#endif
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// module globals
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
struct ShellFunctions
|
||||
{
|
||||
ShellFunctions()
|
||||
{
|
||||
pSHGetFolderPath = NULL;
|
||||
pSHGetSpecialFolderPath = NULL;
|
||||
initialized = false;
|
||||
}
|
||||
|
||||
SHGetFolderPath_t pSHGetFolderPath;
|
||||
SHGetSpecialFolderPath_t pSHGetSpecialFolderPath;
|
||||
|
||||
bool initialized;
|
||||
};
|
||||
|
||||
// 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;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// private functions
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
static void ResolveShellFunctions()
|
||||
{
|
||||
// don't give errors if the functions are unavailable, we're ready to deal
|
||||
// with this
|
||||
wxLogNull noLog;
|
||||
|
||||
// start with the newest functions, fall back to the oldest ones
|
||||
|
||||
// first check for SHGetFolderPath (shell32.dll 5.0)
|
||||
wxDynamicLibrary dllShell32(_T("shell32"));
|
||||
if ( !dllShell32.IsLoaded() )
|
||||
{
|
||||
wxLogTrace(TRACE_MASK, _T("Failed to load shell32.dll"));
|
||||
}
|
||||
|
||||
#if wxUSE_UNICODE
|
||||
static const wchar_t UNICODE_SUFFIX = L'W';
|
||||
#else // !Unicode
|
||||
static const char UNICODE_SUFFIX = 'A';
|
||||
#endif // Unicode/!Unicode
|
||||
|
||||
wxString funcname(_T("SHGetFolderPath"));
|
||||
gs_shellFuncs.pSHGetFolderPath =
|
||||
(SHGetFolderPath_t)dllShell32.GetSymbol(funcname + UNICODE_SUFFIX);
|
||||
|
||||
// then for SHGetSpecialFolderPath (shell32.dll 4.71)
|
||||
if ( !gs_shellFuncs.pSHGetFolderPath )
|
||||
{
|
||||
funcname = _T("SHGetSpecialFolderPath");
|
||||
gs_shellFuncs.pSHGetSpecialFolderPath = (SHGetSpecialFolderPath_t)
|
||||
dllShell32.GetSymbol(funcname + UNICODE_SUFFIX);
|
||||
}
|
||||
|
||||
// finally we fall back on SHGetSpecialFolderLocation (shell32.dll 4.0),
|
||||
// but we don't need to test for it -- it is available even under Win95
|
||||
|
||||
// shell32.dll is going to be unloaded, but it still remains in memory
|
||||
// because we also link to it statically, so it's ok
|
||||
|
||||
gs_shellFuncs.initialized = true;
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// wxStandardPaths implementation
|
||||
// ============================================================================
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// private helpers
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
/* static */
|
||||
wxString wxStandardPaths::DoGetDirectory(int csidl)
|
||||
{
|
||||
if ( !gs_shellFuncs.initialized )
|
||||
ResolveShellFunctions();
|
||||
|
||||
wxString dir;
|
||||
HRESULT hr = E_FAIL;
|
||||
|
||||
// test whether the function is available during compile-time (it must be
|
||||
// defined as either "SHGetFolderPathA" or "SHGetFolderPathW")
|
||||
#ifdef SHGetFolderPath
|
||||
// and now test whether we have it during run-time
|
||||
if ( gs_shellFuncs.pSHGetFolderPath )
|
||||
{
|
||||
hr = gs_shellFuncs.pSHGetFolderPath
|
||||
(
|
||||
NULL, // parent window, not used
|
||||
csidl,
|
||||
NULL, // access token (current user)
|
||||
SHGFP_TYPE_CURRENT, // current path, not just default value
|
||||
wxStringBuffer(dir, MAX_PATH)
|
||||
);
|
||||
|
||||
// somewhat incredibly, the error code in the Unicode version is
|
||||
// different from the one in ASCII version for this function
|
||||
#if wxUSE_UNICODE
|
||||
if ( hr == E_FAIL )
|
||||
#else
|
||||
if ( hr == S_FALSE )
|
||||
#endif
|
||||
{
|
||||
// directory doesn't exist, maybe we can get its default value?
|
||||
hr = gs_shellFuncs.pSHGetFolderPath
|
||||
(
|
||||
NULL,
|
||||
csidl,
|
||||
NULL,
|
||||
SHGFP_TYPE_DEFAULT,
|
||||
wxStringBuffer(dir, MAX_PATH)
|
||||
);
|
||||
}
|
||||
}
|
||||
#endif // SHGetFolderPath
|
||||
|
||||
#ifdef SHGetSpecialFolderPath
|
||||
if ( FAILED(hr) && gs_shellFuncs.pSHGetSpecialFolderPath )
|
||||
{
|
||||
hr = gs_shellFuncs.pSHGetSpecialFolderPath
|
||||
(
|
||||
NULL, // parent window
|
||||
wxStringBuffer(dir, MAX_PATH),
|
||||
csidl,
|
||||
FALSE // don't create if doesn't exist
|
||||
);
|
||||
}
|
||||
#endif // SHGetSpecialFolderPath
|
||||
|
||||
// SHGetSpecialFolderLocation should be available with all compilers and
|
||||
// under all Win32 systems, so don't test for it (and as it doesn't exist
|
||||
// in "A" and "W" versions anyhow, testing would be more involved, too)
|
||||
if ( FAILED(hr) )
|
||||
{
|
||||
LPITEMIDLIST pidl;
|
||||
hr = SHGetSpecialFolderLocation(NULL, csidl, &pidl);
|
||||
|
||||
if ( SUCCEEDED(hr) )
|
||||
{
|
||||
// creating this temp object has (nice) side effect of freeing pidl
|
||||
dir = wxItemIdList(pidl).GetPath();
|
||||
}
|
||||
}
|
||||
|
||||
return dir;
|
||||
}
|
||||
|
||||
/* static */
|
||||
wxString wxStandardPaths::AppendAppName(const wxString& dir)
|
||||
{
|
||||
wxString subdir(dir);
|
||||
|
||||
// empty string indicates that an error has occured, don't touch it then
|
||||
if ( !subdir.empty() )
|
||||
{
|
||||
const wxString appname = wxTheApp->GetAppName();
|
||||
if ( !appname.empty() )
|
||||
subdir << _T('\\') << appname;
|
||||
}
|
||||
|
||||
return subdir;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// public functions
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
wxString wxStandardPaths::GetConfigDir() const
|
||||
{
|
||||
return AppendAppName(DoGetDirectory(CSIDL_COMMON_APPDATA));
|
||||
}
|
||||
|
||||
wxString wxStandardPaths::GetUserConfigDir() const
|
||||
{
|
||||
return DoGetDirectory(CSIDL_APPDATA);
|
||||
}
|
||||
|
||||
wxString wxStandardPaths::GetDataDir() const
|
||||
{
|
||||
return AppendAppName(DoGetDirectory(CSIDL_PROGRAM_FILES));
|
||||
}
|
||||
|
||||
wxString wxStandardPaths::GetUserDataDir() const
|
||||
{
|
||||
return AppendAppName(GetUserConfigDir());
|
||||
}
|
||||
|
||||
wxString wxStandardPaths::GetUserLocalDataDir() const
|
||||
{
|
||||
return AppendAppName(DoGetDirectory(CSIDL_LOCAL_APPDATA));
|
||||
}
|
||||
|
||||
wxString wxStandardPaths::GetPluginsDir() const
|
||||
{
|
||||
return wxFileName(wxGetFullModuleName()).GetPath();
|
||||
}
|
||||
|
||||
|
||||
// ============================================================================
|
||||
// wxStandardPathsWin16 implementation
|
||||
// ============================================================================
|
||||
|
||||
wxString wxStandardPathsWin16::GetConfigDir() const
|
||||
{
|
||||
// this is for compatibility with earlier wxFileConfig versions
|
||||
// which used the Windows directory for the global files
|
||||
wxString dir;
|
||||
if ( !::GetWindowsDirectory(wxStringBuffer(dir, MAX_PATH), MAX_PATH) )
|
||||
{
|
||||
wxLogLastError(_T("GetWindowsDirectory"));
|
||||
}
|
||||
|
||||
return dir;
|
||||
}
|
||||
|
||||
wxString wxStandardPathsWin16::GetUserConfigDir() const
|
||||
{
|
||||
// again, for wxFileConfig which uses $HOME for its user config file
|
||||
return wxGetHomeDir();
|
||||
}
|
||||
|
Reference in New Issue
Block a user