想做个模拟键盘鼠标输入的,这是dll核心代码,
//键盘钩子处理函数。
extern "C" LRESULT WINAPI KeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
{
if( nCode >= 0 )
{
if( wParam == VK_F10 )//当按下F10键时,激活外挂。
{
//外挂实现代码。
CPoint newPoint, oldPoint;
// GetCursorPos(&oldPoint);
newPoint.x = 340;
newPoint.y = 280;
SetCursorPos(newPoint.x, newPoint.y);
mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0);//模拟按下鼠标左键。
mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, 0);//模拟放开鼠标左键。
keybd_event(VK_CONTROL, MapVirtualKey(VK_CONTROL, 0), 0, 0); //按下SHIFT键。
keybd_event('V', MapVirtualKey('V', 0), 0, 0);//按下R键。
keybd_event('V', MapVirtualKey('V', 0), KEYEVENTF_KEYUP, 0);//放开R键。
keybd_event(VK_CONTROL, MapVirtualKey(VK_CONTROL, 0), KEYEVENTF_KEYUP, 0);//放开SHIFT键。
newPoint.y = 340;
SetCursorPos(newPoint.x, newPoint.y);
mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0);//模拟按下鼠标左键。
mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, 0);//模拟放开鼠标左键。
}
}
return CallNextHookEx(glhHook, nCode, wParam, lParam);
}//安装全局钩子。
HHOOK CKeyHook::Start()
{
glhHook = SetWindowsHookEx(WH_KEYBOARD,KeyboardProc,glhInstance,0);//设置键盘钩子。
return glhHook;
}
还有个.exe的,调用这个dll,按f10,其它一切正常,就是响应两次,我估计是按下响应一次,弹起又一次,怎么做能只响应一次呢?
//键盘钩子处理函数。
extern "C" LRESULT WINAPI KeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
{
if( nCode >= 0 )
{
if( wParam == VK_F10 )//当按下F10键时,激活外挂。
{
//外挂实现代码。
CPoint newPoint, oldPoint;
// GetCursorPos(&oldPoint);
newPoint.x = 340;
newPoint.y = 280;
SetCursorPos(newPoint.x, newPoint.y);
mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0);//模拟按下鼠标左键。
mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, 0);//模拟放开鼠标左键。
keybd_event(VK_CONTROL, MapVirtualKey(VK_CONTROL, 0), 0, 0); //按下SHIFT键。
keybd_event('V', MapVirtualKey('V', 0), 0, 0);//按下R键。
keybd_event('V', MapVirtualKey('V', 0), KEYEVENTF_KEYUP, 0);//放开R键。
keybd_event(VK_CONTROL, MapVirtualKey(VK_CONTROL, 0), KEYEVENTF_KEYUP, 0);//放开SHIFT键。
newPoint.y = 340;
SetCursorPos(newPoint.x, newPoint.y);
mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0);//模拟按下鼠标左键。
mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, 0);//模拟放开鼠标左键。
}
}
return CallNextHookEx(glhHook, nCode, wParam, lParam);
}//安装全局钩子。
HHOOK CKeyHook::Start()
{
glhHook = SetWindowsHookEx(WH_KEYBOARD,KeyboardProc,glhInstance,0);//设置键盘钩子。
return glhHook;
}
还有个.exe的,调用这个dll,按f10,其它一切正常,就是响应两次,我估计是按下响应一次,弹起又一次,怎么做能只响应一次呢?
[in] Specifies the repeat count, scan code, extended-key flag, context code, previous key-state flag, and transition-state flag. This parameter can be one or more of the following values. Value Description
0–15 Specifies the repeat count. The value is the number of times the keystroke is repeated as a result of the user's holding down the key.
16–23 Specifies the scan code. The value depends on the original equipment manufacturer (OEM).
24 Specifies whether the key is an extended key, such as a function key or a key on the numeric keypad. The value is 1 if the key is an extended key; otherwise, it is 0.
25–28 Reserved.
29 Specifies the context code. The value is 1 if the ALT key is down; otherwise, it is 0.
30 Specifies the previous key state. The value is 1 if the key is down before the message is sent; it is 0 if the key is up.
31 Specifies the transition state. The value is 0 if the key is being pressed and 1 if it is being released.
我跟踪了一下,当按下的时候lParam == 1078198281;
当弹起的时候
lParam == -1069285375;
在我的代码里,可以勉强加上一判断
if( wParam == VK_F10 && lParam>0)
不过这样找不到根据,请高人能否解释一下
{
char szI[2];
char szReturn[30];
for (int i=1; i<=9; i++)
{
sprintf(szI, "%d", i);
GetPrivateProfileString("data", szI, NULL, szReturn, 30, "data.ini");
SetDataToClipBoard(szReturn);
keybd_event(VK_F10, MapVirtualKey(VK_F10, 0), 0, 0);
}
}
这段代码是每次读INI文件的一个数据
[data]
1 = 989787
2 = 5464
3 = 654
4 = 23121
5 = dfgfg
6 = 23434
7 = 223131
8 = dfdf
9 = 4244
,读一个,放进剪贴板一个,然后模拟按f10,这样就调用了那个钩子,然后通过一套规定好的键盘鼠标操作,
把这些数据输入另一个程序里(那个程序是别人写的,没法改,只能用这种办法输入数据了)
但是,每次只能输入4244这个数据,难道是太快了?还没写进剪贴板就过去了?我本来想的是,每次剪贴板里数据发生变化,调用一次钩子函数,
监视剪贴板变化我已经知道怎么做了,不过只会在exe程序里用这个功能,如何移植到dll里,就不知道了。如这段
if( wParam == VK_F10 )//当按下F10键时,激活外挂。
我想写成类似
if( wParam == WM_DRAWCLIPBOARD )//当剪贴板发生变化,激活外挂。
这样当然不行
void CSimulateDlg::OnButton5()
{
char szI[2];
char szReturn[30];
for (int i=1; i <=1; i++)
{
sprintf(szI, "%d", i);
GetPrivateProfileString("data", szI, NULL, szReturn, 30, "data.ini");
SetDataToClipBoard(szReturn);
keybd_event(VK_F10, MapVirtualKey(VK_F10, 0), 0, 0);
}
}
把for (int i=1; i <=1; i++)这句改成只循环一次,
运行到keybd_event(VK_F10, MapVirtualKey(VK_F10, 0), 0, 0);的时候
,竟然执行两次操作,这是为什么呀?
void CSimulateDlg::OnTimer(UINT nIDEvent)
{
// TODO: Add your message handler code here and/or call default
if (iCount<9)
{
iCount++;
char szI[2];
char szReturn[30];
sprintf(szI, "%d", iCount);
GetPrivateProfileString("data", szI, NULL, szReturn, 30, "E:\\CBuilder\\waiguaTest\\data.ini");
SetDataToClipBoard(szReturn);
//Sleep(500);
keybd_event(VK_F10, MapVirtualKey(VK_F10, 0), 0, 0);
//Sleep(500);
//keybd_event(VK_F10, MapVirtualKey(VK_F10, 0), KEYEVENTF_KEYUP, 0);
}else
{
KillTimer(IDT_TIMER1);
}
CDialog::OnTimer(nIDEvent);
}
我发现了个奇怪的现象,就第一次f10的时候,有时候是出两次,有时候是出三次,后来其它的都没事
备注:尽管keybd_event传递一个与OEM相关的硬件扫描码给系统,但应用程序不能用此扫描码。系统在内部将扫描码转换成虚拟键码,并且在传送给应用程序前清除键码的UP/down位如果总是第一次出错,而且是多按一下F10,很有可能就是所谓的没有清除以前按过的键位,怎么清除呀?