1
0
mirror of https://github.com/narzoul/DDrawCompat synced 2024-12-30 08:55:36 +01:00

Use window procedure override instead of CallWndRetProc

Fixes videos not displaying in The Guild Gold.
This commit is contained in:
narzoul 2020-08-18 10:52:53 +02:00
parent 799e9a95ae
commit a75739e5da
10 changed files with 196 additions and 111 deletions

View File

@ -1,3 +1,5 @@
#include <algorithm>
#include <Common/Log.h> #include <Common/Log.h>
#include <D3dDdi/DrawPrimitive.h> #include <D3dDdi/DrawPrimitive.h>
#include <D3dDdi/Device.h> #include <D3dDdi/Device.h>

View File

@ -220,7 +220,7 @@ namespace
GetWindowThreadProcessId(hwnd, &windowPid); GetWindowThreadProcessId(hwnd, &windowPid);
if (GetCurrentProcessId() != windowPid || if (GetCurrentProcessId() != windowPid ||
!IsWindowVisible(hwnd) || !IsWindowVisible(hwnd) ||
(GetWindowLongPtr(hwnd, GWL_EXSTYLE) & (WS_EX_LAYERED | WS_EX_TRANSPARENT))) (CALL_ORIG_FUNC(GetWindowLongA)(hwnd, GWL_EXSTYLE) & (WS_EX_LAYERED | WS_EX_TRANSPARENT)))
{ {
return TRUE; return TRUE;
} }
@ -323,7 +323,7 @@ namespace
} }
HWND hwnd = WindowFromDC(hdc); HWND hwnd = WindowFromDC(hdc);
if (!hwnd || hwnd == GetDesktopWindow() || (GetWindowLongPtr(hwnd, GWL_EXSTYLE) & WS_EX_LAYERED)) if (!hwnd || hwnd == GetDesktopWindow() || (CALL_ORIG_FUNC(GetWindowLongA)(hwnd, GWL_EXSTYLE) & WS_EX_LAYERED))
{ {
return 1; return 1;
} }

View File

@ -54,7 +54,7 @@ namespace Gdi
bool isDisplayDc(HDC dc) bool isDisplayDc(HDC dc)
{ {
return dc && OBJ_DC == GetObjectType(dc) && DT_RASDISPLAY == CALL_ORIG_FUNC(GetDeviceCaps)(dc, TECHNOLOGY) && return dc && OBJ_DC == GetObjectType(dc) && DT_RASDISPLAY == CALL_ORIG_FUNC(GetDeviceCaps)(dc, TECHNOLOGY) &&
!(GetWindowLongPtr(CALL_ORIG_FUNC(WindowFromDC)(dc), GWL_EXSTYLE) & WS_EX_LAYERED); !(CALL_ORIG_FUNC(GetWindowLongA)(CALL_ORIG_FUNC(WindowFromDC)(dc), GWL_EXSTYLE) & WS_EX_LAYERED);
} }
void redraw(HRGN rgn) void redraw(HRGN rgn)

View File

