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

时间:2017-09-29 13:16:48

标签: c# multiple-monitors cursor-position

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

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

1 个答案:

答案 0 :(得分:0)

事实证明,我不需要如此努力地进行手工转换。 PointToClient方法完成了将全局坐标转换为形状相对坐标的技巧。在我的例子中,我只是在每个屏幕上都有一个透明的表单,通过使用上面的currentDevice变量确定哪个表单是活动表单(包含鼠标光标的表单),然后使用活动表单上的PointToClient方法转换坐标

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