mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-10 23:02:08 +00:00
- Made a few Win32 calls optional in order to restore capatibility with Windows NT 4.0 (not that anyone is using NT 4, but it was a trivial fix)
This commit is contained in:
parent
920a4fbf45
commit
75471df787
4 changed files with 54 additions and 17 deletions
|
@ -22,6 +22,8 @@
|
|||
|
||||
#if defined(_WIN32)
|
||||
|
||||
#include "i_system.h"
|
||||
|
||||
typedef HRESULT (WINAPI *GKFP)(REFKNOWNFOLDERID, DWORD, HANDLE, PWSTR *);
|
||||
|
||||
//===========================================================================
|
||||
|
@ -73,18 +75,7 @@ bool UseKnownFolders()
|
|||
|
||||
bool GetKnownFolder(int shell_folder, REFKNOWNFOLDERID known_folder, bool create, FString &path)
|
||||
{
|
||||
static GKFP SHGetKnownFolderPath = NULL;
|
||||
static bool tested = false;
|
||||
|
||||
if (!tested)
|
||||
{
|
||||
tested = true;
|
||||
HMODULE shell32 = GetModuleHandle("shell32.dll");
|
||||
if (shell32 != NULL)
|
||||
{
|
||||
SHGetKnownFolderPath = (GKFP)GetProcAddress(shell32, "SHGetKnownFolderPath");
|
||||
}
|
||||
}
|
||||
static TOptWin32Proc<GKFP> SHGetKnownFolderPath("shell32.dll", "SHGetKnownFolderPath");
|
||||
|
||||
char pathstr[MAX_PATH];
|
||||
|
||||
|
@ -92,6 +83,13 @@ bool GetKnownFolder(int shell_folder, REFKNOWNFOLDERID known_folder, bool create
|
|||
// new to Vista, hence the reason we support both.
|
||||
if (SHGetKnownFolderPath == NULL)
|
||||
{
|
||||
static TOptWin32Proc<HRESULT(*)(HWND, int, HANDLE, DWORD, LPTSTR)>
|
||||
SHGetFolderPathA("shell32.dll", "SHGetFolderPathA");
|
||||
|
||||
// NT4 doesn't even have this function.
|
||||
if (SHGetFolderPathA == NULL)
|
||||
return false;
|
||||
|
||||
if (shell_folder < 0)
|
||||
{ // Not supported by SHGetFolderPath
|
||||
return false;
|
||||
|
@ -100,7 +98,7 @@ bool GetKnownFolder(int shell_folder, REFKNOWNFOLDERID known_folder, bool create
|
|||
{
|
||||
shell_folder |= CSIDL_FLAG_CREATE;
|
||||
}
|
||||
if (FAILED(SHGetFolderPathA(NULL, shell_folder, NULL, 0, pathstr)))
|
||||
if (FAILED(SHGetFolderPathA.Call(NULL, shell_folder, NULL, 0, pathstr)))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
@ -110,7 +108,7 @@ bool GetKnownFolder(int shell_folder, REFKNOWNFOLDERID known_folder, bool create
|
|||
else
|
||||
{
|
||||
PWSTR wpath;
|
||||
if (FAILED(SHGetKnownFolderPath(known_folder, create ? KF_FLAG_CREATE : 0, NULL, &wpath)))
|
||||
if (FAILED(SHGetKnownFolderPath.Call(known_folder, create ? KF_FLAG_CREATE : 0, NULL, &wpath)))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -1600,13 +1600,20 @@ unsigned int I_MakeRNGSeed()
|
|||
|
||||
FString I_GetLongPathName(FString shortpath)
|
||||
{
|
||||
DWORD buffsize = GetLongPathName(shortpath.GetChars(), NULL, 0);
|
||||
static TOptWin32Proc<DWORD (WINAPI*)(LPCTSTR, LPTSTR, DWORD)>
|
||||
GetLongPathName("kernel32.dll", "GetLongPathNameW", "GetLongPathNameA");
|
||||
|
||||
// Doesn't exist on NT4
|
||||
if (GetLongPathName == NULL)
|
||||
return shortpath;
|
||||
|
||||
DWORD buffsize = GetLongPathName.Call(shortpath.GetChars(), NULL, 0);
|
||||
if (buffsize == 0)
|
||||
{ // nothing to change (it doesn't exist, maybe?)
|
||||
return shortpath;
|
||||
}
|
||||
TCHAR *buff = new TCHAR[buffsize];
|
||||
DWORD buffsize2 = GetLongPathName(shortpath.GetChars(), buff, buffsize);
|
||||
DWORD buffsize2 = GetLongPathName.Call(shortpath.GetChars(), buff, buffsize);
|
||||
if (buffsize2 >= buffsize)
|
||||
{ // Failure! Just return the short path
|
||||
delete[] buff;
|
||||
|
|
|
@ -51,6 +51,35 @@ typedef enum {
|
|||
|
||||
extern os_t OSPlatform;
|
||||
|
||||
// Helper template so that we can access newer Win32 functions with a single static
|
||||
// variable declaration. If this were C++11 it could be totally transparent.
|
||||
template<typename Proto>
|
||||
class TOptWin32Proc
|
||||
{
|
||||
static Proto GetOptionalWin32Proc(const char* module, const char* function, const char* alt)
|
||||
{
|
||||
HMODULE hmodule = GetModuleHandle(module);
|
||||
if (hmodule == NULL)
|
||||
return NULL;
|
||||
|
||||
Proto ret = (Proto)GetProcAddress(hmodule, function);
|
||||
if(ret != NULL || alt == NULL)
|
||||
return ret;
|
||||
|
||||
// Lookup alternate function name (ex. ProcW -> ProcA)
|
||||
return (Proto)GetProcAddress(hmodule, alt);
|
||||
}
|
||||
|
||||
public:
|
||||
const Proto Call;
|
||||
|
||||
TOptWin32Proc(const char* module, const char* function, const char* alt=NULL)
|
||||
: Call(GetOptionalWin32Proc(module, function, alt)) {}
|
||||
|
||||
// Wrapper object can be tested against NULL, but not directly called.
|
||||
operator const void*() const { return Call; }
|
||||
};
|
||||
|
||||
// Called by DoomMain.
|
||||
void I_Init (void);
|
||||
|
||||
|
|
|
@ -414,7 +414,10 @@ void Win32Video::DumpAdapters()
|
|||
HMONITOR hm = D3D->GetAdapterMonitor(i);
|
||||
MONITORINFOEX mi;
|
||||
mi.cbSize = sizeof(mi);
|
||||
if (GetMonitorInfo(hm, &mi))
|
||||
|
||||
TOptWin32Proc<BOOL(WINAPI*)(HMONITOR, LPMONITORINFO)> GetMonitorInfo("user32.dll", "GetMonitorInfoW");
|
||||
assert(GetMonitorInfo != NULL); // Missing in NT4, but so is D3D
|
||||
if (GetMonitorInfo.Call(hm, &mi))
|
||||
{
|
||||
mysnprintf(moreinfo, countof(moreinfo), " [%ldx%ld @ (%ld,%ld)]%s",
|
||||
mi.rcMonitor.right - mi.rcMonitor.left,
|
||||
|
|
Loading…
Reference in a new issue