c++mfcscrollbardarkmodecmfcpropertygridctrl

Assigning dark scrollbars to a CMFCPropertyGrid


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:

enter image description here

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);
            }
        }
    }
}

Using Spy++

Spy++ confirms that the vertical scrollbar has a ScrollBar class name.

if (wcscmp(classList, L"ScrollBar") == 0)

Solution

  • 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!

    Dark Mode property grid with dark scrollbar