获取有关 Windows 10 的 Revert/Keep 新显示设置对话框的通知

Get notification about Windows 10's Revert/Keep new display settings dialog

当用户在 Windows 10(甚至以前的版本更改显示设置)时,OS 会向他们提供选择是保留还是恢复更改。用户还获得了 15 秒 window。如果他们什么都不做,那么设置将被恢复。如果他们 select "Keep Changes" 或 "Revert",将采取适当的行动。我想在显示此对话框时收到 OS 的通知。

我监控了任务管理器中的所有进程,结果没有生成新进程。所以,我什至无法跟踪这个过程。这样做的可能方法是什么?我知道一种实现方式,监听 WM_DISPLAYCHANGE 事件。但这不是可靠的方法,因为给了用户 15 秒 window。基本上,我想在对话框出现和消失时收到通知。我有什么想法可以实现吗?

顺便说一句,我需要为 Windows 10 实现此功能。所以 Windows 10 条信息将是最有帮助的。谢谢!

尝试使用 FindWindowEx 找到 window,子 window 或主要 window 具有特定文本...

WM_DISPLAYCHANGE才是正确的做法。当分辨率真正改变时发送。也就是说,就在对话框出现之前,当您点击恢复时。如果您保持分辨率,则不会发送。

第 15 秒 window,带有保留和恢复按钮,是一个 #32770 对话框。当您使用 OS 对话框时,启动过程是 explorer.exe。它确实显示在我的 spyxx 上 - 见下文。只需在对话框显示时点击 Windows 按钮并查找它即可。

您可以在没有对话框的情况下更改分辨率。显卡通常有自己的软件,有或没有其他对话框。任何软件都可以使用 ChangeDisplaySettings.

更改分辨率

您可能可以找到 OS 对话框,但这会非常脆弱,所以我不推荐它。
如果你真的需要查看系统对话框,你可以在得到 WM_DISPLAYCHANGE.
时枚举所有顶级 windows 我猜你必须连续枚举至少一秒钟,然后寻找子 windows、字幕、类、window 位置(主屏幕中心)的模式。您必须针对每个 OS 版本和每种语言执行此操作。
您还可以在收到 WM_DISPLAYCHANGE 之前定期枚举 windows,然后在分辨率更改后查找顶层 windows 的更改。

编辑:
根据要求,这里有一些代码可以查看对话框:

std::map<std::string,int> windows;

BOOL CALLBACK onEnumWindow( HWND hwnd, LPARAM lParam )
{
    char buf[500];
    if( IsWindowVisible(hwnd) && GetWindowText(hwnd,buf,500) > 0 )
        windows[buf]++;
    return TRUE;
}

std::string getLayout()
{
    std::string layout;
    EnumWindows(onEnumWindow, 0);
    for( auto& w : windows ) {
        if( w.first == "Display Settings" ) layout += "**** ";
        layout += std::to_string(w.second) + "x " + w.first + "\n";
    }
    windows.clear();
    return layout;
}

int _tmain(int argc, _TCHAR* argv[])
{
    std::string layout0;
    for(;;) {
        std::string layout = getLayout();
        if( layout != layout0 ) { // <-- you should test that across res change
            printf("%s\n", layout.c_str());
            layout0 = layout;
        }
    }
    return 0;
}

这是它的输出:

1x C:\Users\yakov\Documents\Visual Studio 2013\Projects\desk\x64\Release\desk.exe
1x EnumWindows function (Windows) - Google Chrome
1x Program Manager
1x Screen Resolution
1x Start
1x desk (Running) - Microsoft Visual Studio

1x C:\Users\yakov\Documents\Visual Studio 2013\Projects\desk\x64\Release\desk.exe
**** 1x Display Settings
1x EnumWindows function (Windows) - Google Chrome
1x Program Manager
1x Screen Resolution
1x Start
1x desk (Running) - Microsoft Visual Studio

1x C:\Users\yakov\Documents\Visual Studio 2013\Projects\desk\x64\Release\desk.exe
1x EnumWindows function (Windows) - Google Chrome
1x Program Manager
1x Screen Resolution
1x Start
1x desk (Running) - Microsoft Visual Studio

另一件需要注意的事情 - 如果屏幕分辨率在 win10 或以后的 OSs 中触发 UAC,您将无法检测到对话框。您仍会收到有关分辨率更改的通知。
UAC 对话框无法检测到,因为它在只能由系统帐户访问的桌面中运行。