想做个模拟键盘鼠标输入的,这是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,其它一切正常,就是响应两次,我估计是按下响应一次,弹起又一次,怎么做能只响应一次呢?

解决方案 »

  1.   

    你还可以加上判断 WM_LBUTTONUP,组合 wParam == VK_F10 
      

  2.   

    lParam    
      [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.  
      

  3.   


    我跟踪了一下,当按下的时候lParam == 1078198281;
    当弹起的时候
    lParam == -1069285375;
    在我的代码里,可以勉强加上一判断
    if( wParam == VK_F10 && lParam>0)
    不过这样找不到根据,请高人能否解释一下
      

  4.   

    一事不烦二主了void CSimulateDlg::OnButton5() 
    {
    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 )//当剪贴板发生变化,激活外挂。
    这样当然不行
      

  5.   

    在消息响应里必须正确处理两个消息:WM_DRAWCLIPBOARD和WM_CHANGECBCHAIN。当剪贴板内容发生变化时,Windows 将触发WM_DRAWCLIPBOARD消息,并将该消息送给Clipboard Viewer Chain的第一个窗口。每一个Clipboard Viewer窗口,包括第一个窗口在响应和处理该消息后,必须根据其保存的链表中的下一个窗口的句柄将该消息发送给下一个Clipboard Viewer窗口。窗口可以在该消息中取出剪贴板内容,并判断是否是该窗口增在监视的内容,如果是就进行相应的处理。
      

  6.   

    还是问个简单点的吧,还是这段代码
    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);的时候
    ,竟然执行两次操作,这是为什么呀?
      

  7.   

    我改成了一秒一次
    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的时候,有时候是出两次,有时候是出三次,后来其它的都没事
      

  8.   

    看这句
    备注:尽管keybd_event传递一个与OEM相关的硬件扫描码给系统,但应用程序不能用此扫描码。系统在内部将扫描码转换成虚拟键码,并且在传送给应用程序前清除键码的UP/down位如果总是第一次出错,而且是多按一下F10,很有可能就是所谓的没有清除以前按过的键位,怎么清除呀?