mirror of
https://github.com/narzoul/DDrawCompat
synced 2024-12-30 08:55:36 +01:00
Moved presentation windows to dedicated thread
This commit is contained in:
parent
906ef5ebe2
commit
12e78aab84
@ -51,6 +51,7 @@ namespace Gdi
|
|||||||
DcFunctions::installHooks();
|
DcFunctions::installHooks();
|
||||||
PaintHandlers::installHooks();
|
PaintHandlers::installHooks();
|
||||||
ScrollFunctions::installHooks();
|
ScrollFunctions::installHooks();
|
||||||
|
Window::installHooks();
|
||||||
WinProc::installHooks();
|
WinProc::installHooks();
|
||||||
Caret::installHooks();
|
Caret::installHooks();
|
||||||
}
|
}
|
||||||
@ -93,6 +94,7 @@ namespace Gdi
|
|||||||
{
|
{
|
||||||
Caret::uninstallHooks();
|
Caret::uninstallHooks();
|
||||||
WinProc::uninstallHooks();
|
WinProc::uninstallHooks();
|
||||||
|
Window::uninstallHooks();
|
||||||
Dc::dllProcessDetach();
|
Dc::dllProcessDetach();
|
||||||
DcCache::dllProcessDetach();
|
DcCache::dllProcessDetach();
|
||||||
ReleaseDC(nullptr, g_screenDc);
|
ReleaseDC(nullptr, g_screenDc);
|
||||||
|
@ -91,16 +91,9 @@ namespace
|
|||||||
{
|
{
|
||||||
DWORD windowPid = 0;
|
DWORD windowPid = 0;
|
||||||
GetWindowThreadProcessId(hwnd, &windowPid);
|
GetWindowThreadProcessId(hwnd, &windowPid);
|
||||||
if (GetCurrentProcessId() != windowPid)
|
if (GetCurrentProcessId() == windowPid)
|
||||||
{
|
{
|
||||||
return TRUE;
|
onCreateWindow(hwnd);
|
||||||
}
|
|
||||||
|
|
||||||
onCreateWindow(hwnd);
|
|
||||||
if (!(GetWindowLongPtr(hwnd, GWL_EXSTYLE) & WS_EX_LAYERED))
|
|
||||||
{
|
|
||||||
RedrawWindow(hwnd, nullptr, nullptr,
|
|
||||||
RDW_INVALIDATE | RDW_ERASE | RDW_FRAME | RDW_ALLCHILDREN | RDW_UPDATENOW);
|
|
||||||
}
|
}
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
#include "Common/Hook.h"
|
#include "Common/Hook.h"
|
||||||
|
#include "Common/Log.h"
|
||||||
#include "DDraw/ScopedThreadLock.h"
|
#include "DDraw/ScopedThreadLock.h"
|
||||||
#include "Gdi/Gdi.h"
|
#include "Gdi/Gdi.h"
|
||||||
#include "Gdi/Window.h"
|
#include "Gdi/Window.h"
|
||||||
@ -7,8 +8,12 @@ extern "C" IMAGE_DOS_HEADER __ImageBase;
|
|||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
ATOM registerPresentationWindowClass();
|
const UINT WM_CREATEPRESENTATIONWINDOW = WM_USER;
|
||||||
|
|
||||||
|
HANDLE g_presentationWindowThread = nullptr;
|
||||||
|
DWORD g_presentationWindowThreadId = 0;
|
||||||
|
HWND g_messageWindow = nullptr;
|
||||||
|
|
||||||
ATOM getComboLBoxAtom()
|
ATOM getComboLBoxAtom()
|
||||||
{
|
{
|
||||||
WNDCLASS wc = {};
|
WNDCLASS wc = {};
|
||||||
@ -16,24 +21,65 @@ namespace
|
|||||||
return comboLBoxAtom;
|
return comboLBoxAtom;
|
||||||
}
|
}
|
||||||
|
|
||||||
ATOM getPresentationWindowClassAtom()
|
LRESULT CALLBACK messageWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||||
{
|
{
|
||||||
static ATOM atom = registerPresentationWindowClass();
|
LOG_FUNC("messageWindowProc", hwnd, Compat::hex(uMsg), Compat::hex(wParam), Compat::hex(lParam));
|
||||||
return atom;
|
switch (uMsg)
|
||||||
|
{
|
||||||
|
case WM_CREATEPRESENTATIONWINDOW:
|
||||||
|
{
|
||||||
|
HWND presentationWindow = CreateWindowEx(
|
||||||
|
WS_EX_LAYERED | WS_EX_TRANSPARENT,
|
||||||
|
"DDrawCompatPresentationWindow",
|
||||||
|
nullptr,
|
||||||
|
WS_DISABLED | WS_POPUP,
|
||||||
|
0, 0, 1, 1,
|
||||||
|
reinterpret_cast<HWND>(wParam),
|
||||||
|
nullptr,
|
||||||
|
nullptr,
|
||||||
|
nullptr);
|
||||||
|
SetLayeredWindowAttributes(presentationWindow, 0, 255, LWA_ALPHA);
|
||||||
|
return reinterpret_cast<LRESULT>(presentationWindow);
|
||||||
|
}
|
||||||
|
|
||||||
|
case WM_DESTROY:
|
||||||
|
PostQuitMessage(0);
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return CALL_ORIG_FUNC(DefWindowProc)(hwnd, uMsg, wParam, lParam);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LRESULT CALLBACK presentationWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
LRESULT CALLBACK presentationWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||||
{
|
{
|
||||||
|
LOG_FUNC("presentationWindowProc", hwnd, Compat::hex(uMsg), Compat::hex(wParam), Compat::hex(lParam));
|
||||||
return CALL_ORIG_FUNC(DefWindowProc)(hwnd, uMsg, wParam, lParam);
|
return CALL_ORIG_FUNC(DefWindowProc)(hwnd, uMsg, wParam, lParam);
|
||||||
}
|
}
|
||||||
|
|
||||||
ATOM registerPresentationWindowClass()
|
DWORD WINAPI presentationWindowThreadProc(LPVOID /*lpParameter*/)
|
||||||
{
|
{
|
||||||
WNDCLASS wc = {};
|
WNDCLASS wc = {};
|
||||||
wc.lpfnWndProc = &presentationWindowProc;
|
wc.lpfnWndProc = &messageWindowProc;
|
||||||
wc.hInstance = reinterpret_cast<HINSTANCE>(&__ImageBase);
|
wc.hInstance = reinterpret_cast<HINSTANCE>(&__ImageBase);
|
||||||
wc.lpszClassName = "DDrawCompatPresentationWindow";
|
wc.lpszClassName = "DDrawCompatMessageWindow";
|
||||||
return RegisterClass(&wc);
|
RegisterClass(&wc);
|
||||||
|
|
||||||
|
g_messageWindow = CreateWindow(
|
||||||
|
"DDrawCompatMessageWindow", nullptr, 0, 0, 0, 0, 0, HWND_MESSAGE, nullptr, nullptr, nullptr);
|
||||||
|
if (!g_messageWindow)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
MSG msg = {};
|
||||||
|
while (GetMessage(&msg, nullptr, 0, 0))
|
||||||
|
{
|
||||||
|
TranslateMessage(&msg);
|
||||||
|
DispatchMessage(&msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -48,17 +94,8 @@ namespace Gdi
|
|||||||
const ATOM atom = static_cast<ATOM>(GetClassLong(hwnd, GCW_ATOM));
|
const ATOM atom = static_cast<ATOM>(GetClassLong(hwnd, GCW_ATOM));
|
||||||
if (MENU_ATOM != atom && getComboLBoxAtom() != atom)
|
if (MENU_ATOM != atom && getComboLBoxAtom() != atom)
|
||||||
{
|
{
|
||||||
m_presentationWindow = CreateWindowEx(
|
m_presentationWindow = reinterpret_cast<HWND>(SendMessage(
|
||||||
WS_EX_LAYERED | WS_EX_TRANSPARENT,
|
g_messageWindow, WM_CREATEPRESENTATIONWINDOW, reinterpret_cast<WPARAM>(hwnd), 0));
|
||||||
reinterpret_cast<const char*>(getPresentationWindowClassAtom()),
|
|
||||||
nullptr,
|
|
||||||
WS_DISABLED | WS_POPUP,
|
|
||||||
0, 0, 1, 1,
|
|
||||||
m_hwnd,
|
|
||||||
nullptr,
|
|
||||||
nullptr,
|
|
||||||
nullptr);
|
|
||||||
SetLayeredWindowAttributes(m_presentationWindow, 0, 255, LWA_ALPHA);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
update();
|
update();
|
||||||
@ -137,9 +174,33 @@ namespace Gdi
|
|||||||
return s_windows;
|
return s_windows;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Window::installHooks()
|
||||||
|
{
|
||||||
|
WNDCLASS wc = {};
|
||||||
|
wc.lpfnWndProc = &presentationWindowProc;
|
||||||
|
wc.hInstance = reinterpret_cast<HINSTANCE>(&__ImageBase);
|
||||||
|
wc.lpszClassName = "DDrawCompatPresentationWindow";
|
||||||
|
RegisterClass(&wc);
|
||||||
|
|
||||||
|
g_presentationWindowThread = CreateThread(
|
||||||
|
nullptr, 0, &presentationWindowThreadProc, nullptr, 0, &g_presentationWindowThreadId);
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
while (!g_messageWindow && i < 1000)
|
||||||
|
{
|
||||||
|
Sleep(1);
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!g_messageWindow)
|
||||||
|
{
|
||||||
|
Compat::Log() << "Failed to create a message-only window";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool Window::isPresentationWindow(HWND hwnd)
|
bool Window::isPresentationWindow(HWND hwnd)
|
||||||
{
|
{
|
||||||
return IsWindow(hwnd) && GetClassLong(hwnd, GCW_ATOM) == getPresentationWindowClassAtom();
|
return IsWindow(hwnd) && g_presentationWindowThreadId == GetWindowThreadProcessId(hwnd, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Window::isTopLevelNonLayeredWindow(HWND hwnd)
|
bool Window::isTopLevelNonLayeredWindow(HWND hwnd)
|
||||||
@ -155,6 +216,19 @@ namespace Gdi
|
|||||||
s_windows.erase(hwnd);
|
s_windows.erase(hwnd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Window::uninstallHooks()
|
||||||
|
{
|
||||||
|
if (g_presentationWindowThread)
|
||||||
|
{
|
||||||
|
SendMessage(g_messageWindow, WM_CLOSE, 0, 0);
|
||||||
|
if (WAIT_OBJECT_0 != WaitForSingleObject(g_presentationWindowThread, 1000))
|
||||||
|
{
|
||||||
|
TerminateThread(g_presentationWindowThread, 0);
|
||||||
|
Compat::Log() << "The presentation window thread was terminated forcefully";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Window::update()
|
void Window::update()
|
||||||
{
|
{
|
||||||
DDraw::ScopedThreadLock lock;
|
DDraw::ScopedThreadLock lock;
|
||||||
|
@ -32,6 +32,9 @@ namespace Gdi
|
|||||||
static bool isTopLevelNonLayeredWindow(HWND hwnd);
|
static bool isTopLevelNonLayeredWindow(HWND hwnd);
|
||||||
static void updateAll();
|
static void updateAll();
|
||||||
|
|
||||||
|
static void installHooks();
|
||||||
|
static void uninstallHooks();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void calcInvalidatedRegion(const RECT& oldWindowRect, const Region& oldVisibleRegion);
|
void calcInvalidatedRegion(const RECT& oldWindowRect, const Region& oldVisibleRegion);
|
||||||
void update();
|
void update();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user