diff --git a/DDrawCompat/DDrawCompat.vcxproj b/DDrawCompat/DDrawCompat.vcxproj
index 6f3dbad..d31e5ca 100644
--- a/DDrawCompat/DDrawCompat.vcxproj
+++ b/DDrawCompat/DDrawCompat.vcxproj
@@ -220,6 +220,7 @@
+
@@ -294,6 +295,7 @@
+
diff --git a/DDrawCompat/DDrawCompat.vcxproj.filters b/DDrawCompat/DDrawCompat.vcxproj.filters
index ac12b5d..c6da761 100644
--- a/DDrawCompat/DDrawCompat.vcxproj.filters
+++ b/DDrawCompat/DDrawCompat.vcxproj.filters
@@ -402,6 +402,9 @@
Header Files\Gdi
+
+ Header Files\Gdi
+
@@ -620,5 +623,8 @@
Source Files\Gdi
+
+ Source Files\Gdi
+
\ No newline at end of file
diff --git a/DDrawCompat/Gdi/DcFunctions.cpp b/DDrawCompat/Gdi/DcFunctions.cpp
index 98f646c..6756958 100644
--- a/DDrawCompat/Gdi/DcFunctions.cpp
+++ b/DDrawCompat/Gdi/DcFunctions.cpp
@@ -9,13 +9,12 @@
#include
#include
#include
-#include
#include
namespace
{
std::unordered_map g_funcNames;
- thread_local bool g_redirectToDib = true;
+ thread_local UINT g_disableDibRedirection = 0;
#define CREATE_DC_FUNC_ATTRIBUTE(attribute) \
template \
@@ -175,7 +174,7 @@ namespace
HBITMAP WINAPI createCompatibleBitmap(HDC hdc, int cx, int cy)
{
LOG_FUNC("CreateCompatibleBitmap", hdc, cx, cy);
- if (g_redirectToDib && Gdi::isDisplayDc(hdc))
+ if (!g_disableDibRedirection && Gdi::isDisplayDc(hdc))
{
const bool useDefaultPalette = false;
return LOG_RESULT(Gdi::VirtualScreen::createOffScreenDib(cx, cy, useDefaultPalette));
@@ -188,7 +187,7 @@ namespace
{
LOG_FUNC("CreateDIBitmap", hdc, lpbmih, fdwInit, lpbInit, lpbmi, fuUsage);
const DWORD CBM_CREATDIB = 2;
- if (g_redirectToDib && !(fdwInit & CBM_CREATDIB) && lpbmih && Gdi::isDisplayDc(hdc))
+ if (!g_disableDibRedirection && !(fdwInit & CBM_CREATDIB) && lpbmih && Gdi::isDisplayDc(hdc))
{
const bool useDefaultPalette = false;
HBITMAP bitmap = Gdi::VirtualScreen::createOffScreenDib(
@@ -205,7 +204,7 @@ namespace
HBITMAP WINAPI createDiscardableBitmap(HDC hdc, int nWidth, int nHeight)
{
LOG_FUNC("CreateDiscardableBitmap", hdc, nWidth, nHeight);
- if (g_redirectToDib && Gdi::isDisplayDc(hdc))
+ if (!g_disableDibRedirection && Gdi::isDisplayDc(hdc))
{
const bool useDefaultPalette = false;
return LOG_RESULT(Gdi::VirtualScreen::createOffScreenDib(nWidth, nHeight, useDefaultPalette));
@@ -257,114 +256,6 @@ namespace
moduleName, funcName, getCompatGdiTextDcFuncPtr(origFunc));
}
- template
- ATOM WINAPI registerClass(const WndClass* lpWndClass, ATOM(WINAPI* origRegisterClass)(const WndClass*),
- ATOM(WINAPI* registerClassEx)(const WndClassEx*))
- {
- if (!lpWndClass)
- {
- return origRegisterClass(lpWndClass);
- }
-
- WndClassEx wc = {};
- wc.cbSize = sizeof(wc);
- memcpy(&wc.style, &lpWndClass->style, sizeof(WndClass));
- return registerClassEx(&wc);
- }
-
- template
- ATOM registerClassEx(const WndClassEx* lpWndClassEx,
- ATOM(WINAPI* origRegisterClassEx)(const WndClassEx*),
- decltype(&SetClassLong) origSetClassLong,
- decltype(&DefWindowProc) origDefWindowProc)
- {
- if (!lpWndClassEx || (!lpWndClassEx->hIcon && !lpWndClassEx->hIconSm))
- {
- return origRegisterClassEx(lpWndClassEx);
- }
-
- WndClassEx wc = *lpWndClassEx;
- wc.lpfnWndProc = origDefWindowProc;
- wc.hIcon = nullptr;
- wc.hIconSm = nullptr;
-
- ATOM atom = origRegisterClassEx(&wc);
- if (atom)
- {
- HWND hwnd = CreateWindow(reinterpret_cast(atom), "", 0, 0, 0, 0, 0, nullptr, nullptr, nullptr, nullptr);
- if (!hwnd)
- {
- UnregisterClass(reinterpret_cast(atom), GetModuleHandle(nullptr));
- return origRegisterClassEx(lpWndClassEx);
- }
-
- if (lpWndClassEx->hIcon)
- {
- SetClassLong(hwnd, GCL_HICON, reinterpret_cast(lpWndClassEx->hIcon));
- }
- if (lpWndClassEx->hIconSm)
- {
- SetClassLong(hwnd, GCL_HICONSM, reinterpret_cast(lpWndClassEx->hIconSm));
- }
-
- origSetClassLong(hwnd, GCL_WNDPROC, reinterpret_cast(lpWndClassEx->lpfnWndProc));
- SetWindowLong(hwnd, GWL_WNDPROC, reinterpret_cast(CALL_ORIG_FUNC(DefWindowProcA)));
- DestroyWindow(hwnd);
- }
-
- return atom;
- }
-
- ATOM WINAPI registerClassA(const WNDCLASSA* lpWndClass)
- {
- LOG_FUNC("RegisterClassA", lpWndClass);
- return LOG_RESULT(registerClass(lpWndClass, CALL_ORIG_FUNC(RegisterClassA), RegisterClassExA));
- }
-
- ATOM WINAPI registerClassW(const WNDCLASSW* lpWndClass)
- {
- LOG_FUNC("RegisterClassW", lpWndClass);
- return LOG_RESULT(registerClass(lpWndClass, CALL_ORIG_FUNC(RegisterClassW), RegisterClassExW));
- }
-
- ATOM WINAPI registerClassExA(const WNDCLASSEXA* lpWndClassEx)
- {
- LOG_FUNC("RegisterClassExA", lpWndClassEx);
- return LOG_RESULT(registerClassEx(lpWndClassEx, CALL_ORIG_FUNC(RegisterClassExA), CALL_ORIG_FUNC(SetClassLongA),
- CALL_ORIG_FUNC(DefWindowProcA)));
- }
-
- ATOM WINAPI registerClassExW(const WNDCLASSEXW* lpWndClassEx)
- {
- LOG_FUNC("RegisterClassExW", lpWndClassEx);
- return LOG_RESULT(registerClassEx(lpWndClassEx, CALL_ORIG_FUNC(RegisterClassExW), CALL_ORIG_FUNC(SetClassLongW),
- CALL_ORIG_FUNC(DefWindowProcW)));
- }
-
- DWORD WINAPI setClassLong(HWND hWnd, int nIndex, LONG dwNewLong, decltype(&SetClassLong) origSetClassLong)
- {
- if (GCL_HICON == nIndex || GCL_HICONSM == nIndex)
- {
- g_redirectToDib = false;
- DWORD result = origSetClassLong(hWnd, nIndex, dwNewLong);
- g_redirectToDib = true;
- return result;
- }
- return origSetClassLong(hWnd, nIndex, dwNewLong);
- }
-
- DWORD WINAPI setClassLongA(HWND hWnd, int nIndex, LONG dwNewLong)
- {
- LOG_FUNC("setClassLongA", hWnd, nIndex, dwNewLong);
- return LOG_RESULT(setClassLong(hWnd, nIndex, dwNewLong, CALL_ORIG_FUNC(SetClassLongA)));
- }
-
- DWORD WINAPI setClassLongW(HWND hWnd, int nIndex, LONG dwNewLong)
- {
- LOG_FUNC("setClassLongW", hWnd, nIndex, dwNewLong);
- return LOG_RESULT(setClassLong(hWnd, nIndex, dwNewLong, CALL_ORIG_FUNC(SetClassLongW)));
- }
-
HWND WINAPI windowFromDc(HDC dc)
{
return CALL_ORIG_FUNC(WindowFromDC)(Gdi::Dc::getOrigDc(dc));
@@ -382,6 +273,11 @@ namespace Gdi
{
namespace DcFunctions
{
+ void disableDibRedirection(bool disable)
+ {
+ g_disableDibRedirection += disable ? 1 : -1;
+ }
+
void installHooks()
{
// Bitmap functions
@@ -469,14 +365,6 @@ namespace Gdi
// Undocumented functions
HOOK_GDI_DC_FUNCTION(gdi32, GdiDrawStream);
HOOK_GDI_DC_FUNCTION(gdi32, PolyPatBlt);
-
- // Window class functions
- HOOK_FUNCTION(user32, RegisterClassA, registerClassA);
- HOOK_FUNCTION(user32, RegisterClassW, registerClassW);
- HOOK_FUNCTION(user32, RegisterClassExA, registerClassExA);
- HOOK_FUNCTION(user32, RegisterClassExW, registerClassExW);
- HOOK_FUNCTION(user32, SetClassLongA, setClassLongA);
- HOOK_FUNCTION(user32, SetClassLongW, setClassLongW);
}
}
}
diff --git a/DDrawCompat/Gdi/DcFunctions.h b/DDrawCompat/Gdi/DcFunctions.h
index 3ae80af..8c21c0d 100644
--- a/DDrawCompat/Gdi/DcFunctions.h
+++ b/DDrawCompat/Gdi/DcFunctions.h
@@ -4,6 +4,8 @@ namespace Gdi
{
namespace DcFunctions
{
+ void disableDibRedirection(bool disable);
+
void installHooks();
}
}
diff --git a/DDrawCompat/Gdi/Gdi.cpp b/DDrawCompat/Gdi/Gdi.cpp
index b9a308a..d051f66 100644
--- a/DDrawCompat/Gdi/Gdi.cpp
+++ b/DDrawCompat/Gdi/Gdi.cpp
@@ -5,6 +5,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -40,6 +41,7 @@ namespace Gdi
DisableProcessWindowsGhosting();
DcFunctions::installHooks();
+ Icon::installHooks();
Metrics::installHooks();
Palette::installHooks();
PresentationWindow::installHooks();
diff --git a/DDrawCompat/Gdi/Icon.cpp b/DDrawCompat/Gdi/Icon.cpp
new file mode 100644
index 0000000..8bf5331
--- /dev/null
+++ b/DDrawCompat/Gdi/Icon.cpp
@@ -0,0 +1,165 @@
+#include