2010-05-12 4 views
6

J'essaye d'envoyer des clics de souris à un programme. Comme je ne veux pas que la souris bouge, je ne veux pas utiliser SendInput ou mouse_event, et parce que la fenêtre qui devrait recevoir les clics n'utilise pas vraiment les boutons ou d'autres événements GUI, je ne peux pas envoyer de messages à ceux-ci boutons.Clic de souris en envoyant des messages

J'essaye de faire fonctionner ceci en utilisant SendMessage, mais pour une raison quelconque cela ne fonctionne pas. Code pertinent est (en C#, mais a essayé Java avec jnative aussi), essayer ceci sur 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); 
    } 

Le close fonctionne très bien, mais le click ne fait rien.

edit: J'ai trouvé le problème. Outre le bogue stupide pour remplacer les coordonnées x et y, comme suggéré ci-dessous, je n'ai pas vérifié si le handle de fenêtre qui reçoit le clic est aussi la fenêtre client correcte. J'ai maintenant

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

qui fonctionne parfaitement.

Répondre

4

Le problème vient de l'empilement des coordonnées x, y.

  1. y devrait être le mot d'ordre élevé
  2. Vous devez utiliser | (Bitwise ou) pour combiner les composants de la paire de coordonnées

Vous devriez avoir les éléments suivants

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

@tobbez, le problème est que MAKELPARAM est une macro C, le code OPs est en réalité C# et il utilise Interop pour appeler les API Win32. –

+1

encore mieux '(y << 16) | (x & 0xffff) ' – BlackBear

0

Vous devez emballer les coordonnées correctement comme Chris dit, rappelez-vous aussi que x et y sont les coordonnées des clients , appelez ScreenToClient() pour convertir les coordonnées de l'écran.

Questions connexes