0

This problem come to me with Telerik Testing Framework.
Telerik Testing Framework try to simulate mouse click using method SendInput to interact with application, but mouse click does not occur.

Under hood telerik code looks like

       [StructLayout(LayoutKind.Explicit)]
    public struct Input
    {
        [FieldOffset(0)]
        public int type;
        [FieldOffset(4)]
        public MOUSEINPUT mi;
    }

    [StructLayout(LayoutKind.Sequential)]
    public struct MOUSEINPUT
    {
        public int dx;
        public int dy;
        public uint mouseData;
        public uint dwFlags;
        public uint time;
        public IntPtr dwExtraInfo;
    }

    public static void MouseClick()
    {
        var leftDown = new Input();
        leftDown.type = 0;
        leftDown.mi.dwFlags = 2;
        SendInput(1, ref leftDown, Marshal.SizeOf(leftDown));


        var leftUp = new Input();
        leftUp.type = 0;
        leftUp.mi.dwFlags = 4;
        SendInput(1, ref leftUp, Marshal.SizeOf(leftUp));
    }
    [DllImport("user32.dll", SetLastError = true)]
    static extern uint SendInput(uint nInputs, ref Input pInputs, int cbSize);

But if change Input structure from LayoutKind.Explicit to LayoutKind.Sequential all works fine, for example:

[StructLayout(LayoutKind.Sequential)]
public struct Input
{
    public int type;
    public MOUSEINPUT mi;
}

In my opinion both variant must work, because in memory they are represented same.

Any idea why Input with LayoutKind.Explicit does not work?

1 Answers1

0

On a 64 bit system, MOUSEINPUT has an alignment of 8 because dwExtraInfo has alignment of 8. Which means that the correct offset on a 64 bit system is 8 rather than 4. If you switch to sequential layout then the C# compiler is able to place the MOUSEINPUT struct at the correct location.

That said, I don't much care for your version either. The INPUT struct is really a size field, followed by a union of MOUSEINPUT, KEYBDINPUT and HARDWAREINPUT. Including only the MOUSEINPUT relies on MOUSEINPUT having the same alignment as the other two members of the union, and having an alignment greater than or equal to that of the two omitted structs.

I suggest that you use the declaration of INPUT found here: https://stackoverflow.com/a/6833311/505088

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490