名字不能取太长 2024-12-07 21:11 采纳率: 75%
浏览 26
已结题

关于远程桌面的鼠标位置转换

我在编写自己的远程桌面,在转换鼠标位置时发现转换到被控端的鼠标坐标不精确,以下是我的被控端的鼠标坐标转换代码:

float relative_x = event->mouse_x / 1280.0f; 
float relative_y = event->mouse_y / 720.0f;
int x = static_cast<int>(relative_x * desk_width); 
int y = static_cast<int>(relative_y * desk_height);
SetCursorPos(x, y);

上述代码将主控端中鼠标相对于窗体的坐标转换为被控端相对于屏幕左上角的坐标,其中1280和720分别是主控端窗体的宽度和高度,event->mouse_x和event->mouse_y是被控端接收到的主控端鼠标相对于窗体的坐标,请问以上代码如何修改能够更加精确的得到被控端的鼠标位置? 现在的偏差有点大。

  • 写回答

17条回答 默认 最新

  • bug菌¹ 优质创作者: Java、算法与数据结构技术领域 2024-12-07 22:20
    关注

    该回答引用ChatGPT-4o并结合自身经验回答,望对题主有所帮助/启发;若有帮助,还望采纳🤝🤝🤝


    您遇到的问题是远程桌面中鼠标坐标转换不精确,导致鼠标的位置偏差。问题的根源可能在于以下几个方面:

    1. 坐标比例的设定
      由于您使用的 1280x720 是主控端的窗口分辨率,而被控端的屏幕分辨率可能与之不匹配。如果主控端和被控端分辨率不同,直接按比例进行缩放会导致坐标不准确。

    2. 分辨率和 DPI 的差异
      不同设备的屏幕分辨率和 DPI(每英寸像素数)可能会有所不同。如果没有考虑 DPI 差异,可能会导致偏差。

    解决方案

    1. 使用主控端屏幕分辨率
      目前代码将主控端的鼠标坐标按 1280x720 转换到被控端的屏幕坐标。但如果主控端和被控端的分辨率不同,您应该根据主控端和被控端的实际分辨率进行转换。例如:

      // 获取主控端和被控端的屏幕分辨率
      int desk_width = GetSystemMetrics(SM_CXSCREEN);  // 被控端的屏幕宽度
      int desk_height = GetSystemMetrics(SM_CYSCREEN); // 被控端的屏幕高度
      
      // 计算主控端和被控端分辨率的比例
      float ratio_x = (float)desk_width / 1280.0f;
      float ratio_y = (float)desk_height / 720.0f;
      
      // 根据比例转换鼠标坐标
      int x = static_cast<int>(event->mouse_x * ratio_x);
      int y = static_cast<int>(event->mouse_y * ratio_y);
      SetCursorPos(x, y);
      
    2. 考虑 DPI 缩放
      如果主控端和被控端设备的 DPI 设置不同,可能会影响坐标转换。Windows 10 引入了 DPI 缩放(即高DPI设置),这会影响应用程序的坐标系统。为了保证精确的转换,您需要考虑 DPI 设置,具体可通过 GetDpiForSystem() 等函数获取 DPI 信息并做相应调整。

      例如,您可以通过计算 DPI 差异来修正鼠标坐标:

      // 获取主控端和被控端的 DPI
      int dpi_x = GetDpiForSystem();
      int dpi_y = GetDpiForSystem();
      
      // 调整比例以考虑 DPI 差异
      float dpi_ratio_x = (float)dpi_x / 96.0f; // 96 DPI 是标准 DPI
      float dpi_ratio_y = (float)dpi_y / 96.0f;
      
      // 计算主控端和被控端的分辨率比例
      float ratio_x = (float)desk_width / 1280.0f * dpi_ratio_x;
      float ratio_y = (float)desk_height / 720.0f * dpi_ratio_y;
      
      int x = static_cast<int>(event->mouse_x * ratio_x);
      int y = static_cast<int>(event->mouse_y * ratio_y);
      SetCursorPos(x, y);
      
    3. 优化坐标转换算法
      如果主控端的窗口本身有缩放(如不全屏、或有屏幕缩放设置),您需要进一步改进坐标转换逻辑。您可以通过获取主控端窗口的实际显示区域,来替代硬编码的 1280x720 数值。

      // 获取主控端窗口的实际尺寸
      RECT window_rect;
      GetWindowRect(hwnd, &window_rect);
      int window_width = window_rect.right - window_rect.left;
      int window_height = window_rect.bottom - window_rect.top;
      
      // 计算转换比例
      float ratio_x = (float)desk_width / window_width;
      float ratio_y = (float)desk_height / window_height;
      
      int x = static_cast<int>(event->mouse_x * ratio_x);
      int y = static_cast<int>(event->mouse_y * ratio_y);
      SetCursorPos(x, y);
      

    总结

    要确保鼠标坐标精确转换,关键是要正确地根据屏幕分辨率、DPI 和窗口尺寸来进行坐标的缩放。以上的代码修改应该能够在不同分辨率和设备设置下,提供更加精确的坐标转换。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(16条)

报告相同问题?

问题事件

  • 系统已结题 12月15日
  • 已采纳回答 12月7日
  • 创建了问题 12月7日