检测通知气球
使用WinXP。我需要做的(首选在 VB 或 c# 中)是检测另一个(闭源)程序何时在托盘中显示通知气球 - 并获取详细信息。任何帮助将不胜感激。谢谢
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
使用WinXP。我需要做的(首选在 VB 或 c# 中)是检测另一个(闭源)程序何时在托盘中显示通知气球 - 并获取详细信息。任何帮助将不胜感激。谢谢
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
接受
或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
发布评论
评论(3)
在类似的情况下,我使用 Microsoft 工具 Spy++ 来获取窗口信息,然后使用 pinvoke 调用
FindWindow
来检测窗口何时存在。我没有尝试过使用通知气球,但我想对
GetText
的 pinvoke 调用会检索内容。In similar situations, I have used the Microsoft tool Spy++ to grab the window information and then uses pinvoke calls to
FindWindow
to detect when the window is present.I've not tried with a notification balloon, but I imagine that a pinvoke call to
GetText
would retrieve the contents.我认为您需要使用 pinvoke 从 .net 语言执行此操作。
在我现在使用的系统(Vista Business SP2)上,气球窗口似乎总是具有窗口类 #32769(为桌面窗口保留)和 Windows 样式位 TTS_BALLOON 设置。
以下可能有效:通过创建一个临时通知气球、获取其 hWnd 并调用 GetParent() 在删除之前。然后,您可以定期轮询该父级 hwnd 的子级(使用 EnumWindows() 或 FindWindowEx() )寻找具有所需类和风格的窗口。
这对我来说似乎非常不可移植,并且可能需要在各种平台上进行大量测试。
pinvoke.net 和间谍++可能有用。
祝你好运!
I think you'll need to use pinvoke to do this from a .net language.
On the system I'm using now (Vista Business SP2), balloon windows always seem to have window class #32769 (reserved for desktop windows) and the windows style bit TTS_BALLOON set.
The following might work: Determine the parent window for all notification balloons by creating a temporary one, getting its hWnd, and calling GetParent() before deleting it. You could then periodically poll the children of this parent hwnd (using EnumWindows() or FindWindowEx()) looking for windows with the required class and style.
This seems highly non-portable to me, and likely to require a lot of testing on a variety of platforms.
pinvoke.net and spy++ might be useful.
Good luck!
您肯定需要使用 Win API 调用来实现此目的。如果这是您唯一想要做的事情,那么您最好直接使用 C 或 C++,这样您就不必为 C# 或 VB 进行大量平台调用。
自从 andyjohnson 发现所有通知气球的窗口类别都是 #32769,并且它们设置了
TTS_BALLOON
样式,您可以使用 CBT 挂钩(如果您不熟悉 Win32 挂钩,您可能需要 阅读它们),以便在创建窗口时获取回调,并检查该类和具有该样式的窗口。不过,我不确定是否为第二个和后续弹出窗口创建了一个新的气球窗口,或者是否只是隐藏并重新显示同一个气球窗口。如果是这种情况,您可能需要 CallWndProc 挂钩< /a>,获取
WM_SHOWWINDOW
消息。编辑:
我应该提到,我提到的挂钩无法在 .NET 中实现。除了低级键盘和鼠标挂钩之外,全局系统挂钩必须在本机(非托管)DLL 中实现。 Windows 会将此 DLL 加载到其他进程中,如果托管 DLL 加载到未加载 .NET CLR 的进程中,则会导致该进程崩溃。 (即使加载了 CLR,它也可能位于不同的地址,也会导致崩溃。)
因此,您必须在本机(非托管)DLL 中构建挂钩。可以从这里连接到托管应用程序,例如 Michael Kennedy 在 Code Project 上所做的,但要正确地做到这一点,并处理我上面提到的钩子类型,您需要使用进程间通信,这是迈克尔·肯尼迪遗漏的步骤。总而言之,出于您所描述的目的,用本机代码构建整个内容可能会更容易。
You will definitely need to use Win API calls to achieve this. If this is the only thing you're trying to do, you'd be better off using straight C or C++ so you don't have to do a bunch of platform invoke for C# or VB.
Since andyjohnson identified that the window class for all notification balloons is #32769, and that they have the
TTS_BALLOON
style set, you could use a CBT hook (if you're not familiar with Win32 hooks, you might want to read up on them), to get a callback whenever a window is created, and check for windows of that class and with that style.I'm not sure, though, if a new balloon window is created for second and subsequent popups or if the same one is just hidden and reshown. If this is the case, you might need a CallWndProc hook, to get
WM_SHOWWINDOW
messages.Edit:
I should mention that the hooks that I've mentioned cannot be implemented in .NET. Except for the low-level keyboard and mouse hooks, global system hooks must be implemented in a native (unmanaged) DLL. Windows will load this DLL into other processes, and if a managed DLL gets loaded into a process that doesn't have the .NET CLR loaded, it will crash that process. (Even if the CLR is loaded, it might be at a different address, also causing a crash.)
So you must build your hooks in a native (unmanaged) DLL. It's possible to interface from here to a managed application, such as Michael Kennedy has done on Code Project, but to do it properly, and handle the hook types I've mentioned above, you'd need to use interprocess communication, a step that Michael Kennedy left out. All in all, for the purpose you've described, it would probably be easier to just build the whole thing in native code.