2016-08-06 9 views
1

Стимуляция мыши с использованием SendInput отлично работает на MainDisplay. Однако, когда я использую SendInput для расширенного экрана (например, второй экран размещен слева от основного дисплея в моем случае. Проблемы воспроизводятся независимо от расширенного отображения в любом месте вокруг основного дисплея, но с разным разрешением, а затем на главном дисплее): Если я использую SendInput на расширенном экране позиция мыши имеет смещение как в положении X, так и Y, всегда немного от 40 до 80 точек в x и от 10 до 20 точек в Y на основе, если X (ширина) и Y (высота) расширенного экрана отличается от основной ширины дисплея/высота)SendInput не работает отлично на расширенном экране

заранее спасибо за какой-либо поддержки о том, почему разница на расширенном экране

[DllImport("user32.dll")] 
[return: MarshalAs(UnmanagedType.Bool)] 
private static extern bool GetCursorPos(ref Win32Point pt); 

[DllImport("user32.dll")] 
internal static extern bool SetCursorPos(int X, int Y); 

[StructLayout(LayoutKind.Sequential)] 
internal struct Win32Point 
{ 
    public Int32 X; 
    public Int32 Y; 
}; 

internal enum SendInputEventType : int 
{ 
    InputMouse, 
    InputKeyboard 
} 

[DllImport("user32.dll", SetLastError = true)] 
    private static extern uint SendInput(uint nInputs, ref Input pInputs, int cbSize); 

public struct Input 
{ 
    public uint InputType; 
    public MouseInput MI; 
} 

public struct MouseInput 
{ 
    public int Dx; 
    public int Dy; 
    public uint MouseData; 
    public uint DwFlags; 
    public uint Time; 
    public IntPtr DwExtraInfo; 
} 

public enum MouseEventInfo 
{ 
    mouseEventfMove = 0x0001, 
    mouseEventfLeftdown = 0x0002, 
    mouseEventfLeftup = 0x0004, 
    mouseEventfRightdown = 0x0008, 
    mouseEventfRightup = 0x0010, 
    mouseEventfWheel = 0x0800, 
    mouseEventfAbsolute = 0x8000, 
    wheelDelta = 0x0078 
} 

static int CalculateAbsoluteCoordinateX(int x, System.Drawing.Rectangle currentBounds) 
    { 
     return ((currentBounds.X + x) * 65536)/(currentBounds.Width); 
    } 

    static int CalculateAbsoluteCoordinateY(int y, System.Drawing.Rectangle currentBounds) 
    { 
     return (((currentBounds.Y + y) * 65536)/currentBounds.Height); 
    } 

// for me screen at index 0 (screen no 1) is main display. Screen id 2 
//placed to the left of the main display as per resolution screen i.e.at 
//index 1 (Screen.AllScreens[1]) is extended display and Bound.X is a -ve value 
    public static int ScreenId = 2; 

    public static System.Drawing.Rectangle CurrentBounds 
    { 
     get 
     { 
      return SysForms.Screen.AllScreens[ScreenId - 1].Bounds; 
     } 
    } 

    public static void ClickLeftMouseButton(int x, int y) 
    { 
     Input mouseInput = new Input(); 
     mouseInput.InputType = SendInputEventType.InputMouse; 
     mouseInput.MI.Dx = CalculateAbsoluteCoordinateX(x, CurrentBounds); 
     mouseInput.MI.Dy = CalculateAbsoluteCoordinateY(y, CurrentBounds); 
     mouseInput.MI.MouseData = 0; 

     mouseInput.MI.DwFlags = MouseEventInfo.mouseEventfMove | MouseEventInfo.mouseEventfAbsolute; 
     SendInput(1, ref mouseInput, Marshal.SizeOf(new INPUT())); 

     mouseInput.MI.DwFlags = MouseEventInfo.mouseEventfLeftdown; 
     SendInput(1, ref mouseInput, Marshal.SizeOf(new INPUT())); 

     mouseInput.MI.DwFlags = MouseEventFlags.mouseEventfLeftup; 
     SendInput(1, ref mouseInput, Marshal.SizeOf(new INPUT())); 
    } 

//Below is code of the WPF MainWindow for testing. Two buttons with click  event. 
// For main display with screenid as 1 both setcursor position and sendinput 
//work perfectly, as I get the MousePosition, but when I apply this to 
//extended screen (currently with two screen, main display is screen 1 in my   
//case and screen 2 is extended screen, they put the mouse at two different positions. 
//I have my doubts the way I am using the extended screen Bounds.X, but 
//haven't will able to fix the issue 

    int x = 600; 
    int y = 300; 

    private void btnSend_Click(object sender, RoutedEventArgs e) 
    { 
     SetCursorPos(SysForms.Screen.AllScreens[ScreenId - 1].Bounds.X + x, SysForms.Screen.AllScreens[screenId - 1].Bounds.Y + y);    
    } 

    private void btnSend1_Click(object sender, RoutedEventArgs e) 
    { 
     ClickLeftMouseButton(x, y); 
    } 
+0

Я не могу ответить на ваш вопрос, но я заметил на мой рабочий компьютер (который имеет два различных решения), что окна, охватывающие оба экрана имеют ужасное время с контекстным меню, выпадающие коробки и т. д., выравниваются правильно и даже правильно калибруются. – leetibbett

ответ

0

Найдено вопрос. При использовании SendInput преобразование x, y в абсолютном значении должно выполняться в отношении экрана Main/Primary. Таким образом, изменения:

static int CalculateAbsoluteCoordinateX(int x, System.Drawing.Rectangle currentBounds) 
{ 
    return ((currentBounds.X + x) * 65536)/(SystemParameters.PrimaryScreenWidth); 
} 

static int CalculateAbsoluteCoordinateY(int y, System.Drawing.Rectangle currentBounds) 
{ 
    return (((currentBounds.Y + y) * 65536)/SystemParameters.PrimaryScreenHeight); 
}