背景需求
通过前辈们写的软体实现我们需要的结果,而在软体中操作非常繁琐,甚至会在多个软件中来回切换,非常耗时;现就需要开发出一个来代替人来回切换窗体,填写数据,点击按钮的自动化工具,解放人力。
实现思路
软件的主窗体,子窗体,窗体内的控件都有自己的操作句柄,标题,类,大小坐标,如果是控件还有对应的控件ID(一般情况下ID是不会改变的),
获取句柄方法
1,需要下载spy++工具
spy++图标
spy++界面
2,鼠标点击框内按住拖动到需要得到句柄的窗口或控件后松开,
3,点击确认得到对应窗口或控件的所有信息。
我们一般需要看类名,标题,控件ID,大小坐标,窗体是没有控件id的。
QT通过获取的信息操作
使用api中的函数获取其操作句柄需要用到的函数
1,FindWindow(“窗体类名”,“窗体标题”);//获取窗体
2,FindWindowEx(父窗口句柄,NULL,窗体类名,窗体标题);//获取子窗口句柄
3,GetDlgItem(父窗口句柄,控件ID);//获取子窗口或控件句柄
例子
//获取窗体句柄 类名需要去掉括号中内容
HWND hwnd = ::FindWindow(L"#32770",L"另存为");
//获取另存为子窗口句柄
HWND Save_file0 = ::FindWindowExA(hwnd ,0,"DUIViewWndClassName",0);
HWND Save_file1 = ::FindWindowExA(Save_file0,0,"DirectUIHWND",0);
//下拉框父句柄
HWND Save_file2 = ::FindWindowExA(Save_file1,0,"FloatNotifySink",0);
//获取文件名下拉框句柄
HWND Save_file3 = ::FindWindowExA(Save_file2,0,"ComboBox",0);
//获取文件名输入框句柄
HWND Save_file4 = ::FindWindowExA(Save_file3,0,"Edit",0);
获取窗体内控件或子窗体句柄,需要从顶级窗口一步一步向下获取,并且需要确定获取的位置正确,可以打印句柄,与spy++显示的句柄相同即可,也可以输出控件或窗体的长宽,起始坐标 来确定是否是需要的窗体句柄
控件ID为0或者控件ID和操作句柄相同怎么办?
就可以使用例子中的方法获取句柄,因为控件ID一般不会改变,是唯一确定的就算在不同电脑上运行也是一样不会改变。
//通过id获取句柄
HWND tWnd3 = GetDlgItem(pWnd, 0x00000001);
得到窗体x,y height width
GeiwindowRect(“操作句柄”, RECT rcg);
GetWindowRect(clear_data,&rcg);
width = rcg.right - rcg.left; //窗口的宽度
height = rcg.bottom - rcg.top; //窗口的高度
i = rcg.left;
j = rcg.top;
X_axis = rcg.right; //纵坐标
Y_axis = rcg.bottom; //横坐标
ui->log->setText(QString("起始x:%3 起始y:%4 纵坐标:%1 横坐标:%2").arg(X_axis).arg(Y_axis).arg(i).arg(j));
模拟键盘鼠标操作
模拟键盘输入函数
VOID keybd_event(
BYTE bVk, // virtual-key code
BYTE bScan, // hardware scan code
DWORD dwFlags, // flags specifying various function options
DWORD dwExtraInfo // additional data associated with keystroke
);
从原型可以看出,Keybd_event()共有四个参数:
第一个为按键的虚拟键值,如回车键为vk_return, tab键为vk_tab(其他具体的参见附录:常用模拟键的键值对照表);
第二个参数为扫描码,一般不用设置,用0代替就行;
第三个参数为选项标志,如果为keydown则置0即可,如果为keyup则设成"KEYEVENTF_KEYUP";
第四个参数一般也是置0即可。
keybd_event(13,0,0,0);//按下enter键
keybd_event(40,0,0,0);//向下移动
::SetCursorPos(i+(X_axis-i)/3, Y_axis/2);//鼠标移动到指定位置
mouse_event(MOUSEEVENTF_LEFTDOWN|MOUSEEVENTF_LEFTUP,i+(X_axis-i)/3,Y_axis/2, 0, 0 );//鼠标左键点击
//向输入框中写入数据
QString filePath= "C2"; //数据
QByteArray t1=filePath.toLocal8Bit();
char *_filePath=t1.data(); //以上3行将QString转换为char*。为保证不出现中文乱码,必须这么转换
//Edit:操作句柄
::SendMessageA(Edit,WM_SETTEXT,0,(LPARAM)_filePath);
附录:键值对照表
常用模拟键的键值对照表(也可参考
http://msdn.microsoft.com/en-us/library/dd375731(v=vs.85).aspx