Pourquoi mes presses de bouton truquées échouent-elles avec SendMessage?

J’essaie d’envoyer des événements de souris à une fenêtre dans Windows via la méthode SendMessage(..) .

Le problème auquel je suis confronté est que les messages ne semblent pas être livrés à la fenêtre que je les envoie, même si SendMessage renvoie 0 , ce qui (selon la documentation) signifie que le message a été livré avec succès.

J’utilise le morceau de code suivant:

(Soit p une structure Point et selectedWindow.Handle un handle valide à une fenêtre)

 int position = ((pX & 0xFFFF) << 16) | (pY & 0xFFFF); SendMessage(selectedWindow.Handle, 0x0201, new IntPtr(), new IntPtr(position)); SendMessage(selectedWindow.Handle, 0x0202, new IntPtr(), new IntPtr(position)); 

0x0201 et 0x0202 sont WM_LBUTTONDOWN et WM_LBUTTONUP .

Quelqu’un pourrait-il m’expliquer pourquoi cela ne fonctionne pas?

(Edit: j’utilise la méthode ScreenToClient() pour convertir une position d’écran en une position dans la fenêtre)

Les messages de souris sont normalement extraits de la queue des messages, ce qui signifie que vous devez utiliser PostMessage (). Mais il est peu probable que ce soit le vrai problème, très peu de programmes effectuent la manipulation de la souris dans la boucle de messages. UAC est un scénario d’échec évident, vous ne pouvez pas envoyer de messages à une fenêtre appartenant à un programme élevé. Vous envoyez la mauvaise valeur de WParam, cela pourrait avoir un effet. Et bien sûr, vous pourriez avoir la mauvaise poignée de fenêtre.

Mais la cause la plus probable est le code que nous ne pouvons pas voir. Vous semblez avoir du mal à générer les coordonnées X et Y du message. Aucun effort de ce type n’est nécessaire, peu importe vous cliquez sur le bouton. Vous pourriez aussi bien cliquer sur (1, 1):

  PostMessage(selectedWindow.Handle, 0x0201, new IntPtr(1), new IntPtr(0x10001)); PostMessage(selectedWindow.Handle, 0x0202, new IntPtr(0), new IntPtr(0x10001)); 

Ou en d’autres termes, les coordonnées de la souris sont relatives du coin supérieur gauche de la fenêtre. Des hacks supplémentaires génèrent le message BM_CLICK et tout message WM_COMMAND généré par le bouton.

Utilisez l’outil Spy ++ pour observer le traitement des messages.

J’ai trois suggestions:

Tout d’abord, assurez-vous que les coordonnées sont relatives à l’origine de la zone client de la fenêtre. Si vous utilisez des coordonnées d’écran, vous devez d’abord utiliser la fonction ScreenToClient pour les convertir.

Deuxièmement, essayez d’utiliser PostMessage au lieu de SendMessage. Cela émule plus étroitement le comportement réel de Windows.

Enfin, à moins que vous ne soyez absolument opposé au déplacement du pointeur de la souris, vous pouvez trouver plus facile d’utiliser la fonction mouse_event ou SendInput.