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
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek “源神”启动!「GitHub 热点速览」
· 我与微信审核的“相爱相杀”看个人小程序副业
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 如何使用 Uni-app 实现视频聊天(源码,支持安卓、iOS)
· C# 集成 DeepSeek 模型实现 AI 私有化(本地部署与 API 调用教程)
2020-04-20 万用表VICTOR VC890C+
2019-04-20 第十章浮力题汇总