如何检测添加的新监视器

How do I detect the addition of a new monitor?

本文关键字:添加 监视器 检测 何检测      更新时间:2023-10-16

我有一个处理一些窗口管理热键的无窗口程序。我希望提供一些功能,比如在监视器之间移动窗口的能力。我已经使用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()是另一种选择。但这仍需要一个窗口期。或者一个服务句柄,但是你不想从一个服务中移动窗口。它们与自己的桌面运行在一个独立的会话中。所以创建一个窗口是一个硬性要求。