@ -1,18 +1,12 @@
#include <vector> #include <vector>
#include "Common/Hook.h" #include <Gdi/AccessGuard.h>
#include "Common/Log.h" #include <Gdi/Dc.h>
#include "D3dDdi/ScopedCriticalSection.h" #include <Gdi/PaintHandlers.h>
#include "DDraw/RealPrimarySurface.h" #include <Gdi/ScrollBar.h>
#include "Gdi/AccessGuard.h" #include <Gdi/ScrollFunctions.h>
#include "Gdi/Dc.h" #include <Gdi/TitleBar.h>
#include "Gdi/Gdi.h" #include <Gdi/VirtualScreen.h>
#include "Gdi/PaintHandlers.h"
#include "Gdi/ScrollBar.h"
#include "Gdi/ScrollFunctions.h"
#include "Gdi/TitleBar.h"
#include "Gdi/VirtualScreen.h"
#include "Gdi/Window.h"
std::ostream& operator<<(std::ostream& os, const MENUITEMINFOW& val) std::ostream& operator<<(std::ostream& os, const MENUITEMINFOW& val)
{ {
@ -91,7 +85,7 @@ namespace
isUnicode == g_currentUser32WndProc->isUnicode && isUnicode == g_currentUser32WndProc->isUnicode &&
!g_currentUser32WndProc->oldWndProc) !g_currentUser32WndProc->oldWndProc)
{ {
decltype(&GetWindowLong) getWindowLong = isUnicode ? GetWindowLongW : GetWindowLongA; decltype(&GetWindowLong) getWindowLong = isUnicode ? CALL_ORIG_FUNC(GetWindowLongW) : CALL_ORIG_FUNC(GetWindowLongA);
auto wndProc = reinterpret_cast<WNDPROC>(getWindowLong(hwnd, GWL_WNDPROC)); auto wndProc = reinterpret_cast<WNDPROC>(getWindowLong(hwnd, GWL_WNDPROC));
HMODULE wndProcModule = nullptr; HMODULE wndProcModule = nullptr;
GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
@ -403,7 +397,7 @@ namespace
return onPaint(hwnd, origWndProc); return onPaint(hwnd, origWndProc);
case WM_SETCURSOR: case WM_SETCURSOR:
if (GetWindowLong(hwnd, GWL_STYLE) & (SBS_SIZEBOX | SBS_SIZEGRIP)) if (CALL_ORIG_FUNC(GetWindowLongA)(hwnd, GWL_STYLE) & (SBS_SIZEBOX | SBS_SIZEGRIP))
{ {
SetCursor(LoadCursor(nullptr, IDC_SIZENWSE)); SetCursor(LoadCursor(nullptr, IDC_SIZENWSE));
} }
@ -492,29 +486,5 @@ namespace Gdi
HOOK_FUNCTION(user32, DefDlgProcW, defDlgProcW); HOOK_FUNCTION(user32, DefDlgProcW, defDlgProcW);
HOOK_FUNCTION(user32, SetMenuItemInfoW, setMenuItemInfoW); HOOK_FUNCTION(user32, SetMenuItemInfoW, setMenuItemInfoW);
} }
void onCreateWindow(HWND hwnd)
{
if (!IsWindowUnicode(hwnd))
{
return;
}
const auto wndProc = reinterpret_cast<WNDPROC>(GetWindowLongW(hwnd, GWL_WNDPROC));
User32WndProc* user32WndProc = nullptr;
if (getUser32WndProcW<menuWndProc>().oldWndProc == wndProc)
{
user32WndProc = &getUser32WndProcW<menuWndProc>();
}
else if (getUser32WndProcW<scrollBarWndProc>().oldWndProc == wndProc)
{
user32WndProc = &getUser32WndProcW<scrollBarWndProc>();
}
if (user32WndProc)
{
SetWindowLongW(hwnd, GWL_WNDPROC, reinterpret_cast<LONG>(user32WndProc->newWndProc));
}
}
} }
} }

View File

@ -5,6 +5,5 @@ namespace Gdi
namespace PaintHandlers namespace PaintHandlers
{ {
void installHooks(); void installHooks();
void onCreateWindow(HWND hwnd);
} }
} }

View File

