实现一个鼠标或者键盘模拟器,可以完成很多功能,比如做一个简单的游戏外挂^_^。通常,模拟键盘鼠标事件有两种方法:
1.keybd_event, mouse_event
2.SendMessage, PostMessage
后者更强大,指定hwnd后可以后台发送对应的鼠标键盘消息,而后者只能够发送前台信息,也就是只能向前端窗口发送消息。
下面是简单的用法举例:
方法1:使用keybd_event, mouse_event
SetCursorPos(x,y);
mouse_event(MOUSEEVENTF_LEFTDOWN,0,0,0,0);
mouse_event(MOUSEEVENTF_LEFTUP,0,0,0,0);
keybd_event(k,0,0,0);
keybd_event(k,0,KEYEVENTF_KEYUP,0);
方法2:使用SendMessage, PostMessage
向当前程序的ID为IDC_EDIT1的输入框输入字符:
HWND tw2 = GetDlgItem(IDC_EDIT1)->m_hWnd;
::SendMessage(tw2,WM_CHAR,s[i],0);
向ID为IDOK的按钮发送鼠标单击事件:
HWND tw3 = GetDlgItem(IDOK)->m_hWnd;
::SendMessage(tw3,WM_LBUTTONDOWN,0,0);
::SendMessage(tw3,WM_LBUTTONUP,0,0);
向打开的记事本输入字符
wnd = ::FindWindow("notepad", NULL);
wnd = FindWindowEx(wnd,0,"Edit",NULL);
::SendMessage(tw2,WM_CHAR,s[i],0);
如果说你不知道名字叫Edit,那么有下面的方法:
CWnd * pwnd = FindWindow("notepad", NULL);
CWnd * p2 = pwnd->GetTopWindow();
wnd = p2->m_hWnd;
::SendMessage(tw2,WM_CHAR,s[i],0);
如果连notepad也不知道的话,你可以使用进程ID:遍历进程池得到想要的进程ID,然后找到指定ID的hwnd
struct EnumParam
{
HWND hMainWnd;
DWORD dwProcessID;
};
BOOL CALLBACK EnumWinProc(HWND hwnd, LPARAM lParam)
{
DWORD dwID;
EnumParam* pep = (EnumParam*)lParam;
GetWindowThreadProcessId(hwnd,&dwID);
if (dwID == pep->dwProcessID) {
pep->hMainWnd = hwnd;
return 0;
}
return TRUE;
}
EnumParam ep;
STARTUPINFO si;
PROCESS_INFORMATION pi;
ep.hMainWnd = NULL;
memset(&si, 0, sizeof(si));
si.cb = sizeof(STARTUPINFO);
if (CreateProcess(NULL,"notepad.exe c:.txt",
NULL,NULL,FALSE,0,NULL,NULL,&si,&pi))
{
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
ep.dwProcessID = pi.dwProcessId;
while(!ep.hMainWnd) {
EnumWindows((WNDENUMPROC)EnumWinProc, (long)&ep);
//没有下面的一行,CPU的使用率会高居不下,同时其它的程序
//也会执行的很慢(包括程序启动的Notepad.exe)
if (ep.hMainWnd==NULL) Sleep(20);
}
//EnumWindows((WNDENUMPROC)EnumWinProc, (long)&ep);
}
//此时的 ep.hMainWnd 就是你要的NodePad.exe窗口的句柄
//接下来由hwnd得到CWND *
wnd = ep.hMainWnd;
if(wnd == NULL) AfxMessageBox("Fasle");
CWnd * tc = FromHandle(wnd);
//获取
wnd = tc->GetTopWindow()->m_hWnd;
::SendMessage(tw2,WM_CHAR,s[i],0);
//OK啦