繁体   English   中英

在多显示器环境中获取相对于当前屏幕的光标位置?

[英]Get cursor position relative to current screen in multi-monitor environments?

我正在开发一个应用程序,它将围绕用户的鼠标坐标在屏幕上绘制一个屏幕捕获框。 我试图让它在多个显示器上工作。 使用 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);

我已经到了那里,但我不确定如何考虑水平甚至对角线相对显示器定位。 如何有效地获取相对于光标当前所在屏幕的鼠标坐标?

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

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

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

辅助功能:

// 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) 的光标位置。
就是这样,没什么了 ¯\\_(ツ)_/¯

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM