Question

J'essaie d'utiliser le code suivant pour appuyer sur un bouton de mon autre application:

HWND ButtonHandle;
if( (wnd = FindWindow(0, "Do you want to save?")) )
{   
   ButtonHandle = FindWindowEx(wnd, 0, "SaveButton", "&Save");
   SendMessage(wnd, WM_COMMAND, MAKEWORD(GetDlgCtrlID(ButtonHandle), BN_CLICKED ), (LPARAM)ButtonHandle);

}

Ça ne marche pas. J'ai essayé de passer différentes poignées à MAKEWORD et de changer les WPARM et LPARAM mais rien.

Des idées sur la manière de cliquer sur un bouton dans la fenêtre d'une autre application?

Le code est apprécié. Merci.

EDIT: La raison pour laquelle cela ne semble pas fonctionner les autorisations. J'ai envoyé un PostMessage () et le résultat était une erreur avec GetLastError () = 5 (ou Access Denied). Des idées?

EDIT2 Je ne veux pas être impoli, mais s'il vous plaît, s'il vous plaît, j'ai déjà effectué une recherche sur toutes les API, y compris l'obtention et la définition des régions du bouton, puis l'envoi d'un bouton l'identifiant de contrôle, obtenant l'identifiant de classe et un zillion de plus. La raison pour laquelle j'ai posé la question ici en premier lieu, c'est parce que j'ai déjà épuisé mes recherches sur Internet. Si vous connaissez la réponse, PLEASE POST CODE , ne suggérez pas d’API et c’est tout, expliquez-moi comment cette API résout le problème. C'est pas difficile. Merci.

EDIT 3: la réponse à la question a été sélectionnée automatiquement à la fin de la prime. La question reste sans réponse.

Était-ce utile?

La solution

  1. Êtes-vous sûr que " SaveButton " Le nom de la classe est valide? Avez-vous le bouton gérer?
  2. Essayez d'envoyer des messages à la fenêtre ButtonHandle (directement au bouton).

Mise à jour: Je pense que cela devrait fonctionner,

SendMessage(ButtonHandle, BM_CLICK, 0, 0);

Autres conseils

SendMessage(btnHandle, WM_LBUTTONDOWN, 0, 0);
SendMessage(btnHandle, WM_LBUTTONUP, 0, 0);
SendMessage(btnHandle, WM_LBUTTONDOWN, 0, 0);
SendMessage(btnHandle, WM_LBUTTONUP, 0, 0);

Vous devez envoyer un clic de bouton deux fois. Vous ne savez pas pourquoi (peut-être que le premier clic active uniquement la fenêtre du bouton), mais j'utilise ce code depuis longtemps et cela a toujours fonctionné pour moi.

peut-être que cela peut aider: http://www.cplusplus.com/forum/beginner/8806/

Voir la solution suivante, vous pouvez aussi utiliser

SendMessage(ButtonHandle, WM_LBUTTONDOWN, 0, 0);
SendMessage(ButtonHandle, WM_LBUTTONUP, 0, 0);

Ou

SendMessage(ButtonHandle, BM_CLICK, 0, 0);

HWND buttonHandle = 0;

BOOL CALLBACK GetButtonHandle(HWND handle, LPARAM)
{
 char label[100];
 int size = GetWindowTextA(handle,label,sizeof(label));
 if(strcmp(label,"&Save") == 0)
 {
  buttonHandle = handle;
  return false;
 }
 return true;
}
void main()
{
 HWND windowHandle = FindWindowA(NULL,"Do you want to Save?");
 if(windowHandle != 0)
 {
  BOOL ret = EnumChildWindows(windowHandle,GetButtonHandle,0);

  if(buttonHandle != 0)
  {
   LRESULT res = SendMessage(buttonHandle,BM_CLICK,0,0);
   //SendMessage(buttonHandle,WM_LBUTTONDOWN,0,0); 
   //SendMessage(buttonHandle,WM_LBUTTONUP,0,0);
  }

 }



}

Remarque: S'assurer du texte de la fenêtre, du texte du bouton (vérifiez s'il y a de la place à la fin du titre de la fenêtre)

