mirror of
https://github.com/narzoul/DDrawCompat
synced 2024-12-30 08:55:36 +01:00
Added manual rendering of title bars
This commit is contained in:
parent
93e06700c1
commit
ab35223c2f
139
DDrawCompat/CompatGdiTitleBar.cpp
Normal file
139
DDrawCompat/CompatGdiTitleBar.cpp
Normal file
@ -0,0 +1,139 @@
|
|||||||
|
#include "CompatGdi.h"
|
||||||
|
#include "CompatGdiTitleBar.h"
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
enum TitleBarInfoIndex
|
||||||
|
{
|
||||||
|
TBII_TITLEBAR = 0,
|
||||||
|
TBII_MINIMIZE_BUTTON = 2,
|
||||||
|
TBII_MAXIMIZE_BUTTON = 3,
|
||||||
|
TBII_HELP_BUTTON = 4,
|
||||||
|
TBII_CLOSE_BUTTON = 5
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace CompatGdi
|
||||||
|
{
|
||||||
|
TitleBar::TitleBar(HWND hwnd, HDC compatDc) :
|
||||||
|
m_hwnd(hwnd), m_compatDc(compatDc), m_buttonWidth(0), m_buttonHeight(0), m_tbi(),
|
||||||
|
m_hasTitleBar(false), m_isToolWindow(false)
|
||||||
|
{
|
||||||
|
m_hasTitleBar = 0 != (GetWindowLongPtr(hwnd, GWL_STYLE) & WS_CAPTION);
|
||||||
|
if (!m_hasTitleBar)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_tbi.cbSize = sizeof(m_tbi);
|
||||||
|
SendMessage(hwnd, WM_GETTITLEBARINFOEX, 0, reinterpret_cast<LPARAM>(&m_tbi));
|
||||||
|
m_hasTitleBar = !IsRectEmpty(&m_tbi.rcTitleBar);
|
||||||
|
if (!m_hasTitleBar)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
POINT origin = {};
|
||||||
|
ClientToScreen(hwnd, &origin);
|
||||||
|
m_tbi.rcTitleBar.left = origin.x;
|
||||||
|
|
||||||
|
RECT windowRect = {};
|
||||||
|
GetWindowRect(hwnd, &windowRect);
|
||||||
|
OffsetRect(&m_tbi.rcTitleBar, -windowRect.left, -windowRect.top);
|
||||||
|
|
||||||
|
m_isToolWindow = 0 != (GetWindowLongPtr(hwnd, GWL_EXSTYLE) & WS_EX_TOOLWINDOW);
|
||||||
|
m_buttonWidth = GetSystemMetrics(m_isToolWindow ? SM_CXSMSIZE : SM_CXSIZE) - 2;
|
||||||
|
m_buttonHeight = GetSystemMetrics(m_isToolWindow ? SM_CYSMSIZE : SM_CYSIZE) - 4;
|
||||||
|
|
||||||
|
for (std::size_t i = TBII_MINIMIZE_BUTTON; i <= TBII_CLOSE_BUTTON; ++i)
|
||||||
|
{
|
||||||
|
if (isVisible(i))
|
||||||
|
{
|
||||||
|
OffsetRect(&m_tbi.rgrect[i], -windowRect.left, -windowRect.top);
|
||||||
|
adjustButtonSize(m_tbi.rgrect[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void TitleBar::adjustButtonSize(RECT& rect) const
|
||||||
|
{
|
||||||
|
rect.left += (rect.right - rect.left - m_buttonWidth) / 2;
|
||||||
|
rect.top += (rect.bottom - rect.top - m_buttonHeight) / 2;
|
||||||
|
rect.right = rect.left + m_buttonWidth;
|
||||||
|
rect.bottom = rect.top + m_buttonHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TitleBar::drawAll() const
|
||||||
|
{
|
||||||
|
drawCaption();
|
||||||
|
drawButtons();
|
||||||
|
}
|
||||||
|
|
||||||
|
void TitleBar::drawButtons() const
|
||||||
|
{
|
||||||
|
if (!m_hasTitleBar)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
drawButton(TBII_MINIMIZE_BUTTON, DFCS_CAPTIONMIN);
|
||||||
|
drawButton(TBII_MAXIMIZE_BUTTON, IsZoomed(m_hwnd) ? DFCS_CAPTIONRESTORE : DFCS_CAPTIONMAX);
|
||||||
|
drawButton(TBII_HELP_BUTTON, DFCS_CAPTIONHELP);
|
||||||
|
drawButton(TBII_CLOSE_BUTTON, DFCS_CAPTIONCLOSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TitleBar::drawCaption() const
|
||||||
|
{
|
||||||
|
if (!m_hasTitleBar)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
UINT flags = DC_ICON | DC_TEXT;
|
||||||
|
if (GetActiveWindow() == m_hwnd)
|
||||||
|
{
|
||||||
|
flags |= DC_ACTIVE;
|
||||||
|
}
|
||||||
|
if (m_isToolWindow)
|
||||||
|
{
|
||||||
|
flags |= DC_SMALLCAP;
|
||||||
|
}
|
||||||
|
|
||||||
|
CALL_ORIG_GDI(DrawCaption)(m_hwnd, m_compatDc, &m_tbi.rcTitleBar, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TitleBar::drawButton(std::size_t tbiIndex, UINT dfcState) const
|
||||||
|
{
|
||||||
|
if (!isVisible(tbiIndex))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
DWORD stateFlags = 0;
|
||||||
|
if (m_tbi.rgstate[tbiIndex] & STATE_SYSTEM_UNAVAILABLE)
|
||||||
|
{
|
||||||
|
stateFlags |= DFCS_INACTIVE;
|
||||||
|
}
|
||||||
|
else if (m_tbi.rgstate[tbiIndex] & STATE_SYSTEM_PRESSED)
|
||||||
|
{
|
||||||
|
stateFlags |= DFCS_PUSHED;
|
||||||
|
}
|
||||||
|
|
||||||
|
RECT rect = m_tbi.rgrect[tbiIndex];
|
||||||
|
CALL_ORIG_GDI(DrawFrameControl)(m_compatDc, &rect, DFC_CAPTION, dfcState | stateFlags);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TitleBar::excludeFromClipRegion() const
|
||||||
|
{
|
||||||
|
if (m_hasTitleBar)
|
||||||
|
{
|
||||||
|
const RECT& r = m_tbi.rcTitleBar;
|
||||||
|
ExcludeClipRect(m_compatDc, r.left, r.top, r.right, r.bottom);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TitleBar::isVisible(std::size_t tbiIndex) const
|
||||||
|
{
|
||||||
|
return !(m_tbi.rgstate[tbiIndex] & (STATE_SYSTEM_INVISIBLE | STATE_SYSTEM_OFFSCREEN));
|
||||||
|
}
|
||||||
|
}
|
34
DDrawCompat/CompatGdiTitleBar.h
Normal file
34
DDrawCompat/CompatGdiTitleBar.h
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#define WIN32_LEAN_AND_MEAN
|
||||||
|
|
||||||
|
#include <cstddef>
|
||||||
|
|
||||||
|
#include <Windows.h>
|
||||||
|
|
||||||
|
namespace CompatGdi
|
||||||
|
{
|
||||||
|
class TitleBar
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
TitleBar(HWND hwnd, HDC compatDc);
|
||||||
|
|
||||||
|
void drawAll() const;
|
||||||
|
void drawButtons() const;
|
||||||
|
void drawCaption() const;
|
||||||
|
void excludeFromClipRegion() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void adjustButtonSize(RECT& rect) const;
|
||||||
|
void drawButton(std::size_t tbiIndex, UINT dfcState) const;
|
||||||
|
bool isVisible(std::size_t tbiIndex) const;
|
||||||
|
|
||||||
|
HWND m_hwnd;
|
||||||
|
HDC m_compatDc;
|
||||||
|
int m_buttonWidth;
|
||||||
|
int m_buttonHeight;
|
||||||
|
TITLEBARINFOEX m_tbi;
|
||||||
|
bool m_hasTitleBar;
|
||||||
|
bool m_isToolWindow;
|
||||||
|
};
|
||||||
|
}
|
@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
#include "CompatGdi.h"
|
#include "CompatGdi.h"
|
||||||
#include "CompatGdiDc.h"
|
#include "CompatGdiDc.h"
|
||||||
|
#include "CompatGdiTitleBar.h"
|
||||||
#include "CompatGdiWinProc.h"
|
#include "CompatGdiWinProc.h"
|
||||||
#include "DDrawLog.h"
|
#include "DDrawLog.h"
|
||||||
|
|
||||||
@ -137,7 +138,7 @@ namespace
|
|||||||
|
|
||||||
void ncPaint(HWND hwnd)
|
void ncPaint(HWND hwnd)
|
||||||
{
|
{
|
||||||
if (!CompatGdi::beginGdiRendering())
|
if (!hwnd || !CompatGdi::beginGdiRendering())
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -154,6 +155,10 @@ namespace
|
|||||||
POINT clientOrigin = {};
|
POINT clientOrigin = {};
|
||||||
ClientToScreen(hwnd, &clientOrigin);
|
ClientToScreen(hwnd, &clientOrigin);
|
||||||
|
|
||||||
|
CompatGdi::TitleBar titleBar(hwnd, compatDc);
|
||||||
|
titleBar.drawAll();
|
||||||
|
titleBar.excludeFromClipRegion();
|
||||||
|
|
||||||
OffsetRect(&clientRect, clientOrigin.x - windowRect.left, clientOrigin.y - windowRect.top);
|
OffsetRect(&clientRect, clientOrigin.x - windowRect.left, clientOrigin.y - windowRect.top);
|
||||||
ExcludeClipRect(compatDc, clientRect.left, clientRect.top, clientRect.right, clientRect.bottom);
|
ExcludeClipRect(compatDc, clientRect.left, clientRect.top, clientRect.right, clientRect.bottom);
|
||||||
CALL_ORIG_GDI(BitBlt)(compatDc, 0, 0,
|
CALL_ORIG_GDI(BitBlt)(compatDc, 0, 0,
|
||||||
@ -168,6 +173,35 @@ namespace
|
|||||||
CompatGdi::endGdiRendering();
|
CompatGdi::endGdiRendering();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CALLBACK objectStateChangeEvent(
|
||||||
|
HWINEVENTHOOK /*hWinEventHook*/,
|
||||||
|
DWORD /*event*/,
|
||||||
|
HWND hwnd,
|
||||||
|
LONG idObject,
|
||||||
|
LONG /*idChild*/,
|
||||||
|
DWORD /*dwEventThread*/,
|
||||||
|
DWORD /*dwmsEventTime*/)
|
||||||
|
{
|
||||||
|
if (OBJID_TITLEBAR == idObject)
|
||||||
|
{
|
||||||
|
if (!hwnd || !CompatGdi::beginGdiRendering())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
HDC windowDc = GetWindowDC(hwnd);
|
||||||
|
HDC compatDc = CompatGdiDc::getDc(windowDc);
|
||||||
|
if (compatDc)
|
||||||
|
{
|
||||||
|
CompatGdi::TitleBar(hwnd, compatDc).drawAll();
|
||||||
|
CompatGdiDc::releaseDc(windowDc);
|
||||||
|
}
|
||||||
|
|
||||||
|
ReleaseDC(hwnd, windowDc);
|
||||||
|
CompatGdi::endGdiRendering();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void updateScrolledWindow(HWND hwnd)
|
void updateScrolledWindow(HWND hwnd)
|
||||||
{
|
{
|
||||||
RedrawWindow(hwnd, nullptr, nullptr, RDW_ERASE | RDW_FRAME | RDW_INVALIDATE);
|
RedrawWindow(hwnd, nullptr, nullptr, RDW_ERASE | RDW_FRAME | RDW_INVALIDATE);
|
||||||
@ -181,5 +215,7 @@ namespace CompatGdiWinProc
|
|||||||
const DWORD threadId = GetCurrentThreadId();
|
const DWORD threadId = GetCurrentThreadId();
|
||||||
SetWindowsHookEx(WH_CALLWNDPROCRET, callWndRetProc, nullptr, threadId);
|
SetWindowsHookEx(WH_CALLWNDPROCRET, callWndRetProc, nullptr, threadId);
|
||||||
SetWindowsHookEx(WH_MOUSE, &mouseProc, nullptr, threadId);
|
SetWindowsHookEx(WH_MOUSE, &mouseProc, nullptr, threadId);
|
||||||
|
SetWinEventHook(EVENT_OBJECT_STATECHANGE, EVENT_OBJECT_STATECHANGE,
|
||||||
|
nullptr, &objectStateChangeEvent, 0, threadId, WINEVENT_OUTOFCONTEXT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -150,6 +150,7 @@
|
|||||||
<ClInclude Include="CompatGdiDc.h" />
|
<ClInclude Include="CompatGdiDc.h" />
|
||||||
<ClInclude Include="CompatGdiDcCache.h" />
|
<ClInclude Include="CompatGdiDcCache.h" />
|
||||||
<ClInclude Include="CompatGdiFunctions.h" />
|
<ClInclude Include="CompatGdiFunctions.h" />
|
||||||
|
<ClInclude Include="CompatGdiTitleBar.h" />
|
||||||
<ClInclude Include="CompatGdiWinProc.h" />
|
<ClInclude Include="CompatGdiWinProc.h" />
|
||||||
<ClInclude Include="Config.h" />
|
<ClInclude Include="Config.h" />
|
||||||
<ClInclude Include="DDrawProcs.h" />
|
<ClInclude Include="DDrawProcs.h" />
|
||||||
@ -175,6 +176,7 @@
|
|||||||
<ClCompile Include="CompatGdiCaret.cpp" />
|
<ClCompile Include="CompatGdiCaret.cpp" />
|
||||||
<ClCompile Include="CompatGdiDcCache.cpp" />
|
<ClCompile Include="CompatGdiDcCache.cpp" />
|
||||||
<ClCompile Include="CompatGdiFunctions.cpp" />
|
<ClCompile Include="CompatGdiFunctions.cpp" />
|
||||||
|
<ClCompile Include="CompatGdiTitleBar.cpp" />
|
||||||
<ClCompile Include="CompatGdiWinProc.cpp" />
|
<ClCompile Include="CompatGdiWinProc.cpp" />
|
||||||
<ClCompile Include="CompatVtable.cpp" />
|
<ClCompile Include="CompatVtable.cpp" />
|
||||||
<ClCompile Include="DDrawLog.cpp" />
|
<ClCompile Include="DDrawLog.cpp" />
|
||||||
|
@ -81,6 +81,9 @@
|
|||||||
<ClInclude Include="CompatGdiCaret.h">
|
<ClInclude Include="CompatGdiCaret.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="CompatGdiTitleBar.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="DllMain.cpp">
|
<ClCompile Include="DllMain.cpp">
|
||||||
@ -134,6 +137,9 @@
|
|||||||
<ClCompile Include="CompatGdiCaret.cpp">
|
<ClCompile Include="CompatGdiCaret.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="CompatGdiTitleBar.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="DDrawCompat.def">
|
<None Include="DDrawCompat.def">
|
||||||
|
Loading…
x
Reference in New Issue
Block a user