MFC-SendInput模拟键盘鼠标操作

这个函数可以在锁屏状态下有效

事件将被插入在鼠标或者键盘消息处理队列里面

 

单个普通按键

复制代码
    
    //功能:在记事本中输入a或A
    HWND hNotepad = ::FindWindow(_T("Notepad"), NULL);//获取记事本句柄
    if (!hNotepad) {
        AfxMessageBox(_T("请打开记事本"));
        ExitProcess(0);
    }
    ::ShowWindow(hNotepad, SW_NORMAL);
    ::SetForegroundWindow(hNotepad);//把记事本置为活动窗口


    
    //INPUT结构体
    INPUT input[2] = {};
    //数组长度就是事件数量
    input[0].type = INPUT_KEYBOARD;
    input[1].type = INPUT_KEYBOARD;//模拟类型
    /*
    DWORD
    INPUT_MOUSE=0    该事件是鼠标事件。使用联合的 mi 结构
    INPUT_KEYBOARD=1  该事件是键盘事件。使用联合的 ki 结构
    INPUT_HARDWARE=2   该事件是硬件事件。使用联合的 hi 结构

    */

    //键盘KEYBDINPUT结构体
    input[0].ki.wVk = 65; //WORD wVk  虚拟键盘代码
    //A键
    input[1].ki.wVk = 65;
    input[0].ki.dwFlags = NULL;
    //KEYEVENTF_KEYUP=0x0002
    //如果指定,表示释放按键。如果未指定,表示按下该键
    input[1].ki.dwFlags = KEYEVENTF_KEYUP;

    UINT uSent = SendInput(ARRAYSIZE(input),input, sizeof(INPUT));//模拟鼠标或者键盘操作
    /*
    参数1:UINT nInput  插入事件的个数
    参数2:LPINPUT pInput   指向一个类型为INPUT的数组变量
    参数3:INT cbSize   指定INPUT结构的大小。如果cbSize不是INPUT结构的大小,则函数将失败返回
    返回值:UINT 是成功插入操作事件的个数
    */

    if (uSent != ARRAYSIZE(input))
    {
        CString str;
        str.Format(_T("插入事件数量不对\r\n"));
        ::OutputDebugString(str);
    }
复制代码

 

组合键

复制代码
    //功能:在记事本中输入CTRL+A 即全选
    HWND hNotepad = ::FindWindow(_T("Notepad"), NULL);//获取记事本句柄
    if (!hNotepad) {
        AfxMessageBox(_T("请打开记事本"));
        ExitProcess(0);
    }
    ::ShowWindow(hNotepad, SW_NORMAL);
    ::SetForegroundWindow(hNotepad);//把记事本置为活动窗口

    //INPUT结构体
    INPUT input[4] = {};
    input[0].type = INPUT_KEYBOARD;
    input[1].type = INPUT_KEYBOARD;
    input[2].type = INPUT_KEYBOARD;
    input[3].type = INPUT_KEYBOARD;

    //键盘KEYBDINPUT结构体
    input[0].ki.wVk = VK_CONTROL; //WORD wVk  虚拟键盘代码
    //CTRL键
    input[1].ki.wVk = 65;
    //A键
    input[2].ki.wVk = 65;
    input[3].ki.wVk = VK_CONTROL;

    input[0].ki.dwFlags = NULL;
    //KEYEVENTF_KEYUP=0x0002
    //如果指定,表示释放按键。如果未指定,表示按下该键
    input[1].ki.dwFlags = NULL;
    input[2].ki.dwFlags = KEYEVENTF_KEYUP;
    input[3].ki.dwFlags = KEYEVENTF_KEYUP;


    UINT uSent = SendInput(ARRAYSIZE(input), input, sizeof(INPUT));//模拟鼠标或者键盘操作
    /*
    参数1:UINT nInput  插入事件的个数
    参数2:LPINPUT pInput   指向一个类型为INPUT的数组变量
    参数3:INT cbSize   指定INPUT结构的大小。如果cbSize不是INPUT结构的大小,则函数将失败返回
    返回值:UINT 是成功插入操作事件的个数
    */

    if (uSent != ARRAYSIZE(input))
    {
        CString str;
        str.Format(_T("插入事件数量不对\r\n"));
        ::OutputDebugString(str);
    }
复制代码

 

移动鼠标 

