我正在开发一个应用程序来检测弹出对话框然后 自动解雇它。我把它写成C ++ / Win32应用程序。该 对话框由IE 7生成,我可以检测到窗口,但是 使OK按钮“点击”的几种方法都失败了。
搜索其他人的解决方案,将这些消息发送给 按钮句柄似乎在很多情况下都有效:
PostMessage( handle, WM_LBUTTONDOWN, 0, 0 );
PostMessage( handle, WM_LBUTTONUP, 0, 0 );
PostMessage( handle, BM_SETSTATE, 1, 0 );
虽然我的测试中对按钮状态没有影响。
我可以将制表符发送到主窗口,然后看到OK 按钮获得焦点,但然后发送返回字符什么都不做。
要了解更多相关信息,我使用Spy ++获取有关此内容的信息 窗口层次结构以及手动时传递的消息 单击“确定”按钮。
查看消息日志并阅读有关WM_MOUSEACTIVATE seamed的内容 提供解决方案。日志信息显示0002166C是按钮 窗口。所以在我的代码中我尝试了这个:
GetClassNameA( handle, str, str_size );
if( strcmp( str, "Internet Explorer_Server" ) != 0 )
return TRUE; // Not the window we're interested in.
// Send a message to activate the button window and have it process a mouse click.
PostMessage( handle, WM_MOUSEACTIVATE, (WPARAM) dialog_handle, MAKELPARAM( HTCLIENT, WM_LBUTTONDOWN );
基于窗口层次结构和消息日志,我认为窗口有 类名“Internet Explorer_Server”是按钮。也许我是 错了,因为它看起来像按钮的奇怪的类名......
下面是窗口层次结构图像的链接,当我的消息日志 手动单击“确定”按钮。最后是在1上执行的代码 第二张计时票,找窗口。
任何见解和帮助表示赞赏!
此处提供了窗口层次结构,源,窗口消息和测试对话框源的图像:
https://sites.google.com/site/matthewmillersmiscellanea/Home/
答案 0 :(得分:2)
理想情况下,您应该创建一个导出全局CBT Window Hook的DLL。这将允许您在创建对话框时获得早期通知。这样可以避免通过不断轮询来消耗资源。
一旦检测到即将创建对话框,您有两个选择:
1)阻止对话创建。
我不建议这样做,它会导致代码完全期望CreateDialog()返回有效的HWND的各种问题;
2)异步控制对话框。
我们通过使用带有注册用户消息的PostMessage并通过挂钩WNDPROC来获取它来实现此目的。收到此消息后,您必须决定如何终止您所在的对话框。
退出对话框有多种方法:
a)使用WM_COMMAND(BN_CLICKED)模拟按OK,取消,中止,无按钮(作为Chris评论)。您可以使用GetDlgItem(),查找WindowText并做出选择。但是,这不适用于非美国英语。尽管如此,在利用Accessibility API可能还有一段距离。
b)使用PostMessage(WM_CLOSE,m_hWnd)模拟关闭对话框。这并不总是按预期工作 - 某些对话框没有[X]关闭按钮,而且他们的客户端代码期望按下特定按钮。
c)使用SendInput() API模拟用户输入。这解决了在其中具有反弹出杀手代码的对话框:)
我们的最终解决方案是一个规则+基于启发式的方法,它有一个配置文件,当app / IE对话框改变了它们的ID,类名或父类名时,我们可以调整它。
答案 1 :(得分:2)
在知道窗口类名称和窗口标题
的情况下,连续关闭特定弹出窗口 #define UNICODE
#include <windows.h>
#pragma comment(lib, "user32")
int main (int nn, char ** aa)
{
while (true) {
HWND iHandle = FindWindow (L"theWindowClassName", L"theWindowCaption");
if (iHandle > 0) SendMessage(iHandle, WM_SYSCOMMAND, SC_CLOSE, 0);
Sleep (200); // check 5 times per second
}
return 0;
}
如果一个人不知道或太一般(例如&#34; Dialog&#34;)你可以通过传递空值来省略它
HWND iHandle = FindWindow (L"theWindowClassName", 0);
or
HWND iHandle = FindWindow (0, L"theWindowCaption");
当然这将关闭所有具有给定名称的窗口。