【问题标题】:Is there any event triggered when a new window is added to the desktop将新窗口添加到桌面时是否触发了任何事件
【发布时间】:2014-08-16 22:36:02
【问题描述】:

我想知道当新窗口出现/出现在桌面上时是否触发了任何事件。我愿意使用 COM、WMI、WinApis、UIAutomation 或任何其他方法,但选择的语言是 C#。

实际要求: 一个进程有 1 个主窗口和许多其他窗口。例如,其中一个窗口的类名是 X(我使用 pinvoke 获得了此信息)。现在,只要过程中有一些通知,这个窗口就会弹出几次。我不想显示这个窗口。我没有对该进程的代码访问权限,因此我可以禁用该窗口。那么有什么方法可以让我获得一个事件或任何其他机制来跟踪桌面,并且任何时候带有类名 X 的窗口出现/即将出现它都会隐藏它。

如果我不清楚这个问题,请告诉我。 谢谢

编辑:西蒙的回答非常好。我试过了,并且能够获得除通知/吐司窗口之外的所有窗口的通知,例如 lync 的即时吐司通知或 Outlook 新邮件通知。我尝试了自动化元素和 Windows 模式的不同元素,但仍然无法获得这些元素......我如何获得这些元素的任何想法......您可以阅读 Simon 的答案中的 cmets 以获取更多上下文/详细信息。再次感谢 Simon 介绍 UIAUtomation 的强大功能...喜欢它!

【问题讨论】:

标签: c# windows com wmi pinvoke


【解决方案1】:

正如 Damien 在他的评论中所说,您可以使用 UI 自动化,就像在 C# 示例控制台应用程序中一样:

class Program
{
    static void Main(string[] args)
    {
        Automation.AddAutomationEventHandler(WindowPattern.WindowOpenedEvent, AutomationElement.RootElement, TreeScope.Subtree, (sender, e) =>
            {
                AutomationElement src = sender as AutomationElement;
                if (src != null)
                {
                    Console.WriteLine("Class : " + src.Current.ClassName);
                    Console.WriteLine("Title : " + src.Current.Name);
                    Console.WriteLine("Handle: " + src.Current.NativeWindowHandle);
                }
            });

        Console.WriteLine("Press any key to quit...");
        Console.ReadKey(true);
    }
}

【讨论】:

  • 嘿...谢谢...我还有一个问题...我们是否还可以获取有关窗口的信息,例如通知,例如 Outlook 中新邮件或新即时消息时的通知在 lync/skype 等...我尝试了上面的代码,但它没有显示这种窗口...通过其他 win api,我发现,例如,lync toast 通知的窗口类与对话不同窗口类。所以我希望在这里举办活动时我会隐藏那个窗口
  • Windows 树很大。该示例使用 AutomationElement.RootElement(即桌面窗口)作为父窗口,它不会获得所有子窗口通知。但是您可以使用其他元素作为开始。您可以使用 AutomationElement.FromHandle、FromPoint 方法等获取其他元素。
  • 我在 Windows 10 上使用 .NET 自动化库。我添加了一个事件处理程序,就像您的示例一样——植根于 RootElement,作用域子树。但奇怪的是,每次打开一个窗口时,我们几乎总是会看到两个事件。偶尔,可能只有一个事件,但>95% 的时间有两个。这些事件是不同的对象,但包含相同的 EventId 并且来自相同的源。有什么线索可以看吗?
  • @SteveRobbins - 我今天用 Windows 10 测试了我的答案代码,它运行良好。您对我的示例或其他代码有疑问吗?如果是另一个代码,你应该问另一个问题。
  • @SimonMourier 好问题。我以前使用自己的代码,但今天我完全按照上面介绍的方式编译了您的代码。我确实看到了相同的行为——但只有少数应用程序(到目前为止有两个)表现出双打开事件。其中一个是我公司的应用程序,另一个是Adobe Acrobat Reader DC Version 2020.006.20034。所以谜团加深了。
【解决方案2】:

一个选项是RegisterShellHookWindow。您提供一个可以接收通知消息的窗口句柄。可能对您有用的通知是 HSHELL_WINDOWCREATEDHSHELL_WINDOWACTIVATED

【讨论】:

    【解决方案3】:

    Here MSDN 提供了注册 Windows 通知的代码。但这是特定于 Windows Sever 2008 的。我认为您可以在您的 Window 版本中找到类似的内容。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-11-06
      • 1970-01-01
      • 1970-01-01
      • 2012-11-02
      • 2020-06-05
      • 2020-12-25
      • 2017-11-18
      • 1970-01-01
      相关资源
      最近更新 更多