2010-05-12 2 views
6

Я пытаюсь направить клики мыши на программу. Поскольку я не хочу, чтобы мышка перемещалась, я не хочу использовать SendInput или mouse_event, и поскольку окно, которое должно получать клики, на самом деле не использует кнопки или другие события GUI, я не могу отправлять сообщения этим кнопок.Нажатие мыши путем отправки сообщений

Я пытаюсь заставить эту работу использовать SendMessage, но по какой-то причине она не работает. Соответствующий код (в C#, но пытался Java с jnative, а), пытаясь это на 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); 
    } 

close работает отлично, но click ничего не делает.

Редактировать: Найдены проблемы. Помимо глупой ошибки для замены координат x и y, как было предложено ниже, я не проверял, является ли дескриптор окна, который получает клик, также правильное клиентское окно. У меня теперь есть

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

который работает идеально.

ответ

4

Проблема заключается в вашей упаковке координат x, y.

  1. y должно быть в слове высокого порядка
  2. Вы должны использовать | (Побитовое или), чтобы объединить компоненты пары координат

Вы должны иметь следующее

((y << 0x10) | x) 
+0

@tobbez, проблема в том, что MAKELPARAM является макросом C, код OPs на самом деле является C#, и он использует Interop для вызова в API Win32. –

+1

еще лучше '(y << 16) | (x & 0xffff) ' – BlackBear

0

Вам необходимо правильно упаковать координаты, как говорит Крис, а также помнить, что х и у координаты клиента , вызовите ScreenToClient() для преобразования координат экрана.

Смежные вопросы