mirror of
https://github.com/narzoul/DDrawCompat
synced 2024-12-30 08:55:36 +01:00
Moved presentation window implementation to separate file
This commit is contained in:
parent
481b09f489
commit
13ab654665
@ -221,6 +221,7 @@
|
|||||||
<ClInclude Include="Gdi\Dc.h" />
|
<ClInclude Include="Gdi\Dc.h" />
|
||||||
<ClInclude Include="Gdi\DcCache.h" />
|
<ClInclude Include="Gdi\DcCache.h" />
|
||||||
<ClInclude Include="Gdi\DcFunctions.h" />
|
<ClInclude Include="Gdi\DcFunctions.h" />
|
||||||
|
<ClInclude Include="Gdi\PresentationWindow.h" />
|
||||||
<ClInclude Include="Gdi\User32WndProcs.h" />
|
<ClInclude Include="Gdi\User32WndProcs.h" />
|
||||||
<ClInclude Include="Gdi\Palette.h" />
|
<ClInclude Include="Gdi\Palette.h" />
|
||||||
<ClInclude Include="Gdi\Region.h" />
|
<ClInclude Include="Gdi\Region.h" />
|
||||||
@ -294,6 +295,7 @@
|
|||||||
<ClCompile Include="Gdi\Dc.cpp" />
|
<ClCompile Include="Gdi\Dc.cpp" />
|
||||||
<ClCompile Include="Gdi\DcCache.cpp" />
|
<ClCompile Include="Gdi\DcCache.cpp" />
|
||||||
<ClCompile Include="Gdi\DcFunctions.cpp" />
|
<ClCompile Include="Gdi\DcFunctions.cpp" />
|
||||||
|
<ClCompile Include="Gdi\PresentationWindow.cpp" />
|
||||||
<ClCompile Include="Gdi\User32WndProcs.cpp" />
|
<ClCompile Include="Gdi\User32WndProcs.cpp" />
|
||||||
<ClCompile Include="Gdi\Palette.cpp" />
|
<ClCompile Include="Gdi\Palette.cpp" />
|
||||||
<ClCompile Include="Gdi\Region.cpp" />
|
<ClCompile Include="Gdi\Region.cpp" />
|
||||||
|
@ -399,6 +399,9 @@
|
|||||||
<ClInclude Include="Gdi\User32WndProcs.h">
|
<ClInclude Include="Gdi\User32WndProcs.h">
|
||||||
<Filter>Header Files\Gdi</Filter>
|
<Filter>Header Files\Gdi</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="Gdi\PresentationWindow.h">
|
||||||
|
<Filter>Header Files\Gdi</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="Gdi\Gdi.cpp">
|
<ClCompile Include="Gdi\Gdi.cpp">
|
||||||
@ -614,5 +617,8 @@
|
|||||||
<ClCompile Include="Gdi\User32WndProcs.cpp">
|
<ClCompile Include="Gdi\User32WndProcs.cpp">
|
||||||
<Filter>Source Files\Gdi</Filter>
|
<Filter>Source Files\Gdi</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="Gdi\PresentationWindow.cpp">
|
||||||
|
<Filter>Source Files\Gdi</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
@ -6,9 +6,9 @@
|
|||||||
#include <Gdi/Font.h>
|
#include <Gdi/Font.h>
|
||||||
#include <Gdi/Gdi.h>
|
#include <Gdi/Gdi.h>
|
||||||
#include <Gdi/Palette.h>
|
#include <Gdi/Palette.h>
|
||||||
|
#include <Gdi/PresentationWindow.h>
|
||||||
#include <Gdi/ScrollFunctions.h>
|
#include <Gdi/ScrollFunctions.h>
|
||||||
#include <Gdi/User32WndProcs.h>
|
#include <Gdi/User32WndProcs.h>
|
||||||
#include <Gdi/Window.h>
|
|
||||||
#include <Gdi/WinProc.h>
|
#include <Gdi/WinProc.h>
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
@ -38,9 +38,9 @@ namespace Gdi
|
|||||||
{
|
{
|
||||||
DcFunctions::installHooks();
|
DcFunctions::installHooks();
|
||||||
Palette::installHooks();
|
Palette::installHooks();
|
||||||
|
PresentationWindow::installHooks();
|
||||||
ScrollFunctions::installHooks();
|
ScrollFunctions::installHooks();
|
||||||
User32WndProcs::installHooks();
|
User32WndProcs::installHooks();
|
||||||
Window::installHooks();
|
|
||||||
WinProc::installHooks();
|
WinProc::installHooks();
|
||||||
Caret::installHooks();
|
Caret::installHooks();
|
||||||
Font::installHooks();
|
Font::installHooks();
|
||||||
@ -59,7 +59,7 @@ namespace Gdi
|
|||||||
|
|
||||||
void redrawWindow(HWND hwnd, HRGN rgn)
|
void redrawWindow(HWND hwnd, HRGN rgn)
|
||||||
{
|
{
|
||||||
if (!IsWindowVisible(hwnd) || IsIconic(hwnd) || Window::isPresentationWindow(hwnd))
|
if (!IsWindowVisible(hwnd) || IsIconic(hwnd) || PresentationWindow::isPresentationWindow(hwnd))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -89,8 +89,8 @@ namespace Gdi
|
|||||||
void uninstallHooks()
|
void uninstallHooks()
|
||||||
{
|
{
|
||||||
Caret::uninstallHooks();
|
Caret::uninstallHooks();
|
||||||
|
PresentationWindow::uninstallHooks();
|
||||||
WinProc::uninstallHooks();
|
WinProc::uninstallHooks();
|
||||||
Window::uninstallHooks();
|
|
||||||
Dc::dllProcessDetach();
|
Dc::dllProcessDetach();
|
||||||
DcCache::dllProcessDetach();
|
DcCache::dllProcessDetach();
|
||||||
}
|
}
|
||||||
|
185
DDrawCompat/Gdi/PresentationWindow.cpp
Normal file
185
DDrawCompat/Gdi/PresentationWindow.cpp
Normal file
@ -0,0 +1,185 @@
|
|||||||
|
#include <Common/Hook.h>
|
||||||
|
#include <Common/Log.h>
|
||||||
|
#include <Dll/Dll.h>
|
||||||
|
#include <Gdi/PresentationWindow.h>
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
const UINT WM_CREATEPRESENTATIONWINDOW = WM_USER;
|
||||||
|
const UINT WM_SETPRESENTATIONWINDOWPOS = WM_USER + 1;
|
||||||
|
const UINT WM_SETPRESENTATIONWINDOWRGN = WM_USER + 2;
|
||||||
|
|
||||||
|
HANDLE g_presentationWindowThread = nullptr;
|
||||||
|
DWORD g_presentationWindowThreadId = 0;
|
||||||
|
HWND g_messageWindow = nullptr;
|
||||||
|
|
||||||
|
LRESULT CALLBACK messageWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||||
|
{
|
||||||
|
LOG_FUNC("messageWindowProc", Compat::WindowMessageStruct(hwnd, uMsg, wParam, lParam));
|
||||||
|
|
||||||
|
switch (uMsg)
|
||||||
|
{
|
||||||
|
case WM_CREATEPRESENTATIONWINDOW:
|
||||||
|
{
|
||||||
|
// Workaround for ForceSimpleWindow shim
|
||||||
|
static auto origCreateWindowExA = reinterpret_cast<decltype(&CreateWindowExA)>(
|
||||||
|
Compat::getProcAddress(GetModuleHandle("user32"), "CreateWindowExA"));
|
||||||
|
|
||||||
|
HWND owner = reinterpret_cast<HWND>(wParam);
|
||||||
|
HWND presentationWindow = origCreateWindowExA(
|
||||||
|
WS_EX_LAYERED | WS_EX_TRANSPARENT | WS_EX_NOPARENTNOTIFY | WS_EX_TOOLWINDOW,
|
||||||
|
"DDrawCompatPresentationWindow",
|
||||||
|
nullptr,
|
||||||
|
WS_DISABLED | WS_POPUP,
|
||||||
|
0, 0, 1, 1,
|
||||||
|
owner,
|
||||||
|
nullptr,
|
||||||
|
nullptr,
|
||||||
|
nullptr);
|
||||||
|
|
||||||
|
if (presentationWindow)
|
||||||
|
{
|
||||||
|
CALL_ORIG_FUNC(SetLayeredWindowAttributes)(presentationWindow, 0, 255, LWA_ALPHA);
|
||||||
|
}
|
||||||
|
|
||||||
|
return LOG_RESULT(reinterpret_cast<LRESULT>(presentationWindow));
|
||||||
|
}
|
||||||
|
|
||||||
|
case WM_DESTROY:
|
||||||
|
PostQuitMessage(0);
|
||||||
|
return LOG_RESULT(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
return LOG_RESULT(CALL_ORIG_FUNC(DefWindowProc)(hwnd, uMsg, wParam, lParam));
|
||||||
|
}
|
||||||
|
|
||||||
|
LRESULT CALLBACK presentationWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||||
|
{
|
||||||
|
LOG_FUNC("presentationWindowProc", Compat::WindowMessageStruct(hwnd, uMsg, wParam, lParam));
|
||||||
|
|
||||||
|
switch (uMsg)
|
||||||
|
{
|
||||||
|
case WM_SETPRESENTATIONWINDOWPOS:
|
||||||
|
{
|
||||||
|
const auto& wp = *reinterpret_cast<WINDOWPOS*>(lParam);
|
||||||
|
return SetWindowPos(hwnd, wp.hwndInsertAfter, wp.x, wp.y, wp.cx, wp.cy, wp.flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
case WM_SETPRESENTATIONWINDOWRGN:
|
||||||
|
{
|
||||||
|
HRGN rgn = nullptr;
|
||||||
|
if (wParam)
|
||||||
|
{
|
||||||
|
rgn = CreateRectRgn(0, 0, 0, 0);
|
||||||
|
CombineRgn(rgn, reinterpret_cast<HRGN>(wParam), nullptr, RGN_COPY);
|
||||||
|
}
|
||||||
|
return SetWindowRgn(hwnd, rgn, FALSE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return CALL_ORIG_FUNC(DefWindowProc)(hwnd, uMsg, wParam, lParam);
|
||||||
|
}
|
||||||
|
|
||||||
|
DWORD WINAPI presentationWindowThreadProc(LPVOID /*lpParameter*/)
|
||||||
|
{
|
||||||
|
SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL);
|
||||||
|
|
||||||
|
WNDCLASS wc = {};
|
||||||
|
wc.lpfnWndProc = &messageWindowProc;
|
||||||
|
wc.hInstance = Dll::g_currentModule;
|
||||||
|
wc.lpszClassName = "DDrawCompatMessageWindow";
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
LRESULT sendMessageBlocking(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||||
|
{
|
||||||
|
DWORD_PTR result = 0;
|
||||||
|
SendMessageTimeout(hwnd, msg, wParam, lParam, SMTO_BLOCK | SMTO_NOTIMEOUTIFNOTHUNG, 0, &result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace Gdi
|
||||||
|
{
|
||||||
|
namespace PresentationWindow
|
||||||
|
{
|
||||||
|
HWND create(HWND owner)
|
||||||
|
{
|
||||||
|
return reinterpret_cast<HWND>(sendMessageBlocking(
|
||||||
|
g_messageWindow, WM_CREATEPRESENTATIONWINDOW, reinterpret_cast<WPARAM>(owner), 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
void destroy(HWND hwnd)
|
||||||
|
{
|
||||||
|
sendMessageBlocking(hwnd, WM_CLOSE, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void installHooks()
|
||||||
|
{
|
||||||
|
WNDCLASS wc = {};
|
||||||
|
wc.lpfnWndProc = &presentationWindowProc;
|
||||||
|
wc.hInstance = Dll::g_currentModule;
|
||||||
|
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() << "ERROR: Failed to create a message-only window";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isPresentationWindow(HWND hwnd)
|
||||||
|
{
|
||||||
|
return GetWindowThreadProcessId(hwnd, nullptr) == g_presentationWindowThreadId;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setWindowPos(HWND hwnd, const WINDOWPOS& wp)
|
||||||
|
{
|
||||||
|
sendMessageBlocking(hwnd, WM_SETPRESENTATIONWINDOWPOS, 0, reinterpret_cast<WPARAM>(&wp));
|
||||||
|
}
|
||||||
|
|
||||||
|
void setWindowRgn(HWND hwnd, HRGN rgn)
|
||||||
|
{
|
||||||
|
sendMessageBlocking(hwnd, WM_SETPRESENTATIONWINDOWRGN, reinterpret_cast<WPARAM>(rgn), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void uninstallHooks()
|
||||||
|
{
|
||||||
|
if (g_presentationWindowThread)
|
||||||
|
{
|
||||||
|
sendMessageBlocking(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";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
18
DDrawCompat/Gdi/PresentationWindow.h
Normal file
18
DDrawCompat/Gdi/PresentationWindow.h
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <Windows.h>
|
||||||
|
|
||||||
|
namespace Gdi
|
||||||
|
{
|
||||||
|
namespace PresentationWindow
|
||||||
|
{
|
||||||
|
HWND create(HWND owner);
|
||||||
|
void destroy(HWND hwnd);
|
||||||
|
bool isPresentationWindow(HWND hwnd);
|
||||||
|
void setWindowPos(HWND hwnd, const WINDOWPOS& wp);
|
||||||
|
void setWindowRgn(HWND hwnd, HRGN rgn);
|
||||||
|
|
||||||
|
void installHooks();
|
||||||
|
void uninstallHooks();
|
||||||
|
}
|
||||||
|
}
|
@ -9,12 +9,13 @@
|
|||||||
#include <Dll/Dll.h>
|
#include <Dll/Dll.h>
|
||||||
#include <Gdi/AccessGuard.h>
|
#include <Gdi/AccessGuard.h>
|
||||||
#include <Gdi/Dc.h>
|
#include <Gdi/Dc.h>
|
||||||
#include <Win32/DisplayMode.h>
|
#include <Gdi/PresentationWindow.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>
|
||||||
#include <Gdi/Window.h>
|
#include <Gdi/Window.h>
|
||||||
#include <Gdi/WinProc.h>
|
#include <Gdi/WinProc.h>
|
||||||
|
#include <Win32/DisplayMode.h>
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
@ -171,7 +172,7 @@ namespace
|
|||||||
DWORD /*dwEventThread*/,
|
DWORD /*dwEventThread*/,
|
||||||
DWORD /*dwmsEventTime*/)
|
DWORD /*dwmsEventTime*/)
|
||||||
{
|
{
|
||||||
if (OBJID_WINDOW == idObject && !Gdi::Window::isPresentationWindow(hwnd))
|
if (OBJID_WINDOW == idObject && !Gdi::PresentationWindow::isPresentationWindow(hwnd))
|
||||||
{
|
{
|
||||||
onCreateWindow(hwnd);
|
onCreateWindow(hwnd);
|
||||||
}
|
}
|
||||||
|
@ -4,12 +4,11 @@
|
|||||||
|
|
||||||
#include <dwmapi.h>
|
#include <dwmapi.h>
|
||||||
|
|
||||||
#include <Common/Hook.h>
|
|
||||||
#include <Common/Log.h>
|
#include <Common/Log.h>
|
||||||
#include <D3dDdi/KernelModeThunks.h>
|
#include <D3dDdi/KernelModeThunks.h>
|
||||||
#include <D3dDdi/ScopedCriticalSection.h>
|
#include <D3dDdi/ScopedCriticalSection.h>
|
||||||
#include <DDraw/RealPrimarySurface.h>
|
#include <DDraw/RealPrimarySurface.h>
|
||||||
#include <Gdi/Gdi.h>
|
#include <Gdi/PresentationWindow.h>
|
||||||
#include <Gdi/VirtualScreen.h>
|
#include <Gdi/VirtualScreen.h>
|
||||||
#include <Gdi/Window.h>
|
#include <Gdi/Window.h>
|
||||||
|
|
||||||
@ -50,14 +49,8 @@ namespace
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const UINT WM_CREATEPRESENTATIONWINDOW = WM_USER;
|
|
||||||
const UINT WM_SETPRESENTATIONWINDOWPOS = WM_USER + 1;
|
|
||||||
const UINT WM_SETPRESENTATIONWINDOWRGN = WM_USER + 2;
|
|
||||||
const RECT REGION_OVERRIDE_MARKER_RECT = { 32000, 32000, 32001, 32001 };
|
const RECT REGION_OVERRIDE_MARKER_RECT = { 32000, 32000, 32001, 32001 };
|
||||||
|
|
||||||
HANDLE g_presentationWindowThread = nullptr;
|
|
||||||
DWORD g_presentationWindowThreadId = 0;
|
|
||||||
HWND g_messageWindow = nullptr;
|
|
||||||
std::map<HWND, Window> g_windows;
|
std::map<HWND, Window> g_windows;
|
||||||
std::vector<Window*> g_windowZOrder;
|
std::vector<Window*> g_windowZOrder;
|
||||||
|
|
||||||
@ -102,107 +95,6 @@ namespace
|
|||||||
return rgn;
|
return rgn;
|
||||||
}
|
}
|
||||||
|
|
||||||
LRESULT CALLBACK messageWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
|
||||||
{
|
|
||||||
LOG_FUNC("messageWindowProc", Compat::WindowMessageStruct(hwnd, uMsg, wParam, lParam));
|
|
||||||
switch (uMsg)
|
|
||||||
{
|
|
||||||
case WM_CREATEPRESENTATIONWINDOW:
|
|
||||||
{
|
|
||||||
// Workaround for ForceSimpleWindow shim
|
|
||||||
static auto origCreateWindowExA = reinterpret_cast<decltype(&CreateWindowExA)>(
|
|
||||||
Compat::getProcAddress(GetModuleHandle("user32"), "CreateWindowExA"));
|
|
||||||
|
|
||||||
HWND owner = reinterpret_cast<HWND>(wParam);
|
|
||||||
HWND presentationWindow = origCreateWindowExA(
|
|
||||||
WS_EX_LAYERED | WS_EX_TRANSPARENT | WS_EX_NOPARENTNOTIFY | WS_EX_TOOLWINDOW,
|
|
||||||
"DDrawCompatPresentationWindow",
|
|
||||||
nullptr,
|
|
||||||
WS_DISABLED | WS_POPUP,
|
|
||||||
0, 0, 1, 1,
|
|
||||||
owner,
|
|
||||||
nullptr,
|
|
||||||
nullptr,
|
|
||||||
nullptr);
|
|
||||||
|
|
||||||
if (presentationWindow)
|
|
||||||
{
|
|
||||||
CALL_ORIG_FUNC(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)
|
|
||||||
{
|
|
||||||
LOG_FUNC("presentationWindowProc", Compat::WindowMessageStruct(hwnd, uMsg, wParam, lParam));
|
|
||||||
|
|
||||||
switch (uMsg)
|
|
||||||
{
|
|
||||||
case WM_SETPRESENTATIONWINDOWPOS:
|
|
||||||
{
|
|
||||||
const auto& wp = *reinterpret_cast<WINDOWPOS*>(lParam);
|
|
||||||
return SetWindowPos(hwnd, wp.hwndInsertAfter, wp.x, wp.y, wp.cx, wp.cy, wp.flags);
|
|
||||||
}
|
|
||||||
|
|
||||||
case WM_SETPRESENTATIONWINDOWRGN:
|
|
||||||
{
|
|
||||||
HRGN rgn = nullptr;
|
|
||||||
if (wParam)
|
|
||||||
{
|
|
||||||
rgn = CreateRectRgn(0, 0, 0, 0);
|
|
||||||
CombineRgn(rgn, reinterpret_cast<HRGN>(wParam), nullptr, RGN_COPY);
|
|
||||||
}
|
|
||||||
return SetWindowRgn(hwnd, rgn, FALSE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return CALL_ORIG_FUNC(DefWindowProc)(hwnd, uMsg, wParam, lParam);
|
|
||||||
}
|
|
||||||
|
|
||||||
DWORD WINAPI presentationWindowThreadProc(LPVOID /*lpParameter*/)
|
|
||||||
{
|
|
||||||
SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL);
|
|
||||||
|
|
||||||
WNDCLASS wc = {};
|
|
||||||
wc.lpfnWndProc = &messageWindowProc;
|
|
||||||
wc.hInstance = Dll::g_currentModule;
|
|
||||||
wc.lpszClassName = "DDrawCompatMessageWindow";
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
LRESULT sendMessageBlocking(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
|
||||||
{
|
|
||||||
DWORD_PTR result = 0;
|
|
||||||
SendMessageTimeout(hwnd, msg, wParam, lParam, SMTO_BLOCK | SMTO_NOTIMEOUTIFNOTHUNG, 0, &result);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
void updatePosition(Window& window, const RECT& oldWindowRect, const RECT& oldClientRect,
|
void updatePosition(Window& window, const RECT& oldWindowRect, const RECT& oldClientRect,
|
||||||
const Gdi::Region& oldVisibleRegion)
|
const Gdi::Region& oldVisibleRegion)
|
||||||
{
|
{
|
||||||
@ -286,8 +178,8 @@ namespace
|
|||||||
|
|
||||||
DWORD processId = 0;
|
DWORD processId = 0;
|
||||||
GetWindowThreadProcessId(hwnd, &processId);
|
GetWindowThreadProcessId(hwnd, &processId);
|
||||||
if (GetWindowThreadProcessId(hwnd, &processId) == g_presentationWindowThreadId ||
|
if (processId != context.processId ||
|
||||||
processId != context.processId)
|
Gdi::PresentationWindow::isPresentationWindow(hwnd))
|
||||||
{
|
{
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
@ -310,13 +202,12 @@ namespace
|
|||||||
it->second.isVisibleRegionChanged = isVisible;
|
it->second.isVisibleRegionChanged = isVisible;
|
||||||
if (!isLayered)
|
if (!isLayered)
|
||||||
{
|
{
|
||||||
it->second.presentationWindow = reinterpret_cast<HWND>(
|
it->second.presentationWindow = Gdi::PresentationWindow::create(hwnd);
|
||||||
sendMessageBlocking(g_messageWindow, WM_CREATEPRESENTATIONWINDOW, reinterpret_cast<WPARAM>(hwnd), 0));
|
|
||||||
setPresentationWindowRgn = true;
|
setPresentationWindowRgn = true;
|
||||||
}
|
}
|
||||||
else if (it->second.presentationWindow)
|
else if (it->second.presentationWindow)
|
||||||
{
|
{
|
||||||
sendMessageBlocking(it->second.presentationWindow, WM_CLOSE, 0, 0);
|
Gdi::PresentationWindow::destroy(it->second.presentationWindow);
|
||||||
it->second.presentationWindow = nullptr;
|
it->second.presentationWindow = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -382,9 +273,7 @@ namespace
|
|||||||
{
|
{
|
||||||
if (setPresentationWindowRgn)
|
if (setPresentationWindowRgn)
|
||||||
{
|
{
|
||||||
HRGN rgn = it->second.windowRegion;
|
Gdi::PresentationWindow::setWindowRgn(it->second.presentationWindow, it->second.windowRegion);
|
||||||
sendMessageBlocking(it->second.presentationWindow, WM_SETPRESENTATIONWINDOWRGN,
|
|
||||||
reinterpret_cast<WPARAM>(rgn), 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
WINDOWPOS wp = {};
|
WINDOWPOS wp = {};
|
||||||
@ -412,8 +301,7 @@ namespace
|
|||||||
wp.flags |= SWP_HIDEWINDOW | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER;
|
wp.flags |= SWP_HIDEWINDOW | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER;
|
||||||
}
|
}
|
||||||
|
|
||||||
sendMessageBlocking(it->second.presentationWindow, WM_SETPRESENTATIONWINDOWPOS,
|
Gdi::PresentationWindow::setWindowPos(it->second.presentationWindow, wp);
|
||||||
0, reinterpret_cast<LPARAM>(&wp));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return TRUE;
|
return TRUE;
|
||||||
@ -424,35 +312,6 @@ namespace Gdi
|
|||||||
{
|
{
|
||||||
namespace Window
|
namespace Window
|
||||||
{
|
{
|
||||||
void installHooks()
|
|
||||||
{
|
|
||||||
WNDCLASS wc = {};
|
|
||||||
wc.lpfnWndProc = &presentationWindowProc;
|
|
||||||
wc.hInstance = Dll::g_currentModule;
|
|
||||||
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() << "ERROR: Failed to create a message-only window";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isPresentationWindow(HWND hwnd)
|
|
||||||
{
|
|
||||||
return g_presentationWindowThreadId == GetWindowThreadProcessId(hwnd, nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
void onStyleChanged(HWND hwnd, WPARAM wParam)
|
void onStyleChanged(HWND hwnd, WPARAM wParam)
|
||||||
{
|
{
|
||||||
if (GWL_EXSTYLE == wParam)
|
if (GWL_EXSTYLE == wParam)
|
||||||
@ -655,7 +514,7 @@ namespace Gdi
|
|||||||
{
|
{
|
||||||
if (it->second.presentationWindow)
|
if (it->second.presentationWindow)
|
||||||
{
|
{
|
||||||
sendMessageBlocking(it->second.presentationWindow, WM_CLOSE, 0, 0);
|
Gdi::PresentationWindow::destroy(it->second.presentationWindow);
|
||||||
}
|
}
|
||||||
it = g_windows.erase(it);
|
it = g_windows.erase(it);
|
||||||
}
|
}
|
||||||
@ -695,18 +554,5 @@ namespace Gdi
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void uninstallHooks()
|
|
||||||
{
|
|
||||||
if (g_presentationWindowThread)
|
|
||||||
{
|
|
||||||
sendMessageBlocking(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";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,6 @@ namespace Gdi
|
|||||||
{
|
{
|
||||||
namespace Window
|
namespace Window
|
||||||
{
|
{
|
||||||
bool isPresentationWindow(HWND hwnd);
|
|
||||||
void onStyleChanged(HWND hwnd, WPARAM wParam);
|
void onStyleChanged(HWND hwnd, WPARAM wParam);
|
||||||
void onSyncPaint(HWND hwnd);
|
void onSyncPaint(HWND hwnd);
|
||||||
void present(CompatRef<IDirectDrawSurface7> dst, CompatRef<IDirectDrawSurface7> src,
|
void present(CompatRef<IDirectDrawSurface7> dst, CompatRef<IDirectDrawSurface7> src,
|
||||||
@ -18,8 +17,5 @@ namespace Gdi
|
|||||||
void presentLayered(CompatRef<IDirectDrawSurface7> dst, POINT offset);
|
void presentLayered(CompatRef<IDirectDrawSurface7> dst, POINT offset);
|
||||||
void updateAll();
|
void updateAll();
|
||||||
void updateLayeredWindowInfo(HWND hwnd, COLORREF colorKey, BYTE alpha);
|
void updateLayeredWindowInfo(HWND hwnd, COLORREF colorKey, BYTE alpha);
|
||||||
|
|
||||||
void installHooks();
|
|
||||||
void uninstallHooks();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user