views:

42

answers:

2

I'm trying to send mouse clicks to a program. As I don't want the mouse to move, I don't want to use SendInput or mouse_event, and because the window that should receive the clicks doesn't really use Buttons or other GUI events, I can't send messages to these buttons.

I'm trying to get this working using SendMessage, but for some reason it doesn't work. Relevant code is (in C#, but tried Java with jnative as well), trying this on Vista

    [DllImport("user32.dll", CharSet=CharSet.Auto)]
    public static extern int SendMessage(IntPtr A_0, int A_1, int A_2,  int  A_3);

    static int WM_CLOSE = 0x10;
    static int WM_LBUTTONDOWN = 0x201;
    static int WM_LBUTTONUP = 0x202;

    public static void click(IntPtr hWnd, int x, int y)
    {
        SendMessage(hWnd, WM_LBUTTONDOWN, 1, ((x << 0x10) ^ y));
        SendMessage(hWnd, WM_LBUTTONUP, 0, ((x << 0x10) ^ y));
    }

    public static void close(IntPtr hWnd)
    {
        SendMessage(hWnd, WM_CLOSE, 0, 0);
    }

The close works fine, but the click doesn't do anything.

edit: Found the problem. Besides the stupid bug to replace the x and y coordinates, as suggested below, I didn't check if the Window handle that receives the click is also the correct client window. I now have

        POINT p = new POINT(x, y);
        IntPtr hWnd = WindowFromPoint(p);

        RECT rct = new RECT();

        if (!GetWindowRect(hWnd, ref rct))
        {
            return;
        }

        int newx = x - rct.Left;
        int newy = y - rct.Top;
        SendMessage(hWnd, WM_LBUTTONDOWN, 1, newy * 65536 + newx);
        SendMessage(hWnd, WM_LBUTTONUP, 0, newy * 65536 + newx);

which works perfect.

+1  A: 

The problem is with your packing of the x,y coordinates.

  1. y should be in the high order word
  2. You should use | (bitwise or) to combine the components of the coordinate pair

You should have the following

((y << 0x10) | x)
Chris Taylor
A: 

You need to pack the coordinates correctly like Chris says, also remember that x and y are client coordinates, call ScreenToClient() to convert screen coordinates.

Anders