当前位置: 首页 > article >正文

Windows截获系统鼠标消息转发到指定窗口

注册输入设备,截获系统底层的设备消息

先看关键代码:


RAWINPUTDEVICE rids[1];
rids[0].usUsagePage = HID_USAGE_PAGE_GENERIC; //0x01
rids[0].usUsage = HID_USAGE_GENERIC_MOUSE; //0x02
rids[0].dwFlags = RIDEV_INPUTSINK; //0x00000100
rids[0].hwndTarget = win->hwnd;
RegisterRawInputDevices(rids, 1, sizeof(rids[0]));

这段代码中,RegisterRawInputDevices 方法用于让程序注册一个或多个输入设备(代码中仅注册了一个),以便应用程序可以直接接收来自这些设备的原始输入数据。

参数RAWINPUTDEVICE的属性usUsagePage的值为HID_USAGE_PAGE_GENERIC,表示通用输入设备。

dwFlags属性的值为HID_USAGE_GENERIC_MOUSE,表示鼠标设备。

dwFlags属性的值为RIDEV_INPUTSINK ,表示原始输入设备的输入将发送到指定的目标窗口,而不是默认的窗口。这意味着即使目标窗口没有被激活,它仍然可以接收输入。

hwndTarget属性的值为目标窗口的句柄。

处理截获到的消息

如下代码所示:


LRESULT CALLBACK processMsg(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
  if (uMsg != WM_INPUT) {
      return CallWindowProc(oldProc, hWnd, uMsg, wParam, lParam);
  }
  UINT dwSize = sizeof(RAWINPUT);
  static BYTE lpb[sizeof(RAWINPUT)];
  GetRawInputData((HRAWINPUT)lParam, RID_INPUT, lpb, &dwSize, sizeof(RAWINPUTHEADER));
  auto raw = (RAWINPUT*)lpb;
  if (raw->header.dwType == RIM_TYPEMOUSE){
    RAWMOUSE rawMouse = raw->data.mouse;
    if (rawMouse.usButtonFlags == RI_MOUSE_WHEEL)
    {
       //鼠标滚轮消息
      return 0;
    }
    switch (rawMouse.ulButtons)
    {
        case RI_MOUSE_LEFT_BUTTON_DOWN:
        {
           //鼠标左键按下消息 
          return 0;               
        }
        case RI_MOUSE_LEFT_BUTTON_UP:
        {
             //鼠标左键弹起消息;
            return 0;
        }
        default:
        {
             //鼠标移动消息
            return 0;
        }
    }
  }
  return CallWindowProc(oldProc, hWnd, uMsg, wParam, lParam);
}

截获到的消息都是 WM_INPUT 消息,其他消息我们就交由窗口的原有消息处理函数处理了。

截获到的消息数据存储在lParam中,我们通过GetRawInputData方法把这些数据提取到一个RAWINPUT类型的对象中。

由于我们只截获了鼠标消息,所以又从RAWINPUT对象中提取了RAWMOUSE类型的对象,我们只处理鼠标消息。

当这个RAWMOUSE对象的usButtonFlags属性值为RI_MOUSE_WHEEL时,表示鼠标滚轮消息。

这个对象的ulButtons属性的值代表着鼠标消息的其他类型,比如鼠标左键按下:RI_MOUSE_LEFT_BUTTON_DOWN,鼠标左键弹起:RI_MOUSE_LEFT_BUTTON_UP等。

如果窗口是你自己的,此时你就可以执行具体的方法了,如果窗口不是你自己的,你还可以把这些消息发送给目标窗口。如下代码所示:


auto lParam = MAKELPARAM(point.x, point.y);
PostMessage(win->hwnd, WM_LBUTTONUP, MK_LBUTTON, lParam);

当然,鼠标消息要注意处理鼠标的坐标呦(你希望得到绝对坐标还是相对坐标呢?)


http://www.kler.cn/a/511452.html

相关文章:

  • Kinova仿生机械臂Gen3搭载BOTA 力矩传感器SeneOne:彰显机器人触觉 AI 与六维力传感的融合力量
  • Python制作简易PDF查看工具PDFViewerV1.0
  • 4 AXI USER IP
  • 双向耦合粒子追踪稳态求解器找到未定义的值?
  • python编程-OpenCV(图像读写-图像处理-图像滤波-角点检测-边缘检测)图像变换
  • vscode离线安装插件--终极解决方案
  • Unity 热更新对象绑定的替代方案--StrangeIoC 注入方式
  • 计算机毕业设计Python+卷积神经网络租房推荐系统 租房大屏可视化 租房爬虫 hadoop spark 58同城租房爬虫 房源推荐系统
  • 3D线上会议:打破空间限制,重塑会议未来
  • 管理口令安全和资源(二)
  • CSS笔记基础篇01——选择器、文字控制属性、背景属性、显示模式、盒子模型
  • HTTP/2 与 HTTP/3 的新特性
  • Matlab总提示内存不够用,明明小于电脑内存
  • DilateFormer: Multi-Scale Dilated Transformer for Visual Recognition 中的空洞自注意力机制
  • ACL基础理论
  • 跨境电商使用云手机用来做什么呢?
  • 网络系统管理Linux环境——ROUTERSRV之SSH
  • 怎么在iPhone手机上使用便签进行记录?
  • 在亚马逊云科技上高效蒸馏低成本、高精度的Llama 3.1 405B模型(上篇)
  • QT 使用OpenGL显示并查看点云图
  • LabVIEW 水电站厂内经济运行系统
  • Spring Security 6.X + JWT + RBAC 权限管理实战教程(上)
  • Redis 在项目中的实战应用与复盘
  • CSS中样式继承+优先级
  • 本地ocr实现监听屏幕弹窗并进行邮箱通知
  • java微服务的异常