@ -22,7 +22,7 @@ namespace Gdi
m_isLeftMouseButtonDown(false), m_cursorPos(), m_isLeftMouseButtonDown(false), m_cursorPos(),
m_horizontalSbi(), m_verticalSbi() m_horizontalSbi(), m_verticalSbi()
{ {
const LONG windowStyle = GetWindowLongPtr(hwnd, GWL_STYLE); const LONG windowStyle = CALL_ORIG_FUNC(GetWindowLongA)(hwnd, GWL_STYLE);
m_horizontalSbi.isVisible = 0 != (windowStyle & WS_HSCROLL); m_horizontalSbi.isVisible = 0 != (windowStyle & WS_HSCROLL);
m_verticalSbi.isVisible = 0 != (windowStyle & WS_VSCROLL); m_verticalSbi.isVisible = 0 != (windowStyle & WS_VSCROLL);

View File

@ -23,7 +23,7 @@ namespace Gdi
m_hwnd(hwnd), m_compatDc(compatDc), m_buttonWidth(0), m_buttonHeight(0), m_tbi(), m_hwnd(hwnd), m_compatDc(compatDc), m_buttonWidth(0), m_buttonHeight(0), m_tbi(),
m_windowRect(), m_hasIcon(false), m_hasTitleBar(false) m_windowRect(), m_hasIcon(false), m_hasTitleBar(false)
{ {
m_hasTitleBar = 0 != (GetWindowLongPtr(hwnd, GWL_STYLE) & WS_CAPTION); m_hasTitleBar = 0 != (CALL_ORIG_FUNC(GetWindowLongA)(hwnd, GWL_STYLE) & WS_CAPTION);
if (!m_hasTitleBar) if (!m_hasTitleBar)
{ {
return; return;

View File

@ -10,7 +10,6 @@
#include <Gdi/AccessGuard.h> #include <Gdi/AccessGuard.h>
#include <Gdi/Dc.h> #include <Gdi/Dc.h>
#include <Win32/DisplayMode.h> #include <Win32/DisplayMode.h>
#include <Gdi/PaintHandlers.h>
#include <Gdi/ScrollBar.h> #include <Gdi/ScrollBar.h>
#include <Gdi/ScrollFunctions.h> #include <Gdi/ScrollFunctions.h>
#include <Gdi/TitleBar.h> #include <Gdi/TitleBar.h>
@ -29,73 +28,119 @@ namespace
ChildWindowInfo() : rect{} {} ChildWindowInfo() : rect{} {}
}; };
std::multimap<DWORD, HHOOK> g_threadIdToHook; struct WindowProc
Compat::CriticalSection g_threadIdToHookCs; {
WNDPROC wndProcA;
WNDPROC wndProcW;
};
HWINEVENTHOOK g_objectCreateEventHook = nullptr; HWINEVENTHOOK g_objectCreateEventHook = nullptr;
HWINEVENTHOOK g_objectStateChangeEventHook = nullptr; HWINEVENTHOOK g_objectStateChangeEventHook = nullptr;
std::set<Gdi::WindowPosChangeNotifyFunc> g_windowPosChangeNotifyFuncs; std::set<Gdi::WindowPosChangeNotifyFunc> g_windowPosChangeNotifyFuncs;
Compat::CriticalSection g_windowProcCs;
std::map<HWND, WindowProc> g_windowProc;
WindowProc getWindowProc(HWND hwnd);
void onActivate(HWND hwnd); void onActivate(HWND hwnd);
void onCreateWindow(HWND hwnd); void onCreateWindow(HWND hwnd);
void onDestroyWindow(HWND hwnd); void onDestroyWindow(HWND hwnd);
void onWindowPosChanged(HWND hwnd); void onWindowPosChanged(HWND hwnd);
void onWindowPosChanging(HWND hwnd, const WINDOWPOS& wp); void onWindowPosChanging(HWND hwnd, const WINDOWPOS& wp);
void setWindowProc(HWND hwnd, WNDPROC wndProcA, WNDPROC wndProcW);
LRESULT CALLBACK callWndRetProc(int nCode, WPARAM wParam, LPARAM lParam) LRESULT CALLBACK ddcWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam,
decltype(&CallWindowProcA) callWindowProc, WNDPROC wndProc)
{ {
auto ret = reinterpret_cast<CWPRETSTRUCT*>(lParam); LOG_FUNC("ddcWindowProc", hwnd, Compat::logWm(uMsg), Compat::hex(wParam), Compat::hex(lParam));
LOG_FUNC("callWndRetProc", Compat::hex(nCode), Compat::hex(wParam), ret); LRESULT result = callWindowProc(wndProc, hwnd, uMsg, wParam, lParam);
if (HC_ACTION == nCode && !Gdi::Window::isPresentationWindow(ret->hwnd)) switch (uMsg)
{ {
switch (ret->message) case WM_ACTIVATE:
onActivate(hwnd);
break;
case WM_COMMAND:
{
auto notifCode = HIWORD(wParam);
if (lParam && (EN_HSCROLL == notifCode || EN_VSCROLL == notifCode))
{ {
case WM_ACTIVATE: Gdi::ScrollFunctions::updateScrolledWindow(reinterpret_cast<HWND>(lParam));
onActivate(ret->hwnd);
break;
case WM_COMMAND:
{
auto notifCode = HIWORD(ret->wParam);
if (ret->lParam && (EN_HSCROLL == notifCode || EN_VSCROLL == notifCode))
{
Gdi::ScrollFunctions::updateScrolledWindow(reinterpret_cast<HWND>(ret->lParam));
}
break;
}
case WM_DESTROY:
onDestroyWindow(ret->hwnd);
break;
case WM_STYLECHANGED:
if (GWL_EXSTYLE == ret->wParam)
{
onWindowPosChanged(ret->hwnd);
}
break;
case WM_WINDOWPOSCHANGED:
onWindowPosChanged(ret->hwnd);
break;
case WM_WINDOWPOSCHANGING:
onWindowPosChanging(ret->hwnd, *reinterpret_cast<WINDOWPOS*>(ret->lParam));
break;
} }
break;
} }
return LOG_RESULT(CallNextHookEx(nullptr, nCode, wParam, lParam)); case WM_NCDESTROY:
onDestroyWindow(hwnd);
break;
case WM_STYLECHANGED:
if (GWL_EXSTYLE == wParam)
{
onWindowPosChanged(hwnd);
}
break;
case WM_WINDOWPOSCHANGED:
onWindowPosChanged(hwnd);
break;
case WM_WINDOWPOSCHANGING:
onWindowPosChanging(hwnd, *reinterpret_cast<WINDOWPOS*>(lParam));
break;
}
return LOG_RESULT(result);
} }
void hookThread(DWORD threadId) LRESULT CALLBACK ddcWindowProcA(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{ {
Compat::ScopedCriticalSection lock(g_threadIdToHookCs); return ddcWindowProc(hwnd, uMsg, wParam, lParam, CallWindowProcA, getWindowProc(hwnd).wndProcA);
if (g_threadIdToHook.end() == g_threadIdToHook.find(threadId)) }
LRESULT CALLBACK ddcWindowProcW(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
return ddcWindowProc(hwnd, uMsg, wParam, lParam, CallWindowProcW, getWindowProc(hwnd).wndProcW);
}
LONG getWindowLong(HWND hWnd, int nIndex,
decltype(&GetWindowLongA) origGetWindowLong, WNDPROC(WindowProc::* wndProc))
{
if (GWL_WNDPROC == nIndex)
{ {
g_threadIdToHook.emplace(threadId, Compat::ScopedCriticalSection lock(g_windowProcCs);
SetWindowsHookEx(WH_CALLWNDPROCRET, callWndRetProc, nullptr, threadId)); auto it = g_windowProc.find(hWnd);
if (it != g_windowProc.end())
{
return reinterpret_cast<LONG>(it->second.*wndProc);
}
} }
return origGetWindowLong(hWnd, nIndex);
}
LONG WINAPI getWindowLongA(HWND hWnd, int nIndex)
{
LOG_FUNC("GetWindowLongA", hWnd, nIndex);
return LOG_RESULT(getWindowLong(hWnd, nIndex, CALL_ORIG_FUNC(GetWindowLongA), &WindowProc::wndProcA));
}
LONG WINAPI getWindowLongW(HWND hWnd, int nIndex)
{
LOG_FUNC("GetWindowLongW", hWnd, nIndex);
return LOG_RESULT(getWindowLong(hWnd, nIndex, CALL_ORIG_FUNC(GetWindowLongW), &WindowProc::wndProcW));
}
WindowProc getWindowProc(HWND hwnd)
{
Compat::ScopedCriticalSection lock(g_windowProcCs);
return g_windowProc[hwnd];
}
BOOL CALLBACK initChildWindow(HWND hwnd, LPARAM /*lParam*/)
{
onCreateWindow(hwnd);
return TRUE;
} }
BOOL CALLBACK initTopLevelWindow(HWND hwnd, LPARAM /*lParam*/) BOOL CALLBACK initTopLevelWindow(HWND hwnd, LPARAM /*lParam*/)
@ -105,6 +150,7 @@ namespace
if (GetCurrentProcessId() == windowPid) if (GetCurrentProcessId() == windowPid)
{ {
onCreateWindow(hwnd); onCreateWindow(hwnd);
EnumChildWindows(hwnd, &initChildWindow, 0);
if (8 == Win32::DisplayMode::getBpp()) if (8 == Win32::DisplayMode::getBpp())
{ {
PostMessage(hwnd, WM_PALETTECHANGED, reinterpret_cast<WPARAM>(GetDesktopWindow()), 0); PostMessage(hwnd, WM_PALETTECHANGED, reinterpret_cast<WPARAM>(GetDesktopWindow()), 0);
@ -196,8 +242,18 @@ namespace
return; return;
} }
hookThread(GetWindowThreadProcessId(hwnd, nullptr)); if (!Gdi::Window::isPresentationWindow(hwnd))
Gdi::PaintHandlers::onCreateWindow(hwnd); {
Compat::ScopedCriticalSection lock(g_windowProcCs);
if (g_windowProc.find(hwnd) == g_windowProc.end())
{
auto wndProcA = reinterpret_cast<WNDPROC>(CALL_ORIG_FUNC(GetWindowLongA)(hwnd, GWL_WNDPROC));
auto wndProcW = reinterpret_cast<WNDPROC>(CALL_ORIG_FUNC(GetWindowLongW)(hwnd, GWL_WNDPROC));
g_windowProc[hwnd] = { wndProcA, wndProcW };
setWindowProc(hwnd, ddcWindowProcA, ddcWindowProcW);
}
}
Gdi::Window::add(hwnd); Gdi::Window::add(hwnd);
} }
@ -205,16 +261,24 @@ namespace
{ {
Gdi::Window::remove(hwnd); Gdi::Window::remove(hwnd);
delete reinterpret_cast<ChildWindowInfo*>(RemoveProp(hwnd, PROP_DDRAWCOMPAT)); delete reinterpret_cast<ChildWindowInfo*>(RemoveProp(hwnd, PROP_DDRAWCOMPAT));
Compat::ScopedCriticalSection lock(g_windowProcCs);
auto it = g_windowProc.find(hwnd);
if (it != g_windowProc.end())
{
setWindowProc(hwnd, it->second.wndProcA, it->second.wndProcW);
g_windowProc.erase(it);
}
} }
void onWindowPosChanged(HWND hwnd) void onWindowPosChanged(HWND hwnd)
{ {
if (Gdi::MENU_ATOM == GetClassLongPtr(hwnd, GCW_ATOM)) if (Gdi::MENU_ATOM == GetClassLongPtr(hwnd, GCW_ATOM))
{ {
auto exStyle = GetWindowLongPtr(hwnd, GWL_EXSTYLE); auto exStyle = CALL_ORIG_FUNC(GetWindowLongA)(hwnd, GWL_EXSTYLE);
if (exStyle & WS_EX_LAYERED) if (exStyle & WS_EX_LAYERED)
{ {
SetWindowLongPtr(hwnd, GWL_EXSTYLE, exStyle & ~WS_EX_LAYERED); CALL_ORIG_FUNC(SetWindowLongA)(hwnd, GWL_EXSTYLE, exStyle & ~WS_EX_LAYERED);
return; return;
} }
} }
@ -271,6 +335,38 @@ namespace
} }
} }
LONG setWindowLong(HWND hWnd, int nIndex, LONG dwNewLong,
decltype(&SetWindowLongA) origSetWindowLong, WNDPROC(WindowProc::* wndProc))
{
if (GWL_WNDPROC == nIndex)
{
Compat::ScopedCriticalSection lock(g_windowProcCs);
auto it = g_windowProc.find(hWnd);
if (it != g_windowProc.end() && 0 != origSetWindowLong(hWnd, nIndex, dwNewLong))
{
WNDPROC oldWndProc = it->second.*wndProc;
it->second.wndProcA = reinterpret_cast<WNDPROC>(CALL_ORIG_FUNC(GetWindowLongA)(hWnd, GWL_WNDPROC));
it->second.wndProcW = reinterpret_cast<WNDPROC>(CALL_ORIG_FUNC(GetWindowLongW)(hWnd, GWL_WNDPROC));
WindowProc newWindowProc = { ddcWindowProcA, ddcWindowProcW };
origSetWindowLong(hWnd, GWL_WNDPROC, reinterpret_cast<LONG>(newWindowProc.*wndProc));
return reinterpret_cast<LONG>(oldWndProc);
}
}
return origSetWindowLong(hWnd, nIndex, dwNewLong);
}
LONG WINAPI setWindowLongA(HWND hWnd, int nIndex, LONG dwNewLong)
{
LOG_FUNC("SetWindowLongA", hWnd, nIndex, dwNewLong);
return LOG_RESULT(setWindowLong(hWnd, nIndex, dwNewLong, CALL_ORIG_FUNC(SetWindowLongA), &WindowProc::wndProcA));
}
LONG WINAPI setWindowLongW(HWND hWnd, int nIndex, LONG dwNewLong)
{
LOG_FUNC("SetWindowLongW", hWnd, nIndex, dwNewLong);
return LOG_RESULT(setWindowLong(hWnd, nIndex, dwNewLong, CALL_ORIG_FUNC(SetWindowLongW), &WindowProc::wndProcW));
}
BOOL WINAPI setWindowPos(HWND hWnd, HWND hWndInsertAfter, int X, int Y, int cx, int cy, UINT uFlags) BOOL WINAPI setWindowPos(HWND hWnd, HWND hWndInsertAfter, int X, int Y, int cx, int cy, UINT uFlags)
{ {
LOG_FUNC("SetWindowPos", hWnd, hWndInsertAfter, X, Y, cx, cy, Compat::hex(uFlags)); LOG_FUNC("SetWindowPos", hWnd, hWndInsertAfter, X, Y, cx, cy, Compat::hex(uFlags));
@ -290,6 +386,18 @@ namespace
delete reinterpret_cast<ChildWindowInfo*>(RemoveProp(hWnd, PROP_DDRAWCOMPAT)); delete reinterpret_cast<ChildWindowInfo*>(RemoveProp(hWnd, PROP_DDRAWCOMPAT));
return LOG_RESULT(result); return LOG_RESULT(result);
} }
void setWindowProc(HWND hwnd, WNDPROC wndProcA, WNDPROC wndProcW)
{
if (IsWindowUnicode(hwnd))
{
CALL_ORIG_FUNC(SetWindowLongW)(hwnd, GWL_WNDPROC, reinterpret_cast<LONG>(wndProcW));
}
else
{
CALL_ORIG_FUNC(SetWindowLongA)(hwnd, GWL_WNDPROC, reinterpret_cast<LONG>(wndProcA));
}
}
} }
namespace Gdi namespace Gdi
@ -298,20 +406,28 @@ namespace Gdi
{ {
void dllThreadDetach() void dllThreadDetach()
{ {
Compat::ScopedCriticalSection lock(g_threadIdToHookCs); auto threadId = GetCurrentThreadId();
const DWORD threadId = GetCurrentThreadId(); Compat::ScopedCriticalSection lock(g_windowProcCs);
for (auto threadIdToHook : g_threadIdToHook) auto it = g_windowProc.begin();
while (it != g_windowProc.end())
{ {
if (threadId == threadIdToHook.first) if (threadId == GetWindowThreadProcessId(it->first, nullptr))
{ {
UnhookWindowsHookEx(threadIdToHook.second); it = g_windowProc.erase(it);
}
else
{
++it;
} }
} }
g_threadIdToHook.erase(threadId);
} }
void installHooks() void installHooks()
{ {
HOOK_FUNCTION(user32, GetWindowLongA, getWindowLongA);
HOOK_FUNCTION(user32, GetWindowLongW, getWindowLongW);
HOOK_FUNCTION(user32, SetWindowLongA, setWindowLongA);
HOOK_FUNCTION(user32, SetWindowLongW, setWindowLongW);
HOOK_FUNCTION(user32, SetWindowPos, setWindowPos); HOOK_FUNCTION(user32, SetWindowPos, setWindowPos);
g_objectCreateEventHook = SetWinEventHook(EVENT_OBJECT_CREATE, EVENT_OBJECT_CREATE, g_objectCreateEventHook = SetWinEventHook(EVENT_OBJECT_CREATE, EVENT_OBJECT_CREATE,
@ -333,14 +449,12 @@ namespace Gdi
UnhookWinEvent(g_objectStateChangeEventHook); UnhookWinEvent(g_objectStateChangeEventHook);
UnhookWinEvent(g_objectCreateEventHook); UnhookWinEvent(g_objectCreateEventHook);
Compat::ScopedCriticalSection lock(g_windowProcCs);
for (const auto& windowProc : g_windowProc)
{ {
Compat::ScopedCriticalSection lock(g_threadIdToHookCs); setWindowProc(windowProc.first, windowProc.second.wndProcA, windowProc.second.wndProcW);
for (auto threadIdToHook : g_threadIdToHook)
{
UnhookWindowsHookEx(threadIdToHook.second);
}
g_threadIdToHook.clear();
} }
g_windowProc.clear();
} }
} }
} }

