I have a windowless program that handles some window management hotkeys. I'd like to provide features such as the ability to move a window between monitors. I've used EnumDisplayMonitors
to enumerate all existing monitors in the system, and I've written code to handle WM_DEVICECHANGE
, but I'm not actually receiving the message.
Here's my message loop:
// I've tried GetMessage(&msg, (HWND) NULL, 0, 0) here too
while (GetMessage(&msg, (HWND) -1, 0, 0) > 0)
{
int key;
int mod;
MessageBox(NULL, (LPCWSTR) ((std::wostringstream&) (std::wostringstream() << L"You got a message: " << msg.message)).str().c_str(), L"Got Message", MB_OK);
switch (msg.message)
{
case WM_HOTKEY:
key = HIWORD(msg.lParam);
mod = LOWORD(msg.lParam);
if (mod != MOD_WIN) continue;
ProcessHotkey(key);
break;
case WM_DEVICECHANGE:
InitMonitorInfo();
}
}
The program compiles and runs fine, and the hotkeys work. Upon adding or removing a monitor though, nothing happens. The message box to indicate a message has been received never appears.
I suppose I could just poll the monitor configuration every 5 seconds, but that's not the right way to solve the problem.
Do I need to actually create a window to receive WM_DEVICECHANGE
? Because I don't. The hotkeys post their messages to NULL
when they fire since they're not bound to a window, to be handled by the main thread.
You must create a window to get the WM_DEVICECHANGE
message.
WM_DEVICECHANGE
is a message that's broadcast, SendMessage(HWND_BROADCAST,...)
style. Only top-level windows can receive it. The window doesn't need to be visible so there's little reason to look for an alternative.
RegisterDeviceNotification()
is an alternative. But that still needs a window. Or a service handle, but you don't want to move windows around from a service. They run in an isolated session with their own desktop. So creating a window is a hard requirement.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With