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

Fixed dialog window position in scaled fullscreen mode

This commit is contained in:
narzoul 2022-04-30 15:47:38 +02:00
parent 31444c364a
commit 01be996c36
2 changed files with 81 additions and 0 deletions

View File

@ -20,6 +20,9 @@ namespace Compat
template <auto origFunc>
decltype(origFunc) g_origFuncPtr = origFunc;
template <auto origFunc>
std::string g_origFuncName;
FARPROC getProcAddress(HMODULE module, const char* procName);
void hookFunction(void*& origFuncPtr, void* newFuncPtr, const char* funcName);
void hookFunction(HMODULE module, const char* funcName, void*& origFuncPtr, void* newFuncPtr);
@ -29,6 +32,7 @@ namespace Compat
template <auto origFunc>
void hookFunction(const char* moduleName, const char* funcName, decltype(origFunc) newFuncPtr)
{
g_origFuncName<origFunc> = funcName;
hookFunction(moduleName, funcName, reinterpret_cast<void*&>(g_origFuncPtr<origFunc>), newFuncPtr);
}

View File

@ -37,16 +37,30 @@ namespace
Compat::SrwLock g_windowProcSrwLock;
std::map<HWND, WindowProc> g_windowProc;
thread_local unsigned g_inCreateDialog = 0;
thread_local unsigned g_inMessageBox = 0;
WindowProc getWindowProc(HWND hwnd);
bool isUser32ScrollBar(HWND hwnd);
void onDestroyWindow(HWND hwnd);
void onGetMinMaxInfo(MINMAXINFO& mmi);
void onInitDialog(HWND hwnd);
void onInitMenuPopup(HMENU menu);
void onUninitMenuPopup(HMENU menu);
void onWindowPosChanged(HWND hwnd, const WINDOWPOS& wp);
void onWindowPosChanging(HWND hwnd, WINDOWPOS& wp);
void setWindowProc(HWND hwnd, WNDPROC wndProcA, WNDPROC wndProcW);
template <auto func, typename Result, typename... Params>
Result WINAPI createDialog(Params... params)
{
LOG_FUNC(Compat::g_origFuncName<func>.c_str(), params...);
++g_inCreateDialog;
Result result = CALL_ORIG_FUNC(func)(params...);
--g_inCreateDialog;
return LOG_RESULT(result);
}
LRESULT CALLBACK ddcWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam,
decltype(&CallWindowProcA) callWindowProc, WNDPROC wndProc)
{
@ -70,6 +84,10 @@ namespace
onGetMinMaxInfo(*reinterpret_cast<MINMAXINFO*>(lParam));
break;
case WM_INITDIALOG:
onInitDialog(hwnd);
break;
case WM_SYNCPAINT:
if (Gdi::Window::isTopLevelWindow(hwnd))
{
@ -197,6 +215,51 @@ namespace
return g_windowProc[hwnd];
}
template <auto func, typename... Params>
int WINAPI messageBox(Params... params)
{
LOG_FUNC(Compat::g_origFuncName<func>.c_str(), params...);
++g_inMessageBox;
int result = CALL_ORIG_FUNC(func)(params...);
--g_inMessageBox;
return LOG_RESULT(result);
}
void onInitDialog(HWND hwnd)
{
if (!Gdi::Window::isTopLevelWindow(hwnd) ||
0 == g_inMessageBox &&
(0 == g_inCreateDialog || !(CALL_ORIG_FUNC(GetWindowLongA)(hwnd, GWL_STYLE) & DS_CENTER)))
{
return;
}
HMONITOR monitor = MonitorFromWindow(hwnd, MONITOR_DEFAULTTOPRIMARY);
MONITORINFO origMi = {};
origMi.cbSize = sizeof(origMi);
CALL_ORIG_FUNC(GetMonitorInfoA)(monitor, &origMi);
MONITORINFO mi = {};
mi.cbSize = sizeof(mi);
GetMonitorInfoA(monitor, &mi);
if (!EqualRect(&origMi.rcMonitor, &mi.rcMonitor))
{
RECT wr = {};
GetWindowRect(hwnd, &wr);
const LONG width = wr.right - wr.left;
const LONG height = wr.bottom - wr.top;
const RECT& mr = 0 == g_inMessageBox ? mi.rcWork : mi.rcMonitor;
const LONG left = (mr.left + mr.right - width) / 2;
const LONG top = (mr.top + mr.bottom - height) / 2;
CALL_ORIG_FUNC(SetWindowPos)(hwnd, nullptr, left, top, width, height,
SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOSENDCHANGING);
}
}
bool isUser32ScrollBar(HWND hwnd)
{
WNDCLASS wc = {};
@ -489,10 +552,24 @@ namespace Gdi
void installHooks()
{
HOOK_FUNCTION(user32, CreateDialogIndirectParamA, createDialog<CreateDialogIndirectParamA>);
HOOK_FUNCTION(user32, CreateDialogIndirectParamW, createDialog<CreateDialogIndirectParamW>);
HOOK_FUNCTION(user32, CreateDialogParamA, createDialog<CreateDialogParamA>);
HOOK_FUNCTION(user32, CreateDialogParamW, createDialog<CreateDialogParamW>);
HOOK_FUNCTION(user32, DialogBoxParamA, createDialog<DialogBoxParamA>);
HOOK_FUNCTION(user32, DialogBoxParamW, createDialog<DialogBoxParamW>);
HOOK_FUNCTION(user32, DialogBoxIndirectParamA, createDialog<DialogBoxIndirectParamA>);
HOOK_FUNCTION(user32, DialogBoxIndirectParamW, createDialog<DialogBoxIndirectParamW>);
HOOK_FUNCTION(user32, GetMessageA, getMessageA);
HOOK_FUNCTION(user32, GetMessageW, getMessageW);
HOOK_FUNCTION(user32, GetWindowLongA, getWindowLongA);
HOOK_FUNCTION(user32, GetWindowLongW, getWindowLongW);
HOOK_FUNCTION(user32, MessageBoxA, messageBox<MessageBoxA>);
HOOK_FUNCTION(user32, MessageBoxW, messageBox<MessageBoxW>);
HOOK_FUNCTION(user32, MessageBoxExA, messageBox<MessageBoxExA>);
HOOK_FUNCTION(user32, MessageBoxExW, messageBox<MessageBoxExW>);
HOOK_FUNCTION(user32, MessageBoxIndirectA, messageBox<MessageBoxIndirectA>);
HOOK_FUNCTION(user32, MessageBoxIndirectW, messageBox<MessageBoxIndirectW>);
HOOK_FUNCTION(user32, PeekMessageA, peekMessageA);
HOOK_FUNCTION(user32, PeekMessageW, peekMessageW);
HOOK_FUNCTION(user32, SetLayeredWindowAttributes, setLayeredWindowAttributes);