在使用发送输入 API 模拟鼠标单击时是否需要引入延迟

Do I need to introduce delays when simulating a mouse click with SendInput API?

本文关键字:是否 延迟 单击 鼠标 输入 模拟 API      更新时间:2023-10-16

我需要能够模拟在另一个进程中单击控件的鼠标。我想出了以下方法:

BOOL SimulateMouseClick(POINT* pPntAt)
{
    //Simulate mouse left-click
    //'pPntAt' = mouse coordinate on the screen
    //RETURN:
    //      = TRUE if success
    BOOL bRes = FALSE;
    if(pPntAt)
    {
        //Get current mouse position
        POINT pntMouse = {0};
        BOOL bGotPntMouse = ::GetCursorPos(&pntMouse);
        //Move mouse to a new position
        ::SetCursorPos(pPntAt->x, pPntAt->y);
        //Send mouse click simulation
        INPUT inp = {0};
        inp.type = INPUT_MOUSE;
        inp.mi.dx = pPntAt->x;
        inp.mi.dy = pPntAt->y;
        inp.mi.dwFlags = MOUSEEVENTF_LEFTDOWN;
        if(SendInput(1, &inp, sizeof(inp)) == 1)
        {
            //Do I need to wait here?
            Sleep(100);
            inp.mi.dwFlags = MOUSEEVENTF_LEFTUP;
            if(SendInput(1, &inp, sizeof(inp)) == 1)
            {
                //Do I need to wait here before restoring mouse pos?
                Sleep(500);
                //Done
                bRes = TRUE;
            }
        }
        //Restore mouse
        if(bGotPntMouse)
        {
            ::SetCursorPos(pntMouse.x, pntMouse.y);
        }
    }
    return bRes;
}

我的问题是我是否需要像人类鼠标点击那样引入那些人为的延迟?

SendInput 的文档包含以下内容:

SendInput 函数将 INPUT 结构中的事件串行插入到键盘或鼠标输入流中。这些事件不会与用户(使用键盘或鼠标)或通过调用keybd_event、mouse_event或对 SendInput 的其他调用插入的其他键盘或鼠标输入事件穿插在一起。

这就是引入SendInput的原因。在SendInput的各个调用之间设置人为的延迟完全违背了它的目的。

简短的回答是:不,您不需要在合成输入之间引入延迟。您也不需要拨打SetCursorPos;INPUT结构已包含鼠标输入的位置。

当然,如果您改用UI 自动化,则不必处理任何这些问题。UI 自动化的设计目标是"通过标准输入以外的方式操作 UI。UI 自动化还允许自动化测试脚本与 UI 交互。