mirror of
https://github.com/narzoul/DDrawCompat
synced 2024-12-30 08:55:36 +01:00
Minimize invalidation on window position changes
This commit is contained in:
parent
0244c8c022
commit
1ab496cbf5
@ -602,7 +602,7 @@ HRESULT STDMETHODCALLTYPE CompatDirectDrawSurface<TSurface>::Restore(TSurface* T
|
||||
result = RealPrimarySurface::restore();
|
||||
if (wasLost)
|
||||
{
|
||||
CompatGdi::invalidate();
|
||||
CompatGdi::invalidate(nullptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -58,14 +58,33 @@ namespace
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
BOOL CALLBACK invalidateWindow(HWND hwnd, LPARAM /*lParam*/)
|
||||
BOOL CALLBACK invalidateWindow(HWND hwnd, LPARAM lParam)
|
||||
{
|
||||
if (!IsWindowVisible(hwnd))
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
DWORD processId = 0;
|
||||
GetWindowThreadProcessId(hwnd, &processId);
|
||||
if (processId == GetCurrentProcessId())
|
||||
if (processId != GetCurrentProcessId())
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (lParam)
|
||||
{
|
||||
POINT origin = {};
|
||||
ClientToScreen(hwnd, &origin);
|
||||
RECT rect = *reinterpret_cast<const RECT*>(lParam);
|
||||
OffsetRect(&rect, -origin.x, -origin.y);
|
||||
RedrawWindow(hwnd, &rect, nullptr, RDW_ERASE | RDW_FRAME | RDW_INVALIDATE | RDW_ALLCHILDREN);
|
||||
}
|
||||
else
|
||||
{
|
||||
RedrawWindow(hwnd, nullptr, nullptr, RDW_ERASE | RDW_FRAME | RDW_INVALIDATE | RDW_ALLCHILDREN);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -237,9 +256,9 @@ namespace CompatGdi
|
||||
}
|
||||
}
|
||||
|
||||
void invalidate()
|
||||
void invalidate(const RECT* rect)
|
||||
{
|
||||
EnumWindows(&invalidateWindow, 0);
|
||||
EnumWindows(&invalidateWindow, reinterpret_cast<LPARAM>(rect));
|
||||
}
|
||||
|
||||
void updatePalette()
|
||||
@ -257,7 +276,7 @@ namespace CompatGdi
|
||||
|
||||
if (0 != memcmp(usedPaletteEntries, g_usedPaletteEntries, sizeof(usedPaletteEntries)))
|
||||
{
|
||||
invalidate();
|
||||
invalidate(nullptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -45,6 +45,6 @@ namespace CompatGdi
|
||||
}
|
||||
|
||||
void installHooks();
|
||||
void invalidate();
|
||||
void invalidate(const RECT* rect);
|
||||
void updatePalette();
|
||||
};
|
||||
|
@ -1,5 +1,7 @@
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
|
||||
#include <unordered_map>
|
||||
|
||||
#include <dwmapi.h>
|
||||
#include <Windows.h>
|
||||
|
||||
@ -12,9 +14,13 @@
|
||||
|
||||
namespace
|
||||
{
|
||||
std::unordered_map<HWND, RECT> g_prevWindowRect;
|
||||
|
||||
void disableDwmAttributes(HWND hwnd);
|
||||
void eraseBackground(HWND hwnd, HDC dc);
|
||||
void ncPaint(HWND hwnd);
|
||||
void onWindowPosChanged(HWND hwnd);
|
||||
void removeDropShadow(HWND hwnd);
|
||||
void updateScrolledWindow(HWND hwnd);
|
||||
|
||||
LRESULT CALLBACK callWndRetProc(int nCode, WPARAM wParam, LPARAM lParam)
|
||||
@ -25,6 +31,12 @@ namespace
|
||||
if (WM_CREATE == ret->message)
|
||||
{
|
||||
disableDwmAttributes(ret->hwnd);
|
||||
removeDropShadow(ret->hwnd);
|
||||
}
|
||||
else if (WM_DESTROY == ret->message)
|
||||
{
|
||||
CompatGdi::GdiScopedThreadLock lock;
|
||||
g_prevWindowRect.erase(ret->hwnd);
|
||||
}
|
||||
else if (WM_ERASEBKGND == ret->message)
|
||||
{
|
||||
@ -42,7 +54,7 @@ namespace
|
||||
}
|
||||
else if (WM_WINDOWPOSCHANGED == ret->message)
|
||||
{
|
||||
CompatGdi::invalidate();
|
||||
onWindowPosChanged(ret->hwnd);
|
||||
}
|
||||
else if (WM_VSCROLL == ret->message || WM_HSCROLL == ret->message)
|
||||
{
|
||||
@ -201,6 +213,36 @@ namespace
|
||||
}
|
||||
}
|
||||
|
||||
void onWindowPosChanged(HWND hwnd)
|
||||
{
|
||||
CompatGdi::GdiScopedThreadLock lock;
|
||||
|
||||
const auto it = g_prevWindowRect.find(hwnd);
|
||||
if (it != g_prevWindowRect.end())
|
||||
{
|
||||
CompatGdi::invalidate(&it->second);
|
||||
}
|
||||
|
||||
if (IsWindowVisible(hwnd))
|
||||
{
|
||||
GetWindowRect(hwnd, it != g_prevWindowRect.end() ? &it->second : &g_prevWindowRect[hwnd]);
|
||||
RedrawWindow(hwnd, nullptr, nullptr, RDW_ERASE | RDW_FRAME | RDW_INVALIDATE | RDW_ALLCHILDREN);
|
||||
}
|
||||
else if (it != g_prevWindowRect.end())
|
||||
{
|
||||
g_prevWindowRect.erase(it);
|
||||
}
|
||||
}
|
||||
|
||||
void removeDropShadow(HWND hwnd)
|
||||
{
|
||||
const auto style = GetClassLongPtr(hwnd, GCL_STYLE);
|
||||
if (style & CS_DROPSHADOW)
|
||||
{
|
||||
SetClassLongPtr(hwnd, GCL_STYLE, style ^ CS_DROPSHADOW);
|
||||
}
|
||||
}
|
||||
|
||||
void updateScrolledWindow(HWND hwnd)
|
||||
{
|
||||
RedrawWindow(hwnd, nullptr, nullptr, RDW_ERASE | RDW_FRAME | RDW_INVALIDATE);
|
||||
|
Loading…
x
Reference in New Issue
Block a user