У меня есть программа без окон, которая обрабатывает некоторые горячие клавиши управления окнами. Я хотел бы предоставить такие функции, как возможность перемещения окна между мониторами. Я использовал EnumDisplayMonitors
перечислить все существующие мониторы в системе, и я написал код для обработки WM_DEVICECHANGE
, но я на самом деле не получаю сообщение.
Вот мой цикл сообщений:
// 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();
}
}
Программа компилируется и работает нормально, а горячие клавиши работают. После добавления или удаления монитора ничего не происходит. Окно сообщения, указывающее, что сообщение было получено, никогда не появляется.
Я полагаю, что я мог бы просто опрашивать конфигурацию монитора каждые 5 секунд, но это не правильный способ решения проблемы.
Нужно ли создавать окно для получения WM_DEVICECHANGE
? Потому что я не Горячие клавиши публикуют свои сообщения NULL
когда они запускаются, так как они не связаны с окном, чтобы обрабатываться основным потоком.
Вы должны создать окно, чтобы получить WM_DEVICECHANGE
сообщение.
WM_DEVICECHANGE
это сообщение, которое транслируется, SendMessage(HWND_BROADCAST,...)
стиль. Только окна верхнего уровня могут получить его. Окно не должно быть видимым, поэтому нет причин искать альтернативу.
RegisterDeviceNotification()
это альтернатива. Но это все еще нуждается в окне. Или дескриптор сервиса, но вы не хотите перемещать окна из сервиса. Они работают в изолированном сеансе со своим рабочим столом. Таким образом, создание окна является жестким требованием.
Других решений пока нет …