Qt or Win32 to obtain notification events for Windows or other systems, users manually switch dark/light mode?

431 views Asked by At

Many articles I read are polling the registry and so on. Is there no corresponding notification event that can be obtained by C/C++?

1

There are 1 answers

5
selbie On BEST ANSWER

In Win32, have a native top-level window (which can be hidden) on your main UI thread listening for WM_SETTINGCHANGE and WM_SYSCOLORCHANGE messages. When you get either event, repoll for screen resolution and desktop color settings.

It's not just light-mode and dark mode you want to monitor for. Also be on the lookout if the user enables a "high contrast" mode.

Here's some sample code you can start with:


struct MyCallback
{
    void OnSettingChange()
    {
        // put your code here
        OutputDebugString(L"OnSettingsChange occurred\r\n");

    }
    void OnColorChange()
    {
        // put your code here
        OutputDebugString(L"OnColorChange occurred\r\n");
    }
};

LRESULT __stdcall HiddenWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    MyCallback* pCallback = (MyCallback*)GetWindowLongPtr(hWnd, GWLP_USERDATA);

    switch (uMsg)
    {
        case WM_CREATE:
        {
            CREATESTRUCT* pCreateData = (CREATESTRUCT*)lParam;
            SetWindowLongPtr(hWnd, GWLP_USERDATA, (LONG)(pCreateData->lpCreateParams));
            return 0;
        }

        case WM_PAINT:
        {
            PAINTSTRUCT ps = {};
            BeginPaint(hWnd, &ps);
            EndPaint(hWnd, &ps);
            return 0;
        }

        case WM_SETTINGCHANGE:
        {
            pCallback->OnSettingChange();
            return 0;
        }
        case WM_SYSCOLORCHANGE:
        {
            pCallback->OnColorChange();
            return 0;
        }
        default:
        {
            return DefWindowProc(hWnd, uMsg, wParam, lParam);
        }
    }

    return 0;
}



HWND CreateHiddenWindow(HINSTANCE hInstance, MyCallback* pCallback)
{
    const wchar_t* CLASSNAME = L"Windows class: 4F98C893-A9E1-4AC4-8E60-68CC220510A7"; // replace with your unique name or guid
    WNDCLASSEXW wcex = {};
    wcex.cbSize = sizeof(wcex);
    wcex.style = CS_HREDRAW | CS_VREDRAW;
    wcex.lpfnWndProc = HiddenWindowProc;
    wcex.lpszClassName = CLASSNAME; 
    wcex.hInstance = hInstance;
    RegisterClassEx(&wcex);

    HWND hWnd = CreateWindow(CLASSNAME, L"Hidden", 0, 0, 0, 0, 0, NULL, NULL, hInstance, pCallback);

    return hWnd;
}