c++ - 获取有关 Windows 10 的恢复/保留新显示设置对话框的通知

标签 c++ windows winapi hook windows-10

当 Windows 10 中的用户(甚至以前的版本更改显示设置)时,操作系统会向他们提供选择是保留还是还原更改。还为用户提供了 15 秒的窗口。如果他们什么都不做,那么设置将被恢复。如果他们选择“保留更改”或“还原”,将采取适当的操作。我想在显示此对话框时收到操作系统的通知。

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

顺便说一下,我需要为 Windows 10 实现这个。因此,Windows 10 信息将是最有帮助的。谢谢!

enter image description here

最佳答案

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

带有保留和恢复按钮的 15 秒窗口是 #32770 对话框。当您使用操作系统对话框时,启动进程是 explorer.exe。它确实显示在我的 spyxx 上 - 见下文。只需在对话框显示时点击 Windows 按钮并查找它。

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

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

enter image description here

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

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 或 future 的操作系统中触发 UAC,您将无法检测到对话框。您仍会收到有关分辨率更改的通知。
UAC 对话框无法检测到,因为它在只能由系统帐户访问的桌面上运行。

关于c++ - 获取有关 Windows 10 的恢复/保留新显示设置对话框的通知,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31526311/

相关文章:

c++ - std::plus 的模板推导失败

c# - 我正在尝试在注册表中创建一个 key 。但是当我执行这个命令时,我得到一个错误 : The specified path is invalid

perl - 如何在 Windows 的后台运行 Perl 脚本?

c++ - 错误 : expression must have class type

c++ - 使用 boost 波

c++ - 如何在不复制的情况下将过滤 vector 的结果存储在另一个 vector 中

windows - 在 Windows 中截取屏幕截图的最快方法是什么?

vba - 用于计算评论数量的 Microsoft Word 宏

c++ - 使用重定向标准输入处理子进程中的 kbhit

c++ - 是否可以在 Qt 应用程序中使用 Win32 Hooks