4

I am trying to send a simulated mouse click to another application. I understand how to actually send the key click, this is not the issue. I need to send the mouse click to the very center of the other application. I can simply test it once and find out the coordinate and send the click to that XY location, but there is an issue... When I move the window, or resize this window the XY coordinates will obviously not be the same.

So I need to find out how to get the size of the window, and its location and then find the center point from this. Anyone know how to do this? Thank you very much to any response!

Here is my code to send the mouse click

public void SendLeftClick(int x, int y)
{
    int old_x, old_y;
    old_x = Cursor.Position.X;
    old_y = Cursor.Position.Y;

    SetCursorPos(x, y);
    mouse_event(MouseEventFlag.LeftDown, x, y, 0, UIntPtr.Zero);
    mouse_event(MouseEventFlag.LeftUp, x, y, 0, UIntPtr.Zero);
    SetCursorPos(old_x, old_y);
}
John Saunders
  • 160,644
  • 26
  • 247
  • 397
user1127093
  • 85
  • 1
  • 3
  • 8

2 Answers2

1

You can use the GetWindowInfo API:

    [return: MarshalAs(UnmanagedType.Bool)]
    [DllImport("user32.dll", SetLastError = true)]
    private static extern bool GetWindowInfo(IntPtr hwnd, ref WINDOWINFO pwi);

    [StructLayout(LayoutKind.Sequential)]
    struct WINDOWINFO
    {
        public uint cbSize;
        public RECT rcWindow;
        public RECT rcClient;
        public uint dwStyle;
        public uint dwExStyle;
        public uint dwWindowStatus;
        public uint cxWindowBorders;
        public uint cyWindowBorders;
        public ushort atomWindowType;
        public ushort wCreatorVersion;

        public WINDOWINFO(Boolean? filler)
            : this()   // Allows automatic initialization of "cbSize" with "new WINDOWINFO(null/true/false)".
        {
            cbSize = (UInt32)(Marshal.SizeOf(typeof(WINDOWINFO)));
        }

    }
    [StructLayout(LayoutKind.Sequential)]
    struct RECT
    {
        public int left, top, right, bottom;
    }


    private void button1_Click_1(object sender, EventArgs e)
    {
        var p = System.Diagnostics.Process.GetProcessesByName("mspaint");

        if (p.Length == 0) return;

        WINDOWINFO wi = new WINDOWINFO(false);
        GetWindowInfo(p[0].MainWindowHandle, ref wi);

        SendLeftClick((wi.rcWindow.left + wi.rcWindow.right) / 2, (wi.rcWindow.top + wi.rcWindow.bottom) / 2);
    }
John Koerner
  • 37,428
  • 8
  • 84
  • 134
  • Seems overcomplicated, when `GetWindowRect` or `GetClientRect` would do. The extra complexity leads to errors, like that you didn't set `cbSize` before calling. – Ben Voigt May 25 '12 at 01:56
  • cbsize got set in the constructor of the windowinfo call. This call can also help if he needs to take into account borders of the window when doing calculations, but your point is valid. – John Koerner May 25 '12 at 01:58
  • In the one-parameter constructor you didn't use? – Ben Voigt May 25 '12 at 01:59
0

Set the cursor position AND also set 0,0 as X and Y in the mouse_event routine:

SetCursorPos(x, y);
mouse_event(MouseEventFlag.LeftDown, 0, 0, 0, UIntPtr.Zero);
mouse_event(MouseEventFlag.LeftUp, 0, 0, 0, UIntPtr.Zero);

Working fine for me now.

Rogério Silva
  • 121
  • 1
  • 11