mirror of
https://github.com/narzoul/DDrawCompat
synced 2024-12-30 08:55:36 +01:00
Fixed sporadic deadlock caused by presentation window title update
Fixes occasional deadlock when alt-tabbing in Age of Wonders: Shadow Magic.
This commit is contained in:
parent
ea4097d810
commit
8485017afc
@ -9,9 +9,23 @@ namespace
|
|||||||
{
|
{
|
||||||
ATOM g_classAtom = 0;
|
ATOM g_classAtom = 0;
|
||||||
|
|
||||||
|
std::wstring getWindowText(HWND hwnd)
|
||||||
|
{
|
||||||
|
const UINT MAX_LEN = 256;
|
||||||
|
wchar_t windowText[MAX_LEN] = {};
|
||||||
|
InternalGetWindowText(hwnd, windowText, MAX_LEN);
|
||||||
|
return windowText;
|
||||||
|
}
|
||||||
|
|
||||||
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", Compat::WindowMessageStruct(hwnd, uMsg, wParam, lParam));
|
LOG_FUNC("presentationWindowProc", Compat::WindowMessageStruct(hwnd, uMsg, wParam, lParam));
|
||||||
|
if (WM_NULL == uMsg && WM_GETTEXT == wParam && WM_SETTEXT == lParam)
|
||||||
|
{
|
||||||
|
std::wstring windowText(L"[DDrawCompat] " + getWindowText(GetParent(hwnd)));
|
||||||
|
SetWindowTextW(hwnd, windowText.c_str());
|
||||||
|
return LOG_RESULT(0);
|
||||||
|
}
|
||||||
return LOG_RESULT(CALL_ORIG_FUNC(DefWindowProcA)(hwnd, uMsg, wParam, lParam));
|
return LOG_RESULT(CALL_ORIG_FUNC(DefWindowProcA)(hwnd, uMsg, wParam, lParam));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -54,7 +54,6 @@ namespace
|
|||||||
|
|
||||||
decltype(&DwmSetIconicThumbnail) g_dwmSetIconicThumbnail = nullptr;
|
decltype(&DwmSetIconicThumbnail) g_dwmSetIconicThumbnail = nullptr;
|
||||||
|
|
||||||
wchar_t g_dummyWindowText;
|
|
||||||
std::map<HMENU, UINT> g_menuMaxHeight;
|
std::map<HMENU, UINT> g_menuMaxHeight;
|
||||||
std::set<Gdi::WindowPosChangeNotifyFunc> g_windowPosChangeNotifyFuncs;
|
std::set<Gdi::WindowPosChangeNotifyFunc> g_windowPosChangeNotifyFuncs;
|
||||||
|
|
||||||
@ -71,7 +70,6 @@ namespace
|
|||||||
|
|
||||||
void dwmSendIconicThumbnail(HWND hwnd, LONG width, LONG height);
|
void dwmSendIconicThumbnail(HWND hwnd, LONG width, LONG height);
|
||||||
WindowProc getWindowProc(HWND hwnd);
|
WindowProc getWindowProc(HWND hwnd);
|
||||||
std::wstring getWindowText(HWND hwnd, WNDPROC wndProc);
|
|
||||||
bool isUser32ScrollBar(HWND hwnd);
|
bool isUser32ScrollBar(HWND hwnd);
|
||||||
void onDestroyWindow(HWND hwnd);
|
void onDestroyWindow(HWND hwnd);
|
||||||
void onGetMinMaxInfo(MINMAXINFO& mmi);
|
void onGetMinMaxInfo(MINMAXINFO& mmi);
|
||||||
@ -146,19 +144,6 @@ namespace
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WM_NULL:
|
|
||||||
if (WM_GETTEXT == wParam && reinterpret_cast<LPARAM>(&g_dummyWindowText) == lParam)
|
|
||||||
{
|
|
||||||
auto presentationWindow = Gdi::Window::getPresentationWindow(hwnd);
|
|
||||||
if (presentationWindow)
|
|
||||||
{
|
|
||||||
std::wstring windowText(L"[DDrawCompat] " + getWindowText(hwnd, wndProc));
|
|
||||||
SendMessageW(presentationWindow, WM_SETTEXT, 0, reinterpret_cast<LPARAM>(windowText.c_str()));
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case WM_SYNCPAINT:
|
case WM_SYNCPAINT:
|
||||||
if (Gdi::Window::isTopLevelWindow(hwnd))
|
if (Gdi::Window::isTopLevelWindow(hwnd))
|
||||||
{
|
{
|
||||||
@ -412,25 +397,6 @@ namespace
|
|||||||
return it != g_windowProc.end() ? it->second : WindowProc{};
|
return it != g_windowProc.end() ? it->second : WindowProc{};
|
||||||
}
|
}
|
||||||
|
|
||||||
std::wstring getWindowText(HWND hwnd, WNDPROC wndProc)
|
|
||||||
{
|
|
||||||
const UINT MAX_LEN = 256;
|
|
||||||
if (IsWindowUnicode(hwnd))
|
|
||||||
{
|
|
||||||
wchar_t windowText[MAX_LEN] = {};
|
|
||||||
CallWindowProcW(wndProc, hwnd, WM_GETTEXT, MAX_LEN, reinterpret_cast<LPARAM>(windowText));
|
|
||||||
windowText[MAX_LEN - 1] = 0;
|
|
||||||
return windowText;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
char windowText[MAX_LEN] = {};
|
|
||||||
CallWindowProcA(wndProc, hwnd, WM_GETTEXT, MAX_LEN, reinterpret_cast<LPARAM>(windowText));
|
|
||||||
windowText[MAX_LEN - 1] = 0;
|
|
||||||
return std::wstring(windowText, windowText + strlen(windowText));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template <auto func, typename... Params>
|
template <auto func, typename... Params>
|
||||||
int WINAPI messageBox(Params... params)
|
int WINAPI messageBox(Params... params)
|
||||||
{
|
{
|
||||||
@ -813,7 +779,11 @@ namespace
|
|||||||
case EVENT_OBJECT_NAMECHANGE:
|
case EVENT_OBJECT_NAMECHANGE:
|
||||||
if (OBJID_WINDOW == idObject && Gdi::Window::isTopLevelWindow(hwnd) && !Gdi::GuiThread::isGuiThreadWindow(hwnd))
|
if (OBJID_WINDOW == idObject && Gdi::Window::isTopLevelWindow(hwnd) && !Gdi::GuiThread::isGuiThreadWindow(hwnd))
|
||||||
{
|
{
|
||||||
Gdi::WinProc::updatePresentationWindowText(hwnd);
|
auto presentationWindow = Gdi::Window::getPresentationWindow(hwnd);
|
||||||
|
if (presentationWindow)
|
||||||
|
{
|
||||||
|
Gdi::Window::updatePresentationWindowText(presentationWindow);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1038,11 +1008,6 @@ namespace Gdi
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void updatePresentationWindowText(HWND owner)
|
|
||||||
{
|
|
||||||
SendNotifyMessageW(owner, WM_NULL, WM_GETTEXT, reinterpret_cast<LPARAM>(&g_dummyWindowText));
|
|
||||||
}
|
|
||||||
|
|
||||||
void watchWindowPosChanges(WindowPosChangeNotifyFunc notifyFunc)
|
void watchWindowPosChanges(WindowPosChangeNotifyFunc notifyFunc)
|
||||||
{
|
{
|
||||||
g_windowPosChangeNotifyFuncs.insert(notifyFunc);
|
g_windowPosChangeNotifyFuncs.insert(notifyFunc);
|
||||||
|
@ -290,7 +290,7 @@ namespace
|
|||||||
if (!isLayered)
|
if (!isLayered)
|
||||||
{
|
{
|
||||||
it->second.presentationWindow = Gdi::PresentationWindow::create(hwnd);
|
it->second.presentationWindow = Gdi::PresentationWindow::create(hwnd);
|
||||||
Gdi::WinProc::updatePresentationWindowText(hwnd);
|
Gdi::Window::updatePresentationWindowText(it->second.presentationWindow);
|
||||||
}
|
}
|
||||||
else if (it->second.presentationWindow)
|
else if (it->second.presentationWindow)
|
||||||
{
|
{
|
||||||
@ -662,7 +662,7 @@ namespace Gdi
|
|||||||
|
|
||||||
if (it->second.presentationWindow)
|
if (it->second.presentationWindow)
|
||||||
{
|
{
|
||||||
Gdi::WinProc::updatePresentationWindowText(hwnd);
|
updatePresentationWindowText(it->second.presentationWindow);
|
||||||
Gdi::GuiThread::setWindowRgn(it->second.presentationWindow, getWindowRgn(hwnd));
|
Gdi::GuiThread::setWindowRgn(it->second.presentationWindow, getWindowRgn(hwnd));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -729,6 +729,11 @@ namespace Gdi
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void updatePresentationWindowText(HWND presentationWindow)
|
||||||
|
{
|
||||||
|
PostMessageW(presentationWindow, WM_NULL, WM_GETTEXT, WM_SETTEXT);
|
||||||
|
}
|
||||||
|
|
||||||
void updateWindowPos(HWND hwnd)
|
void updateWindowPos(HWND hwnd)
|
||||||
{
|
{
|
||||||
if (IsWindowVisible(hwnd) && !IsIconic(hwnd))
|
if (IsWindowVisible(hwnd) && !IsIconic(hwnd))
|
||||||
|
@ -33,6 +33,7 @@ namespace Gdi
|
|||||||
void updateLayeredWindowInfo(HWND hwnd, HDC hdcSrc, const POINT* pptSrc,
|
void updateLayeredWindowInfo(HWND hwnd, HDC hdcSrc, const POINT* pptSrc,
|
||||||
COLORREF colorKey, BYTE alpha, BYTE alphaFormat);
|
COLORREF colorKey, BYTE alpha, BYTE alphaFormat);
|
||||||
void updatePresentationWindowPos(HWND presentationWindow, HWND owner);
|
void updatePresentationWindowPos(HWND presentationWindow, HWND owner);
|
||||||
|
void updatePresentationWindowText(HWND presentationWindow);
|
||||||
void updateWindowPos(HWND hwnd);
|
void updateWindowPos(HWND hwnd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user