I have seen the repository on GitHub:
https://github.com/ysc3839/win32-darkmode
I implemented the FixDarkScrollBars
function in my test project. The good news is that it works for 99% of my dialog:
The only control that still has light scrollbars is the CMFCPropertyGrid
. Here is FixDarkScrollBar
:
void FixDarkScrollBar()
{
HMODULE hComctl = LoadLibraryExW(L"comctl32.dll", nullptr, LOAD_LIBRARY_SEARCH_SYSTEM32);
if (hComctl)
{
auto addr = FindDelayLoadThunkInModule(hComctl, "uxtheme.dll", 49); // OpenNcThemeData
if (addr)
{
DWORD oldProtect;
if (VirtualProtect(addr, sizeof(IMAGE_THUNK_DATA), PAGE_READWRITE, &oldProtect))
{
auto MyOpenThemeData = [](HWND hWnd, LPCWSTR classList) -> HTHEME {
if (wcscmp(classList, L"ScrollBar") == 0)
{
hWnd = nullptr;
classList = L"Explorer::ScrollBar";
}
return _OpenNcThemeData(hWnd, classList);
};
addr->u1.Function = reinterpret_cast<ULONG_PTR>(static_cast<fnOpenNcThemeData>(MyOpenThemeData));
VirtualProtect(addr, sizeof(IMAGE_THUNK_DATA), oldProtect, &oldProtect);
}
}
}
}
Spy++ confirms that the vertical scrollbar has a ScrollBar
class name.
FixDarkScrollbar
function, where it is looking for that class name:if (wcscmp(classList, L"ScrollBar") == 0)
CMFCPropertyGridCtrl::GetScrollBarCtrl
function returns a CScrollBar
.Turns out that there is a simple solution. IN the comments to my question I was encouraged to look at the original MFC source control (afxproperygridctrl.h
) and I could see that it has a scrollbar member variable:
CScrollBar m_wndScrollVert; // Vertical scroll bar
The vertical toolbar is created in the Init
function:
m_wndScrollVert.Create(WS_CHILD | WS_VISIBLE | SBS_VERT, rectDummy, this, AFX_ID_SCROLL_VERT);
So, I thought I would go back to basics:
auto pScrollBar = m_gridCtrl.GetScrollBarCtrl(SB_VERT);
if (pScrollBar)
{
SetWindowTheme(pScrollBar->GetSafeHwnd(), DarkModeTools::szDarkMode_Explorer, nullptr);
}
And, voila!