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

Reply via email to