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

Added WM_PAINT handling for scroll bar controls

Now size box rendering works correctly, so no need for that workaround in
CompatGdiScrollBar.
There seems to be a bug with subclassing scroll bars though, as the cursor
will no longer change to a sizing arrow when it's over a size box control.
At least there is a simple workaround for that via WM_SETCURSOR.
This commit is contained in:
narzoul 2016-03-19 22:23:51 +01:00
parent 6850fc449c
commit 91a158020a
3 changed files with 58 additions and 57 deletions

View File

@ -18,6 +18,7 @@ namespace
WNDPROC g_origEditWndProc = nullptr;
WNDPROC g_origListBoxWndProc = nullptr;
WNDPROC g_origScrollBarWndProc = nullptr;
LRESULT WINAPI defDlgProcA(HWND hdlg, UINT msg, WPARAM wParam, LPARAM lParam)
{
@ -156,6 +157,33 @@ namespace
return 0;
}
LRESULT onPaint(HWND hwnd, WNDPROC origWndProc)
{
if (!hwnd || !CompatGdi::beginGdiRendering())
{
return origWndProc(hwnd, WM_PAINT, 0, 0);
}
PAINTSTRUCT paint = {};
HDC dc = BeginPaint(hwnd, &paint);
HDC compatDc = CompatGdiDc::getDc(dc);
if (compatDc)
{
origWndProc(hwnd, WM_PRINTCLIENT, reinterpret_cast<WPARAM>(compatDc), PRF_CLIENT);
CompatGdiDc::releaseDc(dc);
}
else
{
origWndProc(hwnd, WM_PRINTCLIENT, reinterpret_cast<WPARAM>(dc), PRF_CLIENT);
}
EndPaint(hwnd, &paint);
CompatGdi::endGdiRendering();
return 0;
}
LRESULT onPrint(HWND hwnd, UINT msg, HDC dc, LONG flags, WNDPROC origWndProc)
{
if (!CompatGdi::beginGdiRendering())
@ -178,6 +206,34 @@ namespace
CompatGdi::endGdiRendering();
return result;
}
LRESULT WINAPI scrollBarWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
Compat::LogEnter("scrollBarWndProc", hwnd, msg, wParam, lParam);
LRESULT result = 0;
switch (msg)
{
case WM_PAINT:
result = onPaint(hwnd, g_origScrollBarWndProc);
break;
case WM_SETCURSOR:
if (GetWindowLong(hwnd, GWL_STYLE) & (SBS_SIZEBOX | SBS_SIZEGRIP))
{
SetCursor(LoadCursor(nullptr, IDC_SIZENWSE));
}
result = TRUE;
break;
default:
result = g_origScrollBarWndProc(hwnd, msg, wParam, lParam);
break;
}
Compat::LogLeave("scrollBarWndProc", hwnd, msg, wParam, lParam) << result;
return result;
}
}
namespace CompatGdiPaintHandlers
@ -186,6 +242,7 @@ namespace CompatGdiPaintHandlers
{
CompatGdi::hookWndProc("Edit", g_origEditWndProc, &editWndProc);
CompatGdi::hookWndProc("ListBox", g_origListBoxWndProc, &listBoxWndProc);
CompatGdi::hookWndProc("ScrollBar", g_origScrollBarWndProc, &scrollBarWndProc);
DetourTransactionBegin();
HOOK_GDI_FUNCTION(user32, DefWindowProcA, defWindowProcA);

View File

@ -19,14 +19,12 @@ namespace CompatGdi
ScrollBar::ScrollBar(HWND hwnd, HDC compatDc) :
m_hwnd(hwnd), m_compatDc(compatDc), m_windowRect(),
m_isLeftMouseButtonDown(false), m_cursorPos(),
m_horizontalSbi(), m_verticalSbi(),
m_hasSizeBox(false), m_sizeBoxRect()
m_horizontalSbi(), m_verticalSbi()
{
const LONG windowStyle = GetWindowLongPtr(hwnd, GWL_STYLE);
m_horizontalSbi.isVisible = 0 != (windowStyle & WS_HSCROLL);
m_verticalSbi.isVisible = 0 != (windowStyle & WS_VSCROLL);
m_hasSizeBox = 0 != (windowStyle & WS_SIZEBOX);
GetWindowRect(hwnd, &m_windowRect);
@ -53,18 +51,12 @@ namespace CompatGdi
m_verticalSbi = getScrollBarInfo(OBJID_VSCROLL);
}
}
if (m_hasSizeBox)
{
m_sizeBoxRect = getSizeBoxRect();
}
}
void ScrollBar::drawAll() const
{
drawHorizArrows();
drawVertArrows();
drawSizeBox();
}
void ScrollBar::drawArrow(const ScrollBarChildInfo& sbci, UINT dfcState) const
@ -92,15 +84,6 @@ namespace CompatGdi
}
}
void ScrollBar::drawSizeBox() const
{
if (m_hasSizeBox)
{
RECT rect = m_sizeBoxRect;
CALL_ORIG_GDI(DrawFrameControl)(m_compatDc, &rect, DFC_SCROLL, DFCS_SCROLLSIZEGRIP);
}
}
void ScrollBar::drawVertArrows() const
{
if (m_verticalSbi.isVisible)
@ -128,11 +111,6 @@ namespace CompatGdi
{
excludeFromClipRegion(m_horizontalSbi);
excludeFromClipRegion(m_verticalSbi);
if (m_hasSizeBox)
{
excludeFromClipRegion(m_sizeBoxRect);
}
}
ScrollBar::ScrollBarInfo ScrollBar::getScrollBarInfo(LONG objId) const
@ -183,36 +161,6 @@ namespace CompatGdi
return scrollBarInfo;
}
RECT ScrollBar::getSizeBoxRect() const
{
RECT clientRect = {};
GetClientRect(m_hwnd, &clientRect);
POINT clientOrigin = {};
ClientToScreen(m_hwnd, &clientOrigin);
OffsetRect(&clientRect, clientOrigin.x - m_windowRect.left, clientOrigin.y - m_windowRect.top);
const int width = GetSystemMetrics(SM_CXVSCROLL);
const int height = GetSystemMetrics(SM_CYHSCROLL);
RECT sizeBoxRect = {};
if (m_horizontalSbi.isVisible && m_verticalSbi.isVisible)
{
sizeBoxRect.left = clientRect.right;
sizeBoxRect.top = clientRect.bottom;
}
else
{
sizeBoxRect.left = clientRect.right - width;
sizeBoxRect.top = clientRect.bottom - height;
}
sizeBoxRect.right = sizeBoxRect.left + width;
sizeBoxRect.bottom = sizeBoxRect.top + height;
return sizeBoxRect;
}
void ScrollBar::setPressedState(ScrollBarChildInfo& sbci) const
{
if (!(sbci.state & STATE_SYSTEM_UNAVAILABLE) && PtInRect(&sbci.rect, m_cursorPos))

View File

@ -13,7 +13,6 @@ namespace CompatGdi
void drawAll() const;
void drawHorizArrows() const;
void drawSizeBox() const;
void drawVertArrows() const;
void excludeFromClipRegion() const;
@ -35,7 +34,6 @@ namespace CompatGdi
void excludeFromClipRegion(const RECT& rect) const;
void excludeFromClipRegion(const ScrollBarInfo& sbi) const;
ScrollBarInfo getScrollBarInfo(LONG objId) const;
RECT getSizeBoxRect() const;
void setPressedState(ScrollBarChildInfo& sbci) const;
HWND m_hwnd;
@ -45,7 +43,5 @@ namespace CompatGdi
POINT m_cursorPos;
ScrollBarInfo m_horizontalSbi;
ScrollBarInfo m_verticalSbi;
bool m_hasSizeBox;
RECT m_sizeBoxRect;
};
}