首页 > 解决方案 > 当窗口移动到另一个监视器时是否有通知?

问题描述

我有一个在IDXGISwapChain1关闭垂直同步的情况下刷新的窗口。如果可能,我想手动控制窗口的当前速率,使其尽可能接近当前显示器的刷新率。

在将具有不同刷新率的两台显示器连接到 PC 的情况下,我希望在窗口从一台显示器移动到另一台显示器时收到通知,以便我可以相应地更改当前的帧速率。

WM_DISPLAYCHANGEWM_DPICHANGED据我所知,可能无法涵盖这种情况。如果我错了,请纠正我。

更新: 这是我根据 Strive 的回答编写的代码,

LRESULT OnPositionChanged(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
    // Get the monitor handle for the window. 
    HMONITOR currentMonitor = MonitorFromWindow(m_hWnd, MONITOR_DEFAULTTONEAREST);
    // error handling

    // no need to bother if the window stays on the same monitor
    if (_currentMonitor != currentMonitor)
    {
        // Get more information about the monitor
        MONITORINFOEX monitorInfo;
        monitorInfo.cbSize = sizeof(MONITORINFOEX);
        BOOL succeed = GetMonitorInfo(currentMonitor, (LPMONITORINFO)&monitorInfo);
        // error handling

        // Get the current display settings for that monitor, which includes the refresh rate
        DEVMODE devMode;
        devMode.dmSize = sizeof(DEVMODE);
        succeed = EnumDisplaySettings(monitorInfo.szDevice, ENUM_CURRENT_SETTINGS, &devMode);
        // error handling

        // use devMode.dmDisplayFrequency to update my present frame rate
        // ...

        _currentMonitor = currentMonitor;
    }

    return 0L;
}

LRESULT OnDisplayChanged(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
    // WM_DISPLAYCHANGE message is sent to all windows when the display resolution has changed
    // When a WM_DISPLAYCHANGE message is sent, any monitor may be removed from the desktop and thus its HMONITOR becomes invalid or has its settings changed.

    _currentMonitor = NULL;

    return 0L;
}

我想在窗口改变位置后改变帧率,所以我切换到WM_WINDOWPOSCHANGED.

标签: windowswinapiwindow

解决方案


窗口位置改变后,您可以查看WM_WINDOWPOSCHANGING消息。

由于调用 SetWindowPos 函数或另一个窗口管理函数,发送到其大小、位置或 Z 顺序中的位置即将更改的窗口。

然后通过调用EnumDisplaySettings函数获取当前显示器的刷新赫兹。如果刷新频率发生变化,请更改应用程序的刷新频率。

dmDisplayFrequency :指定显示设备在特定模式下的频率,以赫兹(每秒周期数)为单位。该值也称为显示设备的垂直刷新率。显示驱动程序使用此成员。例如,在 ChangeDisplaySettings 函数中使用它。打印机驱动程序不使用该成员。

注意:您可以设置一个变量来保存之前显示的刷新频率,然后将该变量与当前显示的频率进行比较。如果不同,则表示 Hz 发生了变化。

如果需要确定窗口在哪个监视器上,可以使用MonitorFromWindow函数。

这是一个代码示例: 如何确定应用程序正在使用哪个监视器以及如何获取它的句柄?


推荐阅读