以编程方式closures对话框 – win32

我正在开发一个应用程序来检测popup对话框,然后自动解除它。 我正在写这个C ++ / Win32应用程序。 这个对话框是由IE 7生成的,我可以检测到这个窗口,但是有几个方法让OKbutton“点击”失败了。

search其他人的解决scheme,发送这些消息到button处理似乎在很多情况下工作:

PostMessage( handle, WM_LBUTTONDOWN, 0, 0 ); PostMessage( handle, WM_LBUTTONUP, 0, 0 ); PostMessage( handle, BM_SETSTATE, 1, 0 ); 

它在我的testing中对button状态没有影响。

我可以将制表符发送到主窗口,看到确定button获得焦点,但发送返回字符什么都不做。

要了解更多信息,我使用Spy ++获取有关窗口层次结构的信息,以及手动单击“确定”button时发送的消息。

查看消息日志并阅读有关WM_MOUSEACTIVATE的信息,以提供解决scheme。 日志信息显示0002166C是button窗口。 所以在我的代码中,我试过这个:

 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”的窗口是button。 也许我错了,因为它看起来像一个button的古怪类名称…

以下是指向窗口层次结构图像的链接,当我手动单击确定button时,消息logging。 最后是在1秒定时器票证上执行的代码,寻找窗口。

任何见解和帮助表示赞赏!

窗口层次结构,源代码,窗口消息和testing对话框源代码的图像可以在这里find:

https://sites.google.com/site/matthewmillersmiscellanea/Home/

理想情况下,您应该创建一个导出全局CBT窗口挂钩的DLL。 这将允许您在创建对话框时获得提前通知。 这将避免通过不断的投票来消耗资源。

一旦你发现一个对话框即将被创建,你有两个选择:

1)防止创建对话框。

我不建议这样做,它会导致代码的各种问题,完全期待由CreateDialog()返回有效的HWND;

2)异步控制对话框。

我们通过使用带注册用户消息的PostMessage并通过挂接WNDPROC来实现此目的。 当你得到这个消息时,你必须决定如何杀死你所在的对话框。

有多种方法可以退出对话框:

a)模拟按OK,取消,中止,使用WM_COMMAND(BN_CLICKED)没有按钮(如克里斯评论)。 您可以使用GetDlgItem(),查找WindowText并进行选择。 但是,这不适用于非美国英语。 虽然在这里利用Accessibility API可能会有一些距离。

b)模拟用PostMessage关闭对话框(WM_CLOSE,m_hWnd)。 这并不总是按预期工作 – 一些对话框没有[X]关闭按钮,他们的客户端代码正在等待按下特定的按钮。

c)使用SendInput()API模拟用户输入。 这解决了在其中具有反弹出杀手代码的对话框:)

我们的最终解决方案是一个基于规则+启发式的方法,它有一个配置文件,当应用程序/ IE对话框改变了它们的ID,类名或父类名时,我们可以调整它。

为了知道窗口类名称和窗口标题,连续关闭一个特定的弹出窗口

  #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; } 

如果一个不知道或者过于通用(比如“Dialog”),你可以通过传递一个null来忽略它

  HWND iHandle = FindWindow (L"theWindowClassName", 0); or HWND iHandle = FindWindow (0, L"theWindowCaption"); 

当然这会关闭所有窗户的名字。