SendInput在扩展屏幕上无法正常工作

本文关键字:常工作 工作 扩展 屏幕 SendInput | 更新日期: 2023-09-27 18:01:04

使用SendInput的鼠标刺激在MainDisplay上非常有效。但是,当我将SendInput用于扩展屏幕时(例如,在我的情况下,第二个屏幕位于主显示器的左侧。无论扩展显示器在主显示器周围的任何位置,问题都是可复制的,但分辨率与主显示器不同(:如果我在扩展屏幕上使用SendInput,鼠标位置在X和Y位置都有偏移,因此,根据扩展屏幕的X(宽度(和Y(高度(是否与主显示器的宽度/高度不同,在X上的偏移范围为40到80点,在Y上的偏移为10到20点

提前感谢您对扩展屏幕差异的任何支持

[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);
    }

SendInput在扩展屏幕上无法正常工作

发现问题。使用SendInput时,必须根据主屏幕/主屏幕转换x、y的绝对值。因此变化:

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);
}