Angus Leeming wrote:
>> Would it be possible to move the GetFolderPath code to os_win32.C? It
>> could be exported via a simple get_folder_path(int) function, or
>> something. I understand there is a problem with declaring it in os.h,
>> though.
...
> Perhaps you'd prefer a separate os_win32.h that is explictly #included by
> package.C ?
See attached.
--
Angus
// -*- C++ -*-
/**
* \file os_win32.h
* This file is part of LyX, the document processor.
* Licence details can be found in the file COPYING.
*
* \author Angus Leeming
*
* Full author contact details are available in file CREDITS.
*
* These classes should be used only on Windows machines.
*/
#ifndef OS_WIN32_H
#define OS_WIN32_H
#include <string>
#if !defined(_WIN32)
# error os_win32.h should be compiled only under Windows.
#endif
/* The GetLongPathNameA function declaration in
* winbase.h under MinGW or Cygwin is protected
* by the WINVER macro which is defined in windef.h
*/
#if defined(__MINGW32__) || defined(__CYGWIN__) || defined(__CYGWIN32__)
# if defined(WINVER) && WINVER < 0x0500
# error WINVER must be >= 0x0500
# endif
# define WINVER 0x0500
#endif
#include <windef.h>
/** This class provides a portable wrapper to SHGetFolderPathA that can be
* used on all versions of Windows >= Win95.
*
* GetLongPathNameA is to be found in Kernel32.dll
* on Win98 and newer flavours of Windows. The function
* is declared in winbase.h on such a machine.
*
* However, whilst
*
* char spath[] = ...;
* char lpath[PATH_MAX];
* GetLongPathName(spath, lpath, PATH_MAX);
*
* will compile on WinXP, the resulting executable will
* fail on Win95. Thus, we need to check Kernel32.dll
* dynamically for GetLongPathNameA and if it is not
* found, revert to our own version that emulates it.
*
* kernel32.dll is loaded dynamically in the constructor. If the .dll is
* found not to contain GetLongPathNameA then it is unloaded immediately.
* Otherwise, the .dll is unloaded in the destructor
*/
class GetLongPath {
public:
GetLongPath();
~GetLongPath();
/** Wrapper for GetLongPathNameA.
* @returns the long path name associated with @c short_path.
*/
std::string const operator()(std::string const & short_path) const;
private:
std::string const system_wrapper(std::string const & short_path) const;
typedef DWORD (__stdcall * function_pointer)(LPCTSTR, LPTSTR, DWORD);
HMODULE kernel32_dll_;
function_pointer system_func_;
};
/** Win98 and earlier don't have SHGetFolderPath in shell32.dll.
* Microsoft recommend that we load shfolder.dll at run time and
* access the function through that.
*
* shfolder.dll is loaded dynamically in the constructor. If loading
* fails or if the .dll is found not to contain SHGetFolderPathA then
* the program exits immediately. Otherwise, the .dll is unloaded in
* the destructor
*
* The class makes SHGetFolderPath available through its function operator.
* It will work on all versions of Windows >= Win95.
*/
class GetFolderPath {
public:
GetFolderPath();
~GetFolderPath();
/** Wrapper for SHGetFolderPathA, returning
* the path asscociated with @c folder_id.
*/
std::string const operator()(int folder_id) const;
private:
typedef HRESULT (__stdcall * function_pointer)(HWND, int, HANDLE, DWORD, LPCSTR);
HMODULE folder_module_;
function_pointer folder_path_func_;
};
#endif // OS_WIN32_H