Les erreurs d'accès refusé sur SendMessage ou PostMessage n'ont de sens que si le processus d'envoi du message s'exécute à un niveau d'intégrité inférieur au processus cible.

Cela ne devrait se produire que si le processus propriétaire de la fenêtre cible est en cours d'exécution & "en tant qu'administrateur &"; ou est un service. Et il est extrêmement difficile pour les services de créer des fenêtres sur le bureau interactif avec Windows 6 et les versions ultérieures.

Vous pouvez en savoir plus sur les niveaux d'intégrité ici s'ils le sont appliquer même à distance à cette situation. Internet Explorer est à peu près la seule autre application qui «adhère» au modèle de sécurité de l’intégrité en abaissant volontairement son niveau d’intégrité afin de se sandboxer plus efficacement.

Si vous pouvez soulever la fenêtre contenant le bouton, vous pouvez envoyer un événement de souris brut à une position comprise dans les limites du bouton.

Il existe deux fonctions pour simuler un événement de souris SendInput et mouse_event . Je recommande d'utiliser la fonction WM_CUSTOM. Pour ouvrir une fenêtre, vous pouvez utiliser ShowWindow . Je ne sais pas comment obtenir la poignée d'un bouton, mais si vous avez son hWnd, il est facile de trouver sa position absolue avec GetWindowRect . Essayez de les utiliser, si vous rencontrez des problèmes, je serai heureux de vous aider.

Ou définissez un WM personnalisé dans la fenêtre de votre application pour gérer la demande de sauvegarde. WM_USER ou <=> (ne me souviens plus lequel) marque le début des messages de fenêtre définis par l'utilisateur.

Lorsque je dois faire ce genre de choses, j'utilise SendKeys. C’est VB-ish et C # fournit une interface agréable à utiliser, mais pour C / C ++, vous devez le faire & Lt; de cette façon > ;. Ce qui est bien, c’est que vous pouvez écrire des scripts et les exécuter au lieu de les coder en dur dans votre code.

Microsoft utilise maintenant l'accessibilité active (MSAA) pour UI Automation, (Il a été renommé plusieurs fois au fil des ans)  voir

Désolé, je & # 8217; je n'ai pas de code simple pour vous aider à démarrer. As & # 8220; SendMessage () & # 8221; ne semble pas fonctionner pour vous, je ne & # 8217; ne connais aucune autre option que & # 8220; UI Automation & # 8221;

Je suppose que vous avez vérifié avec Spy ++ (installé avec MsDev) que votre message est envoyé au bon bouton, etc. & # 8211; et que le bouton est un boutons Windows standard. Mon premier instant dirait que vous utilisiez & # 8220; SendMessage () & Quot; ou " PostMessage () & # 8221; mais étant donné le nombre de réponses à propos de & # 8220; SendMessage () & # 8221; et le fait que cela ne fonctionne pas pour vous. Je m'attends à ce que quelqu'un se passe & # 8230;

Vous pouvez utiliser sendkeys (comme l'a dit tr3) pour envoyer des clics de souris, ce qui est différent de l'utilisation de SendMessage. Il est également moins direct et plus hack-ish, mais il est utile pour l’automatisation (sous VBS).

En outre, devinez bien, mais le problème pourrait être que votre gestion des messages est interrompue quelque part si vous n'appelez pas le membre de la classe de base. Exemple:

void CMyClass::OnMessageY(CWnd *cwnd)
{
    CBaseClass::OnMessageY(cwnd);
    //... my code
}

si vous êtes certain que ButtonHandle est un handle valide, vous pouvez utiliser la paire de messages WM_LBUTTONDOWN et WM_LBUTTONUP au lieu de BN_CLICKED

HWND ButtonHandle;
if( (wnd = FindWindow(0, "Do you want to save?")) )
{   
    SendMessage(ButtonHandle, WM_LBUTTONDOWN, MK_LBUTTON, 0);
    SendMessage(ButtonHandle, WM_LBUTTONUP, MK_LBUTTON, 0);
}

Une approche non C: utilisez Java et la classe java.awt.Robot pour déplacer la souris et effectuez des clics réels (je suppose qu'il existe également quelque chose dans le monde Windows). Problème: vous devez savoir où se trouve votre bouton: D

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top