窗口标题更改事件

本文关键字:事件 窗口标题 | 更新日期: 2023-09-27 18:19:43

如果一个窗口,例如Firefox,将其标题从Firefox更改为Stack Overflow - Firefox,那么我希望我的应用程序记录Firefox更改了标题。

如果不使用钩子和循环(EnumWindows),这可能吗?如果只能用钩子做,那是哪种类型的钩子?

窗口标题更改事件

WinEvents就是实现这一目标的方法。您需要的API是SetWinEventHook()-如果您关心特定的窗口,请使用GetWindowThreadProcessId()获取HWND的线程ID,然后仅侦听该特定线程中的事件。对于窗口标题更改,您将需要EVENT_OBJECT_NAMEMECHANGE事件。

你可以挂接"上下文中"或"上下文外"-后者是最简单的,意味着事件会被传递回你自己的进程,所以你不需要一个单独的DLL-这使得在C#中完成这一切成为可能;但是调用SetWinEventHook的线程必须有一个消息循环(GetMessage/PranslateMessage/DispatchMessage),因为事件是在幕后使用消息形式传递的。

在WinEvent回调中,你需要检查HWND是否是你关心的,因为你会得到目标线程上任何UI的名称更改,可能包括子窗口名称更改,或者其他你不关心的事情。

--

顺便说一句,您可以检查这个答案,以获得一些使用WinEvents的示例C#代码;它使用它们来跟踪桌面上所有窗口的前景窗口变化;但应该只进行上面概述的一些简单修改来跟踪特定窗口上的名称更改。

您将需要一个钩子(或您在问题中提到的轮询技术)。

基本上,在Windows API中,要更改"窗口标题"(或者更确切地说是窗口的文本),需要发送WM_SETTEXT,因此挂钩需要拦截该消息。你需要的钩子类型是WH_CALLWNDPROC,只需检查你收到的消息是否是WM_SETTEXT,而hWnd是你正在查看的应用程序的主窗口(这样你就不会像应用程序试图设置子窗口的文本那样得到误报)。

这里需要注意的是:虽然这里可能不是这样,但请注意,您看到的标题实际上可以手动绘制,而不是通过通常的Windows API。在走得太远之前,使用Spy++或其他东西来看看发生了什么,你可能会白白花费很多时间。