Many articles I read are polling the registry and so on. Is there no corresponding notification event that can be obtained by C/C ?
CodePudding user response:
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;
}
