mirror of
https://github.com/narzoul/DDrawCompat
synced 2024-12-30 08:55:36 +01:00
Fixed occasional deadlock during Sim City 4 startup
This commit is contained in:
parent
8f8eca66d3
commit
87a09b12b9
@ -1,8 +1,10 @@
|
|||||||
#include <Common/Hook.h>
|
#include <Common/Hook.h>
|
||||||
#include <Common/Log.h>
|
#include <Common/Log.h>
|
||||||
|
#include <D3dDdi/ScopedCriticalSection.h>
|
||||||
#include <Dll/Dll.h>
|
#include <Dll/Dll.h>
|
||||||
#include <Gdi/PresentationWindow.h>
|
#include <Gdi/PresentationWindow.h>
|
||||||
#include <Gdi/WinProc.h>
|
#include <Gdi/WinProc.h>
|
||||||
|
#include <Win32/DisplayMode.h>
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
@ -15,6 +17,28 @@ namespace
|
|||||||
HWND g_messageWindow = nullptr;
|
HWND g_messageWindow = nullptr;
|
||||||
bool g_isThreadReady = false;
|
bool g_isThreadReady = false;
|
||||||
|
|
||||||
|
BOOL CALLBACK initChildWindow(HWND hwnd, LPARAM /*lParam*/)
|
||||||
|
{
|
||||||
|
Gdi::WinProc::onCreateWindow(hwnd);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL CALLBACK initTopLevelWindow(HWND hwnd, LPARAM /*lParam*/)
|
||||||
|
{
|
||||||
|
DWORD windowPid = 0;
|
||||||
|
GetWindowThreadProcessId(hwnd, &windowPid);
|
||||||
|
if (GetCurrentProcessId() == windowPid)
|
||||||
|
{
|
||||||
|
Gdi::WinProc::onCreateWindow(hwnd);
|
||||||
|
EnumChildWindows(hwnd, &initChildWindow, 0);
|
||||||
|
if (8 == Win32::DisplayMode::getBpp())
|
||||||
|
{
|
||||||
|
PostMessage(hwnd, WM_PALETTECHANGED, reinterpret_cast<WPARAM>(GetDesktopWindow()), 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
LRESULT CALLBACK messageWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
LRESULT CALLBACK messageWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||||
{
|
{
|
||||||
LOG_FUNC("messageWindowProc", Compat::WindowMessageStruct(hwnd, uMsg, wParam, lParam));
|
LOG_FUNC("messageWindowProc", Compat::WindowMessageStruct(hwnd, uMsg, wParam, lParam));
|
||||||
@ -98,8 +122,13 @@ namespace
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
g_isThreadReady = true;
|
{
|
||||||
Gdi::WinProc::installHooks();
|
D3dDdi::ScopedCriticalSection lock;
|
||||||
|
Gdi::WinProc::installHooks();
|
||||||
|
g_isThreadReady = true;
|
||||||
|
EnumWindows(initTopLevelWindow, 0);
|
||||||
|
}
|
||||||
|
|
||||||
Compat::closeDbgEng();
|
Compat::closeDbgEng();
|
||||||
|
|
||||||
MSG msg = {};
|
MSG msg = {};
|
||||||
@ -132,7 +161,7 @@ namespace Gdi
|
|||||||
|
|
||||||
void destroy(HWND hwnd)
|
void destroy(HWND hwnd)
|
||||||
{
|
{
|
||||||
sendMessageBlocking(hwnd, WM_CLOSE, 0, 0);
|
PostMessage(hwnd, WM_CLOSE, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void installHooks()
|
void installHooks()
|
||||||
|
@ -15,7 +15,6 @@
|
|||||||
#include <Gdi/TitleBar.h>
|
#include <Gdi/TitleBar.h>
|
||||||
#include <Gdi/Window.h>
|
#include <Gdi/Window.h>
|
||||||
#include <Gdi/WinProc.h>
|
#include <Gdi/WinProc.h>
|
||||||
#include <Win32/DisplayMode.h>
|
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
@ -25,7 +24,6 @@ namespace
|
|||||||
WNDPROC wndProcW;
|
WNDPROC wndProcW;
|
||||||
};
|
};
|
||||||
|
|
||||||
bool g_isInitialized = false;
|
|
||||||
std::set<Gdi::WindowPosChangeNotifyFunc> g_windowPosChangeNotifyFuncs;
|
std::set<Gdi::WindowPosChangeNotifyFunc> g_windowPosChangeNotifyFuncs;
|
||||||
|
|
||||||
Compat::SrwLock g_windowProcSrwLock;
|
Compat::SrwLock g_windowProcSrwLock;
|
||||||
@ -134,28 +132,6 @@ namespace
|
|||||||
return g_windowProc[hwnd];
|
return g_windowProc[hwnd];
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL CALLBACK initChildWindow(HWND hwnd, LPARAM /*lParam*/)
|
|
||||||
{
|
|
||||||
onCreateWindow(hwnd);
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOL CALLBACK initTopLevelWindow(HWND hwnd, LPARAM /*lParam*/)
|
|
||||||
{
|
|
||||||
DWORD windowPid = 0;
|
|
||||||
GetWindowThreadProcessId(hwnd, &windowPid);
|
|
||||||
if (GetCurrentProcessId() == windowPid)
|
|
||||||
{
|
|
||||||
onCreateWindow(hwnd);
|
|
||||||
EnumChildWindows(hwnd, &initChildWindow, 0);
|
|
||||||
if (8 == Win32::DisplayMode::getBpp())
|
|
||||||
{
|
|
||||||
PostMessage(hwnd, WM_PALETTECHANGED, reinterpret_cast<WPARAM>(GetDesktopWindow()), 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isTopLevelWindow(HWND hwnd)
|
bool isTopLevelWindow(HWND hwnd)
|
||||||
{
|
{
|
||||||
return GetDesktopWindow() == GetAncestor(hwnd, GA_PARENT);
|
return GetDesktopWindow() == GetAncestor(hwnd, GA_PARENT);
|
||||||
@ -463,16 +439,11 @@ namespace Gdi
|
|||||||
Dll::g_currentModule, &objectCreateEvent, GetCurrentProcessId(), 0, WINEVENT_INCONTEXT);
|
Dll::g_currentModule, &objectCreateEvent, GetCurrentProcessId(), 0, WINEVENT_INCONTEXT);
|
||||||
SetWinEventHook(EVENT_OBJECT_STATECHANGE, EVENT_OBJECT_STATECHANGE,
|
SetWinEventHook(EVENT_OBJECT_STATECHANGE, EVENT_OBJECT_STATECHANGE,
|
||||||
Dll::g_currentModule, &objectStateChangeEvent, GetCurrentProcessId(), 0, WINEVENT_INCONTEXT);
|
Dll::g_currentModule, &objectStateChangeEvent, GetCurrentProcessId(), 0, WINEVENT_INCONTEXT);
|
||||||
|
|
||||||
g_isInitialized = true;
|
|
||||||
|
|
||||||
EnumWindows(initTopLevelWindow, 0);
|
|
||||||
Gdi::Window::updateAll();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void onCreateWindow(HWND hwnd)
|
void onCreateWindow(HWND hwnd)
|
||||||
{
|
{
|
||||||
if (g_isInitialized)
|
if (PresentationWindow::isThreadReady())
|
||||||
{
|
{
|
||||||
::onCreateWindow(hwnd);
|
::onCreateWindow(hwnd);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user