1
0
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:
narzoul 2021-04-08 16:53:41 +02:00
parent 8f8eca66d3
commit 87a09b12b9
2 changed files with 33 additions and 33 deletions

View File

@ -1,8 +1,10 @@
#include <Common/Hook.h>
#include <Common/Log.h>
#include <D3dDdi/ScopedCriticalSection.h>
#include <Dll/Dll.h>
#include <Gdi/PresentationWindow.h>
#include <Gdi/WinProc.h>
#include <Win32/DisplayMode.h>
namespace
{
@ -15,6 +17,28 @@ namespace
HWND g_messageWindow = nullptr;
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)
{
LOG_FUNC("messageWindowProc", Compat::WindowMessageStruct(hwnd, uMsg, wParam, lParam));
@ -98,8 +122,13 @@ namespace
return 0;
}
g_isThreadReady = true;
Gdi::WinProc::installHooks();
{
D3dDdi::ScopedCriticalSection lock;
Gdi::WinProc::installHooks();
g_isThreadReady = true;
EnumWindows(initTopLevelWindow, 0);
}
Compat::closeDbgEng();
MSG msg = {};
@ -132,7 +161,7 @@ namespace Gdi
void destroy(HWND hwnd)
{
sendMessageBlocking(hwnd, WM_CLOSE, 0, 0);
PostMessage(hwnd, WM_CLOSE, 0, 0);
}
void installHooks()

View File

@ -15,7 +15,6 @@
#include <Gdi/TitleBar.h>
#include <Gdi/Window.h>
#include <Gdi/WinProc.h>
#include <Win32/DisplayMode.h>
namespace
{
@ -25,7 +24,6 @@ namespace
WNDPROC wndProcW;
};
bool g_isInitialized = false;
std::set<Gdi::WindowPosChangeNotifyFunc> g_windowPosChangeNotifyFuncs;
Compat::SrwLock g_windowProcSrwLock;
@ -134,28 +132,6 @@ namespace
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)
{
return GetDesktopWindow() == GetAncestor(hwnd, GA_PARENT);
@ -463,16 +439,11 @@ namespace Gdi
Dll::g_currentModule, &objectCreateEvent, GetCurrentProcessId(), 0, WINEVENT_INCONTEXT);
SetWinEventHook(EVENT_OBJECT_STATECHANGE, EVENT_OBJECT_STATECHANGE,
Dll::g_currentModule, &objectStateChangeEvent, GetCurrentProcessId(), 0, WINEVENT_INCONTEXT);
g_isInitialized = true;
EnumWindows(initTopLevelWindow, 0);
Gdi::Window::updateAll();
}
void onCreateWindow(HWND hwnd)
{
if (g_isInitialized)
if (PresentationWindow::isThreadReady())
{
::onCreateWindow(hwnd);
}