【问题标题】:Get cursor position relative to current screen in multi-monitor environments?在多显示器环境中获取相对于当前屏幕的光标位置?
【发布时间】:2017-09-29 13:16:47
【问题描述】:

我正在开发一个应用程序,它将在屏幕上围绕用户的鼠标坐标绘制一个屏幕捕获框。我试图让它在多个显示器上工作。使用 Cursor.Position 我可以获得全局坐标并确定用户在哪个屏幕上,但是因为我收到的坐标是全局坐标而不是相对于它所在的监视器,所以我在将全局坐标转换为屏幕相对坐标时遇到了困难定位。

当显示器全部垂直排列时,我可以使用基本逻辑来获取相对坐标,但我不确定当显示器以独特的方式设置时如何解决问题(即并非所有显示器的尺寸都相同, 一个在两个垂直显示器的右侧等)

这是我目前所拥有的:

_screens = ScreenHelper.GetMonitorsInfo();
CursorPosition = Cursor.Position;
var currentDevice = Screen.FromPoint(CursorPosition);

if (!currentDevice.Primary)
{
    // If the current screen is not the primary monitor, we need to calculate the cursor's current position relative to the screen.
    //Find the position in the screens array that the cursor is located, then the position of the primary display.
    var cursorIndex = _screens.IndexOf(_screens.Find(x => x.DeviceName == currentDevice.DeviceName));
    var primaryIndex = _screens.IndexOf(_screens.Find(x => x.DeviceName == Screen.PrimaryScreen.DeviceName));

    //Cursor is to the right of primary screen.
    if (primaryIndex > cursorIndex)
    {
        for (int i = cursorIndex + 1; i <= primaryIndex; i++)
        {
            CursorPosition = new Point(CursorPosition.X - _screens[i].HorizontalResolution, CursorPosition.Y);
        }
    }
    //Cursor is to the left of primary screen.
    else
    {
        for (int i = cursorIndex - 1; i >= primaryIndex; i--)
        {
            CursorPosition = new Point(CursorPosition.X + _screens[i].HorizontalResolution, CursorPosition.Y);
        }
    }
}

public static List<DeviceInfo> GetMonitorsInfo()
{
    _result = new List<DeviceInfo>();
    EnumDisplayMonitors(IntPtr.Zero, IntPtr.Zero, MonitorEnum, IntPtr.Zero);
    return _result;
}

[DllImport("user32.dll")]
private static extern bool EnumDisplayMonitors(IntPtr hdc, IntPtr lprcClip, MonitorEnumDelegate lpfnEnum, IntPtr dwData);

我是其中的一部分,但我不确定如何考虑水平甚至对角相对显示器定位。如何有效地获取相对于光标当前所在屏幕的鼠标坐标?

【问题讨论】:

  • _screens 是如何实例化的?
  • KDecker,我更新了 OP 以包含该信息。
  • 另外,我正在寻找相对于光标所在屏幕的坐标,而不仅仅是当前屏幕是哪个屏幕。
  • 很难看出这些信息有什么用处。但是你只需要减去 Screen.Bounds.X 和 Y。

标签: c# multiple-monitors cursor-position


【解决方案1】:

事实证明,我不需要那么努力地手动完成转换。 PointToClient 方法完成了将全局坐标转换为形式相对坐标的技巧。就我而言,我只是在每个屏幕上生成了一个透明表单,通过使用上面的 currentDevice 变量确定哪个表单是活动表单(包含鼠标光标的表单),然后在活动表单上使用 PointToClient 方法来转换坐标.

https://stackoverflow.com/a/19165028/3911065

【讨论】:

    【解决方案2】:

    有一个非常简单的方法可以做到这一点:

    辅助函数:

    // to get the currently active display's bounding rectangle
    public Rectangle GetCurrentDisplaySize()
    {
      return System.Windows.Forms.Screen.FromPoint(System.Windows.Forms.Cursor.Position).Bounds;
    }
    
    // to get the current cursor position
    public System.Drawing.Point GetCurrentCursorPosition()
    {
      return System.Windows.Forms.Cursor.Position;
    }
    
    

    用法:

    // always reload the display properties as the active display could change in multi-monitor setups
    Rectangle displayDimensions = GetCurrentDisplaySize();
    Point cursorPos = GetCurrentCursorPosition();
    int cursorRelativeToDisplayX = cursorPos.X - displayDimensions.X
    int cursorRelativeToDisplayY = cursorPos.Y - displayDimensions.Y
    

    这将从光标位置减去活动显示器的位置偏移,从而得到相对于活动显示器原点 (0,0) 的光标位置。
    就是这样,没有什么了¯\_(ツ)_/¯

    【讨论】:

      猜你喜欢
      • 2014-03-02
      • 1970-01-01
      • 1970-01-01
      • 2011-09-19
      • 1970-01-01
      • 2019-10-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多