mirror of
https://github.com/narzoul/DDrawCompat
synced 2024-12-30 08:55:36 +01:00
Added WM_PAINT handling for popup menus
This commit is contained in:
parent
91a158020a
commit
7c06d9440b
@ -87,7 +87,7 @@ namespace
|
|||||||
MoveToEx(compatDc.dc, currentPos.x, currentPos.y, nullptr);
|
MoveToEx(compatDc.dc, currentPos.x, currentPos.y, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL CALLBACK excludeClipRectsForOverlappingWindows(HWND hwnd, LPARAM lParam)
|
BOOL CALLBACK excludeClipRectForOverlappingWindow(HWND hwnd, LPARAM lParam)
|
||||||
{
|
{
|
||||||
auto excludeClipRectsData = reinterpret_cast<ExcludeClipRectsData*>(lParam);
|
auto excludeClipRectsData = reinterpret_cast<ExcludeClipRectsData*>(lParam);
|
||||||
if (hwnd == excludeClipRectsData->rootWnd)
|
if (hwnd == excludeClipRectsData->rootWnd)
|
||||||
@ -107,30 +107,58 @@ namespace
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setClippingRegion(HDC compatDc, HDC origDc, POINT& origin)
|
void excludeClipRectsForOverlappingWindows(
|
||||||
|
HWND hwnd, bool isMenuWindow, HDC compatDc, const POINT& origin)
|
||||||
{
|
{
|
||||||
HRGN clipRgn = CreateRectRgn(0, 0, 0, 0);
|
ExcludeClipRectsData excludeClipRectsData = { compatDc, origin, GetAncestor(hwnd, GA_ROOT) };
|
||||||
const bool isEmptyClipRgn = 1 != GetRandomRgn(origDc, clipRgn, SYSRGN);
|
if (!isMenuWindow)
|
||||||
SelectClipRgn(compatDc, isEmptyClipRgn ? nullptr : clipRgn);
|
|
||||||
DeleteObject(clipRgn);
|
|
||||||
|
|
||||||
HRGN origClipRgn = CreateRectRgn(0, 0, 0, 0);
|
|
||||||
if (1 == GetClipRgn(origDc, origClipRgn))
|
|
||||||
{
|
{
|
||||||
OffsetRgn(origClipRgn, origin.x, origin.y);
|
EnumWindows(&excludeClipRectForOverlappingWindow,
|
||||||
ExtSelectClipRgn(compatDc, origClipRgn, RGN_AND);
|
reinterpret_cast<LPARAM>(&excludeClipRectsData));
|
||||||
}
|
}
|
||||||
DeleteObject(origClipRgn);
|
|
||||||
|
|
||||||
if (!isEmptyClipRgn)
|
HWND menuWindow = FindWindow(reinterpret_cast<LPCSTR>(0x8000), nullptr);
|
||||||
|
while (menuWindow && menuWindow != hwnd)
|
||||||
{
|
{
|
||||||
HWND hwnd = WindowFromDC(origDc);
|
excludeClipRectForOverlappingWindow(
|
||||||
if (hwnd)
|
menuWindow, reinterpret_cast<LPARAM>(&excludeClipRectsData));
|
||||||
|
menuWindow = FindWindowEx(nullptr, menuWindow, reinterpret_cast<LPCSTR>(0x8000), nullptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void setClippingRegion(HDC compatDc, HDC origDc, const POINT& origin)
|
||||||
|
{
|
||||||
|
const HWND hwnd = WindowFromDC(origDc);
|
||||||
|
const bool isMenuWindow = hwnd && 0x8000 == GetClassLongPtr(hwnd, GCW_ATOM);
|
||||||
|
|
||||||
|
if (isMenuWindow)
|
||||||
|
{
|
||||||
|
RECT windowRect = {};
|
||||||
|
GetWindowRect(hwnd, &windowRect);
|
||||||
|
|
||||||
|
HRGN windowRgn = CreateRectRgnIndirect(&windowRect);
|
||||||
|
SelectClipRgn(compatDc, windowRgn);
|
||||||
|
DeleteObject(windowRgn);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
HRGN clipRgn = CreateRectRgn(0, 0, 0, 0);
|
||||||
|
const bool isEmptyClipRgn = 1 != GetRandomRgn(origDc, clipRgn, SYSRGN);
|
||||||
|
SelectClipRgn(compatDc, isEmptyClipRgn ? nullptr : clipRgn);
|
||||||
|
DeleteObject(clipRgn);
|
||||||
|
|
||||||
|
HRGN origClipRgn = CreateRectRgn(0, 0, 0, 0);
|
||||||
|
if (1 == GetClipRgn(origDc, origClipRgn))
|
||||||
{
|
{
|
||||||
ExcludeClipRectsData excludeClipRectsData = { compatDc, origin, GetAncestor(hwnd, GA_ROOT) };
|
OffsetRgn(origClipRgn, origin.x, origin.y);
|
||||||
EnumWindows(&excludeClipRectsForOverlappingWindows,
|
ExtSelectClipRgn(compatDc, origClipRgn, RGN_AND);
|
||||||
reinterpret_cast<LPARAM>(&excludeClipRectsData));
|
|
||||||
}
|
}
|
||||||
|
DeleteObject(origClipRgn);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hwnd)
|
||||||
|
{
|
||||||
|
excludeClipRectsForOverlappingWindows(hwnd, isMenuWindow, compatDc, origin);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,11 +13,14 @@ namespace
|
|||||||
LRESULT WINAPI eraseBackgroundProc(
|
LRESULT WINAPI eraseBackgroundProc(
|
||||||
HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam, WNDPROC origWndProc, const char* wndProcName);
|
HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam, WNDPROC origWndProc, const char* wndProcName);
|
||||||
LRESULT onEraseBackground(HWND hwnd, HDC dc, WNDPROC origWndProc);
|
LRESULT onEraseBackground(HWND hwnd, HDC dc, WNDPROC origWndProc);
|
||||||
|
LRESULT onMenuPaint(HWND hwnd, WNDPROC origWndProc);
|
||||||
LRESULT onNcPaint(HWND hwnd, WPARAM wParam, WNDPROC origWndProc);
|
LRESULT onNcPaint(HWND hwnd, WPARAM wParam, WNDPROC origWndProc);
|
||||||
|
LRESULT onPaint(HWND hwnd, WNDPROC origWndProc);
|
||||||
LRESULT onPrint(HWND hwnd, UINT msg, HDC dc, LONG flags, WNDPROC origWndProc);
|
LRESULT onPrint(HWND hwnd, UINT msg, HDC dc, LONG flags, WNDPROC origWndProc);
|
||||||
|
|
||||||
WNDPROC g_origEditWndProc = nullptr;
|
WNDPROC g_origEditWndProc = nullptr;
|
||||||
WNDPROC g_origListBoxWndProc = nullptr;
|
WNDPROC g_origListBoxWndProc = nullptr;
|
||||||
|
WNDPROC g_origMenuWndProc = nullptr;
|
||||||
WNDPROC g_origScrollBarWndProc = nullptr;
|
WNDPROC g_origScrollBarWndProc = nullptr;
|
||||||
|
|
||||||
LRESULT WINAPI defDlgProcA(HWND hdlg, UINT msg, WPARAM wParam, LPARAM lParam)
|
LRESULT WINAPI defDlgProcA(HWND hdlg, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||||
@ -104,6 +107,26 @@ namespace
|
|||||||
return eraseBackgroundProc(hwnd, msg, wParam, lParam, g_origListBoxWndProc, "listBoxWndProc");
|
return eraseBackgroundProc(hwnd, msg, wParam, lParam, g_origListBoxWndProc, "listBoxWndProc");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LRESULT WINAPI menuWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||||
|
{
|
||||||
|
Compat::LogEnter("menuWndProc", hwnd, msg, wParam, lParam);
|
||||||
|
LRESULT result = 0;
|
||||||
|
|
||||||
|
switch (msg)
|
||||||
|
{
|
||||||
|
case WM_PAINT:
|
||||||
|
result = onMenuPaint(hwnd, g_origMenuWndProc);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
result = g_origMenuWndProc(hwnd, msg, wParam, lParam);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
Compat::LogLeave("menuWndProc", hwnd, msg, wParam, lParam) << result;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
LRESULT onEraseBackground(HWND hwnd, HDC dc, WNDPROC origWndProc)
|
LRESULT onEraseBackground(HWND hwnd, HDC dc, WNDPROC origWndProc)
|
||||||
{
|
{
|
||||||
if (!hwnd || !CompatGdi::beginGdiRendering())
|
if (!hwnd || !CompatGdi::beginGdiRendering())
|
||||||
@ -157,6 +180,32 @@ namespace
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LRESULT onMenuPaint(HWND hwnd, WNDPROC origWndProc)
|
||||||
|
{
|
||||||
|
if (!hwnd || !CompatGdi::beginGdiRendering())
|
||||||
|
{
|
||||||
|
return origWndProc(hwnd, WM_PAINT, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
HDC dc = GetWindowDC(hwnd);
|
||||||
|
HDC compatDc = CompatGdiDc::getDc(dc);
|
||||||
|
if (compatDc)
|
||||||
|
{
|
||||||
|
origWndProc(hwnd, WM_PRINT, reinterpret_cast<WPARAM>(compatDc),
|
||||||
|
PRF_NONCLIENT | PRF_ERASEBKGND | PRF_CLIENT);
|
||||||
|
ValidateRect(hwnd, nullptr);
|
||||||
|
CompatGdiDc::releaseDc(dc);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
origWndProc(hwnd, WM_PAINT, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
ReleaseDC(hwnd, dc);
|
||||||
|
CompatGdi::endGdiRendering();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
LRESULT onPaint(HWND hwnd, WNDPROC origWndProc)
|
LRESULT onPaint(HWND hwnd, WNDPROC origWndProc)
|
||||||
{
|
{
|
||||||
if (!hwnd || !CompatGdi::beginGdiRendering())
|
if (!hwnd || !CompatGdi::beginGdiRendering())
|
||||||
@ -242,6 +291,7 @@ namespace CompatGdiPaintHandlers
|
|||||||
{
|
{
|
||||||
CompatGdi::hookWndProc("Edit", g_origEditWndProc, &editWndProc);
|
CompatGdi::hookWndProc("Edit", g_origEditWndProc, &editWndProc);
|
||||||
CompatGdi::hookWndProc("ListBox", g_origListBoxWndProc, &listBoxWndProc);
|
CompatGdi::hookWndProc("ListBox", g_origListBoxWndProc, &listBoxWndProc);
|
||||||
|
CompatGdi::hookWndProc("#32768", g_origMenuWndProc, &menuWndProc);
|
||||||
CompatGdi::hookWndProc("ScrollBar", g_origScrollBarWndProc, &scrollBarWndProc);
|
CompatGdi::hookWndProc("ScrollBar", g_origScrollBarWndProc, &scrollBarWndProc);
|
||||||
|
|
||||||
DetourTransactionBegin();
|
DetourTransactionBegin();
|
||||||
|
@ -18,6 +18,7 @@ namespace
|
|||||||
std::unordered_map<HWND, RECT> g_prevWindowRect;
|
std::unordered_map<HWND, RECT> g_prevWindowRect;
|
||||||
|
|
||||||
void disableDwmAttributes(HWND hwnd);
|
void disableDwmAttributes(HWND hwnd);
|
||||||
|
void onMenuSelect();
|
||||||
void onWindowPosChanged(HWND hwnd);
|
void onWindowPosChanged(HWND hwnd);
|
||||||
void removeDropShadow(HWND hwnd);
|
void removeDropShadow(HWND hwnd);
|
||||||
|
|
||||||
@ -55,6 +56,10 @@ namespace
|
|||||||
CompatGdiScrollFunctions::updateScrolledWindow(reinterpret_cast<HWND>(ret->lParam));
|
CompatGdiScrollFunctions::updateScrolledWindow(reinterpret_cast<HWND>(ret->lParam));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (WM_MENUSELECT == ret->message)
|
||||||
|
{
|
||||||
|
onMenuSelect();
|
||||||
|
}
|
||||||
else if (BM_SETSTYLE == ret->message)
|
else if (BM_SETSTYLE == ret->message)
|
||||||
{
|
{
|
||||||
RedrawWindow(ret->hwnd, nullptr, nullptr, RDW_ERASE | RDW_FRAME | RDW_INVALIDATE);
|
RedrawWindow(ret->hwnd, nullptr, nullptr, RDW_ERASE | RDW_FRAME | RDW_INVALIDATE);
|
||||||
@ -131,6 +136,16 @@ namespace
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void onMenuSelect()
|
||||||
|
{
|
||||||
|
HWND menuWindow = FindWindow(reinterpret_cast<LPCSTR>(0x8000), nullptr);
|
||||||
|
while (menuWindow)
|
||||||
|
{
|
||||||
|
RedrawWindow(menuWindow, nullptr, nullptr, RDW_INVALIDATE);
|
||||||
|
menuWindow = FindWindowEx(nullptr, menuWindow, reinterpret_cast<LPCSTR>(0x8000), nullptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void onWindowPosChanged(HWND hwnd)
|
void onWindowPosChanged(HWND hwnd)
|
||||||
{
|
{
|
||||||
CompatGdi::GdiScopedThreadLock lock;
|
CompatGdi::GdiScopedThreadLock lock;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user