读书人

模拟对另一过程的窗口按钮的点击

发布时间: 2013-03-06 16:20:31 作者: rapoo

模拟对另一进程的窗口按钮的点击

1、

在自动化测试中经常要模拟窗口按钮的点击。

参考文章:http://blog.csdn.net/blackboyofsnp/article/details/3372719

有时我们需要这么做, 手动模拟按钮按下的事件, 让程序做出与按钮真的按下时一样的响应.

设按钮ID为ID_BTN_OK, 当前Dialog窗口. 实际上系统并不能区分按钮是真的按下了(如用鼠标点击), 还是一个我们自己用代码模拟出的一种"假象".它所需要知道的只是哪个窗口(按钮也是一种窗口)发生了哪一种事件, 然后在消息循环中处理它. 系统怎么才能知道这些呢? 当然靠的是消息(message), 我们只需按照Windows或者MFC的标准格式把相应的信息传给系统,系统就会"上当"了. 向系统传递消息可以用SendMessage或PostMessage(可能还有其他很多函数哦), 但SendMessage执行后系统会一直等待, 直到要发送的消息被处理掉. 而PostMessage可不管那么多, 发送消息后立即返回程序流程. 当按钮按下的响应函数中有很大一个循环时, 用SendMessage会出现许多问题, 尤其是要在程序初始化阶段模拟时,会导致窗体无法完成初始化. 所以我们用PostMessage(). 它的原型为:
BOOL PostMessage(          HWND hWnd,    UINT Msg,    WPARAM wParam,     LPARAM lParam);


这样写;

PostMessage(WM_COMMAND, MAKEWPARAM(ID_BTN_OK, BN_CLICKED), NULL);

void CtestDlg::OnBnClickedBtnTest(){ AfxMessageBox(_T("OK"));}

然后在对话框的OnInitDialog()函数的return TRUE前加上:

PostMessage(WM_COMMAND, MAKEWPARAM(IDC_BTN_TEST, BN_CLICKED), NULL);

好了,再运行程序,会弹出个消息框 “OK”,说明模拟正确。

2#region Dll Import 需要导入的api 声明。 [DllImport("User32.dll", EntryPoint = "FindWindow")] private static extern IntPtr FindWindow(string lpClassName, string lpWindowName); [DllImport("user32.dll", EntryPoint = "FindWindowEx")] private static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow); [DllImport("User32.dll", EntryPoint = "SendMessage")] private static extern int SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, string lParam); const int WM_GETTEXT = 0x000D; const int WM_SETTEXT = 0x000C; const int WM_CLICK = 0x00F5; #endregion //关消息的方法 private void ClosePopWindow(object obj) { //这些用spy++可以看到 string lpszParentClass = "#32770"; //整个窗口的类名 string lpszParentWindow = "建立新的下载任务"; //窗口标题 string lpszClass_Submit = "Button"; //需要查找的Button的类名 string lpszName_Submit = "立即下载"; //需要查找的Button的标题 IntPtr ParenthWnd = new IntPtr(0); IntPtr EdithWnd = new IntPtr(0); int i = 0; while (true) { //查到窗体,得到整个窗体 ParenthWnd = FindWindow(lpszParentClass, lpszParentWindow); //判断这个窗体是否有效 if (!ParenthWnd.Equals(IntPtr.Zero)) { //得到第一级子窗口 EdithWnd = FindWindowEx(ParenthWnd, new IntPtr(0), "#32770", ""); //Console.WriteLine("第一级-"+EdithWnd.ToString()); //得到Button这个子窗体,并触发它的Click事件 EdithWnd = FindWindowEx(EdithWnd, new IntPtr(0), lpszClass_Submit, lpszName_Submit); //Console.WriteLine("第二级-" + EdithWnd.ToString()); if (!EdithWnd.Equals(IntPtr.Zero)) { SendMessage(EdithWnd, WM_CLICK, (IntPtr)0, "0"); } return; } Thread.Sleep(1000); i++; // Console.WriteLine("第"+i.ToString()+"次检查"); 5秒都没显示出来就推出循环 if (i > 15) { //break; } } } //需要导入如下类库using System.Runtime.InteropServices;using System.Threading;using Microsoft.Win32; //在迅雷提交前添加一个方法ThreadPool.QueueUserWorkItem(new WaitCallback(ClosePopWindow));


3、

#include <iostream>#include <fstream>#include <math.h>#include <cctype>#include <string>#include <windows.h>using namespace std;int main(){    //cout << "Hello world!" << endl;    HWND hwnd = FindWindow( 0, "文件窗口"  );    //HWND hWnd2 =  GetDlgItem( hwnd, 1001);    char* strs = new char[ 255 ];    HWND hWnd2 = ::FindWindowEx(hwnd,NULL,"Button",NULL);    while ( hWnd2 )    {        GetWindowText( hWnd2, strs, 255 );        cout << strs << endl;       /* if ( strcasecmp( strs, "确定" ) == 0 ) {            break;        }*/        hWnd2 = FindWindowEx( hwnd, hWnd2, "Button", NULL );    }    UINT nCtrlID = ::GetDlgCtrlID(hWnd2);    ::PostMessage(hWnd2, WM_COMMAND, (WPARAM)(BN_CLICKED << 16 | nCtrlID), (LPARAM)hWnd2);    ::PostMessage(hWnd2,WM_MOUSEMOVE, MK_LBUTTON, MAKELONG(0,0) );    ::PostMessage(hWnd2,WM_LBUTTONDOWN,MK_LBUTTON,MAKELPARAM(0,0));    ::PostMessage(hWnd2,WM_LBUTTONUP,MK_LBUTTON,MAKELPARAM(0,0));    return 0;}


4、往编辑框中写入文件(可实现)

SetWindowText

读书人网 >编程

热点推荐