复制代码
    int x = 200;//要移动到的 x 坐标
    int y = 100;
    int cx_screen = ::GetSystemMetrics(SM_CXSCREEN);  //屏幕宽
    int cy_screen = ::GetSystemMetrics(SM_CYSCREEN);  //屏幕高

    int real_x = 65535 * x / cx_screen; //像素坐标转换成绝对坐标
    //如果指定了MOUSEEVENTF_ABSOLUTE,dx和dy就是从0到65535的绝对坐标。
    //这个事件的作用是将坐标映射到显示器表面。
    //(0,0)坐标对应着显示器表面的左上角,(65535,65535)坐标对应着显示器表面的右下角
    int real_y = 65535 * y / cy_screen;


    INPUT inputs[1] = {};
    inputs[0].type = INPUT_MOUSE;
    inputs[0].mi.dx = real_x;
    inputs[0].mi.dy = real_y;
    /*
    dx  dy:LONG  默认为鼠标移动相对数值(与上次位置变化相比),
            若想用其绝对数值需要在dwFlags成员里面使用MOUSEEVENTF_ABSOLUTE标识符
    */

    inputs[0].mi.dwFlags = MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE;  //鼠标动作
    /*
    DWORD   
    MOUSEEVENTF_MOVE=0x0001         鼠标移动
    MOUSEEVENTF_LEFTDOWN=0x0002     鼠标左键按下
    MOUSEEVENTF_LEFTUP=0x0004       鼠标左键释放
    MOUSEEVENTF_RIGHTDOWN=0x0008    鼠标右键按下
    MOUSEEVENTF_RIGHTUP=0x0010      鼠标右键释放
    MOUSEEVENTF_MIDDLEDOWN=0x0020   鼠标中部按下
    MOUSEEVENTF_MIDDLEUP=0x0040     鼠标中部释放
    MOUSEEVENTF_XDOWN=0x0080        鼠标x键按下
    MOUSEEVENTF_XUP=0x0100          鼠标x键释放
    MOUSEEVENTF_WHEEL=0x0800        鼠标滚轮移动,移动数值在mouseData指定
    MOUSEEVENTF_ABSOLUTE=0x8000     成员dxdy为绝对坐标

    */

    inputs[0].mi.mouseData = 0;
    /*
    DWORD
    1.如果 dwFlags 包含MOUSEEVENTF_WHEEL,则mouseData表明指定滚轮移动量。正值表示滚轮向前旋转;负值表示滚轮向后旋转
    2.如果 dwFlags 包含MOUSEEVENTF_XDOWN或MOUSEEVENTF_XUP,则 mouseData 指定按下或释放了哪些 X 按钮。此值可以是以下的任意组合
                    XBUTTON1=0x0001    第一个 X 按钮
                    XBUTTON2=0x0002    第二个 X 按钮

    */


    UINT uSent = SendInput(ARRAYSIZE(inputs), inputs, sizeof(INPUT));
复制代码

 

单击鼠标 

复制代码
    HWND h = ::FindWindow(_T("#32770"), _T("测试窗口"));
    if (!h) {
        AfxMessageBox(_T("请打开测试程序"));
        ExitProcess(0);
    }
    ::ShowWindow(h, SW_NORMAL);
    ::SetForegroundWindow(h);

    HWND hWnd = ::GetDlgItem(h, 0x03E8);//获取子控件句柄
    CRect mRect;
    BOOL bb = ::GetWindowRect(hWnd, &mRect);//获取指定控件的边框矩形的坐标
    SetCursorPos((mRect.left+ mRect.right)/2, (mRect.top+ mRect.bottom)/2);//把光标移到屏幕的指定位置

    INPUT input[2] = {};
    input[0].type = INPUT_MOUSE;
    input[1].type = INPUT_MOUSE;

    input[0].mi.dwFlags = MOUSEEVENTF_LEFTDOWN;
    input[1].mi.dwFlags = MOUSEEVENTF_LEFTUP;

    UINT uSent = SendInput(ARRAYSIZE(input), input, sizeof(INPUT));
复制代码

测试窗口下载:

链接:https://pan.baidu.com/s/1s_5xvRpTUZtQDKPZ_INSmQ
提取码:6666

 

鼠标双击 

鼠标双击其实就是两次单击

实例看:https://www.cnblogs.com/liming19680104/p/17342378.html 

 

 

 

 

posted @   天子骄龙  阅读(1156)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek “源神”启动!「GitHub 热点速览」
· 我与微信审核的“相爱相杀”看个人小程序副业
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 如何使用 Uni-app 实现视频聊天(源码,支持安卓、iOS)
· C# 集成 DeepSeek 模型实现 AI 私有化(本地部署与 API 调用教程)
历史上的今天:
2020-04-20 万用表VICTOR VC890C+
2019-04-20 第十章浮力题汇总
点击右上角即可分享
微信分享提示

目录导航