2010-06-09 3 views
5

Je veux yo utiliser SendMessage ou PostMessage appuyer sur un bouton dans une autre applicationCliquez sur un bouton dans une autre application

i ont un exemple de code pour le faire en obtenant la poignée de fenêtre, mais il ne fonctionne pas

J'ai aussi utilisé "WinDowse" pour obtenir les informations requises. voici le code

private const uint BM_CLICK = 0x00F5; 
private const uint WM_LBUTTONDOWN = 0x0201; 
private const uint WM_LBUTTONUP = 0x0202; 

private void PushOKButton(IntPtr ptrWindow) 
{ 
    WindowHandle = FindWindow(null, "Form1"); 
    if (ptrWindow == IntPtr.Zero) 
     return; 

    IntPtr ptrOKButton = FindWindowEx(ptrWindow, IntPtr.Zero, "Button", "&Yes"); 

    if (ptrOKButton == IntPtr.Zero) 
     return; 

    SendMessage(ptrOKButton, WM_LBUTTONDOWN, 0, 0); 
    SendMessage(ptrOKButton, WM_LBUTTONUP, 0, 0); 
    SendMessage(ptrOKButton, BM_CLICK, 0, 0); 
} 

Y at-il une Suloution Compelete dans C#?

Répondre

0

Vous avez la bonne idée générale. Il y a toujours des astuces à l'automatisation.

Bas/Up est preatty près de l'action brute de cliquer, mais pas tout à fait la même chose. Vous voulez envisager

  1. les coords où vous cliquez sur - certains boutons n'aiment pas les clics de bord à 0,0
  2. position de la souris - souris en dehors du bouton au début ou à la fin peut provoquer de ne pas travailler
  3. temps de cliquer - parfois un clic rapide est ignoré, ajoutez un petit retard de dire 10ms

BM_CLICK est un message win32 supplémentaire qui est envoyé lorsque vous faites un clic de souris sur un bouton - c'est la méthode plus courte et plus facile si les contrôles sont le bon type à utiliser thi s seul.

Certains efforts sont faits pour éviter que les choses comme l'utilisation de WM_GETTEXT sur les modifications de mot de passe des applications étrangères, méfiez-vous, vous pouvez également avoir des problèmes en fonction de l'application de destination.

Malheureusement j'ai pas de code C# exemple pour vous en ce moment.

Peut-être que vous pourriez regarder en AutoIT pour gagner du temps.

+0

* "Vous avez la bonne idée générale." * - Eh bien, non. L'idée est aussi mauvaise que possible. Les messages sont simplement la partie observable du traitement d'entrée. Si vous rejouez juste cette partie, vous finirez avec un état incohérent. La vraie réponse est [UI Automation] (https://msdn.microsoft.com/en-us/library/ms747327.aspx). – IInspectable

+0

Le framework .Net UI Automation est limité, et provoque une variété d'artefacts - comme le lecteur Adobe demandant le mode d'accessibilité si vous regardez même de côté les fenêtres qu'il affiche. Nous avons bloqué de nombreuses applications Microsoft essayant d'utiliser UI Automation en raison de bogues dans les applications cibles où la création de contrôle personnalisé n'a pas couvert correctement le support d'automatisation. –

+0

UI Automation est exposée via des objets COM, facilement consommables depuis .NET, dans le cas où la prise en charge de la bibliothèque pré-compilée n'est pas suffisante. Votre commentaire indique que vous avez répondu à une question différente: * "En supposant que UI Automation ne fonctionne pas pour nous, quelles sont les alternatives?" * L'OP n'a jamais prétendu que UI Automation ne fonctionnerait pas pour eux. . Et si vous avez besoin de fausses entrées, vous devez vraiment le faire correctement. Envoyer des messages ne fera pas (voir [Relecture d'entrée n'est pas la même que le retraitement] (https://blogs.msdn.microsoft.com/oldnewthing/20121206-00/?p=5903)). – IInspectable

-1

Voici un exemple d'utilisation de l'API win32 pour conduire la souris - en fait utilisé pour glisser-déposer sélection d'une zone, mais vous pouvez changer les coords de la souris vers le bas/à l'intérieur du bouton.

POINT p; 
BOOL cursorPosGetSuccessful = GetCursorPos(&p); 
mouse_event(MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE, horA, verA, NULL, 0); 
mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, NULL, 0); 
mouse_event(MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE, horB, verB, NULL, 0); 
mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, NULL, 0); 
if (cursorPosGetSuccessful)// put the mouse back to roughly where it used to be before the scan. 
    mouse_event(MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE, p.x, p.y, NULL, 0); 
+0

supposons que j'ai ces: coords de la souris, légende de la fenêtre, poignée de la fenêtre, nom de la classe de la fenêtre, pouvez-vous laisser un code complet? – sam

+0

Directement à partir de [mouse_event] (https://msdn.microsoft.com/en-us/library/windows/desktop/ms646260.aspx): * "Cette fonction a été remplacée Utiliser [SendInput] (https: // msdn .microsoft.com/fr-fr/library/windows/desktop/ms646310.aspx). "* Aucune ne vous permet de contrôler un processus spécifique; L'entrée va toujours au processus de premier plan. Comme indiqué sur votre autre réponse (pourquoi avez-vous ressenti le besoin irrésistible d'en poster deux quand même?): La vraie réponse est [UI Automation] (https://msdn.microsoft.com/fr-fr/library/ms747327.aspx) . – IInspectable

+0

Merci pour la mise à jour. Le deuxième message était dû à une réponse différente possible. –

Questions connexes