View File

@ -212,7 +212,7 @@ namespace Gdi
, m_windowRect{ 0, 0, 0, 0 } , m_windowRect{ 0, 0, 0, 0 }
, m_colorKey(CLR_INVALID) , m_colorKey(CLR_INVALID)
, m_alpha(255) , m_alpha(255)
, m_isLayered(GetWindowLong(m_hwnd, GWL_EXSTYLE)& WS_EX_LAYERED) , m_isLayered(CALL_ORIG_FUNC(GetWindowLongA)(m_hwnd, GWL_EXSTYLE)& WS_EX_LAYERED)
{ {
DWMNCRENDERINGPOLICY ncRenderingPolicy = DWMNCRP_DISABLED; DWMNCRENDERINGPOLICY ncRenderingPolicy = DWMNCRP_DISABLED;
DwmSetWindowAttribute(hwnd, DWMWA_NCRENDERING_POLICY, &ncRenderingPolicy, sizeof(ncRenderingPolicy)); DwmSetWindowAttribute(hwnd, DWMWA_NCRENDERING_POLICY, &ncRenderingPolicy, sizeof(ncRenderingPolicy));
@ -410,7 +410,7 @@ namespace Gdi
void Window::update() void Window::update()
{ {
D3dDdi::ScopedCriticalSection lock; D3dDdi::ScopedCriticalSection lock;
const bool isLayered = GetWindowLong(m_hwnd, GWL_EXSTYLE) & WS_EX_LAYERED; const bool isLayered = CALL_ORIG_FUNC(GetWindowLongA)(m_hwnd, GWL_EXSTYLE) & WS_EX_LAYERED;
if (isLayered != m_isLayered) if (isLayered != m_isLayered)
{ {
if (!isLayered) if (!isLayered)

View File

@ -106,8 +106,8 @@ std::ostream& operator<<(std::ostream& os, HWND hwnd)
<< name << name
<< Compat::hex(GetClassLong(hwnd, GCL_STYLE)) << Compat::hex(GetClassLong(hwnd, GCL_STYLE))
<< rect << rect
<< Compat::hex(GetWindowLong(hwnd, GWL_STYLE)) << Compat::hex(CALL_ORIG_FUNC(GetWindowLongA)(hwnd, GWL_STYLE))
<< Compat::hex(GetWindowLong(hwnd, GWL_EXSTYLE)); << Compat::hex(CALL_ORIG_FUNC(GetWindowLongA)(hwnd, GWL_EXSTYLE));
} }
std::ostream& operator<<(std::ostream& os, const MEMORYSTATUS& ms) std::ostream& operator<<(std::ostream& os, const MEMORYSTATUS& ms)