1、前台模拟鼠标键盘操作
这里将窗口置顶,再调用模拟键鼠操作相关的API,微软提供了一个API,例如:
SetWindowPos(this->GetSafeHwnd(),HWND_TOPMOST, cx, cy, 0, 0, SWP_NOSIZE);
但是这个API也不能确保当前窗口就是最顶层(因为另一个程序再次调用的时候会覆盖)
为了确保当前窗口在最顶层,下面是我整理后的代码,实例代码如下:
激活窗口:
- void CMFCDlg::OnBtnActivewindow()
- {
- // TODO: Add your control notification handler code here
- CString strCaption = _T("水晶连连看");
- CWnd* pwndFirst = CWnd::FindWindow(NULL,strCaption);
- if(pwndFirst)
- {
- CWnd* pwndPopup = pwndFirst->GetLastActivePopup();
- pwndFirst->SetForegroundWindow();
- pwndFirst->ShowWindow(SW_SHOWNORMAL);
- if(pwndFirst != pwndPopup)
- {
- pwndPopup->SetForegroundWindow();
- ::SendMessage((HWND__ *)pwndPopup, WM_SYSKEYDOWN,VK_MENU,0);
- ::SendMessage((HWND__ *)pwndPopup, WM_SYSKEYDOWN,VK_F4,0); //按下f4
- ::SendMessage((HWND__ *)pwndPopup, WM_SYSKEYUP,VK_MENU,0);
- ::SendMessage((HWND__ *)pwndPopup, WM_SYSKEYUP,VK_F4,0);
- }
- }
- }
模拟按键:
- void Output()
- {
- // 模拟 Ctrl + V 按下
- keybd_event(VK_CONTROL, 0, 0, 0);
- keybd_event('V', 0, 0, 0);
- // 模拟 Ctrl + V 弹起
- keybd_event('V', 0, KEYEVENTF_KEYUP, 0);
- keybd_event(VK_CONTROL, 0, KEYEVENTF_KEYUP, 0);
- // 模拟 Alt + S 按下
- keybd_event(VK_MENU, 0, 0, 0);
- keybd_event('S', 0, 0, 0);
- // 模拟 Enter 按下弹起
- keybd_event(VK_RETURN, 0, 0, 0);
- keybd_event(VK_RETURN, 0, KEYEVENTF_KEYUP, 0);
- Sleep(10);
- // 模拟 Alt + S 弹起
- keybd_event('S', 0, KEYEVENTF_KEYUP, 0);
- keybd_event(VK_MENU, 0, KEYEVENTF_KEYUP, 0);
- // 模拟 Enter 按下
- keybd_event(VK_RETURN,0,0,0);
- Sleep(10);
- }
模拟鼠标点击:
- void CLinkDlg::OnTest()
- {
- // TODO: Add your control notification handler code here
- CString gameCaption="水晶连连看";
- HWND hWnd=::FindWindow(NULL,gameCaption);
- DWORD dwPid;
- RECT rect;
- POINT ptOld;
- // 获取窗口句柄、当前窗口的位置(相对桌面屏幕)
- ::GetWindowThreadProcessId(hWnd,&dwPid);
- ::GetWindowRect(hWnd,&rect);
- // 获取旧的鼠标位置、设置新的位置
- ::GetCursorPos(&ptOld);
- ::SetCursorPos(80,150);
- // 在新的位置点击鼠标左键
- mouse_event(MOUSEEVENTF_LEFTDOWN,0,0,0,0);
- mouse_event(MOUSEEVENTF_LEFTUP,0,0,0,0);
- // 在第二点点击鼠标左键
- SetCursorPos(rect.left +200,rect.top +150);
- mouse_event(MOUSEEVENTF_LEFTDOWN,0,0,0,0);
- mouse_event(MOUSEEVENTF_LEFTUP,0,0,0,0);
- }
2、后台模拟鼠标键盘操作
这里就不需要激活窗口了,这就类似传说中XX脱机外挂,还是参见代码吧!
后台模拟键盘事件:
- void CTestDlg::PressF5()
- {
- HWND hWnd = ::FindWindow(NULL,_T("水晶连连看"));
- if(!hWnd)
- {
- MessageBox("请先运行水晶连连看主程序","提示",MB_OK | MB_ICONERROR);
- return;
- }
- // 下面是后台模拟按下回车键与F5
- ::PostMessage(hWnd,WM_KEYDOWN,VK_RETURN,0);
- ::PostMessage(hWnd,WM_KEYUP,VK_RETURN,0);
- ::PostMessage(hWnd,WM_KEYDOWN,VK_F5,0);
- ::PostMessage(hWnd,WM_KEYUP,VK_F5,0);
- ::PostMessage(hWnd,WM_KEYDOWN,VK_RETURN,0);
- ::PostMessage(hWnd,WM_KEYUP,VK_RETURN,0);
- }
后台模拟鼠标点击:
在测试这段代码时,我查找了很多资料未果,因为最后一个参数LPARAM我尝试过很多方法去表示鼠标的坐标也不行,终于在codeproject一位朋友告诉我用MAKELPARAM宏来设置鼠标X、Y的坐标,在此深表感谢!
- void CTestDlg::MouseClick()
- {
- CString gameCaption="水晶连连看";
- HWND hWnd=::FindWindow(NULL,gameCaption);
- // 模拟点击主窗口相对坐标(80,130)的位置
- ::PostMessage(hWnd,WM_MOUSEMOVE, MK_LBUTTON, MAKELONG(80,130));
- ::PostMessage(hWnd,WM_LBUTTONDOWN,MK_LBUTTON,MAKELPARAM(80,130));
- ::PostMessage(hWnd,WM_LBUTTONUP,MK_LBUTTON,MAKELPARAM(80,130));
- Sleep(10);
- }
相关工程的源代码就不用上传了吧,有兴趣的自己摸索一下~~~