"Petit" problemme de HANDLE

Signaler
Messages postés
4
Date d'inscription
vendredi 4 février 2005
Statut
Membre
Dernière intervention
4 septembre 2006
-
Messages postés
21042
Date d'inscription
jeudi 23 janvier 2003
Statut
Modérateur
Dernière intervention
21 août 2019
-
Bonjour a tous !

Alor voilà mon probleme, j'ai dans mon application , écrit une fonction permettant de lancer un autre programme externe, que je n'ai pas développé.

A l'aide de la fonction ShellExecuteEx(), jusque là, ça vas, maintenant le programme externe en question se lance de lui même en mode console (fenêtre de cmd msdos), et pour l'arrêter il suffit de sélectionner sa fenêtre et de presser "F4" sur le clavier.

Je n'arrive pas à récupérer le handle de cette fenêtre par son nom exact, qui a mon avis est trop long ou peut-être mal formaté je ne sais pas (je precise au passage que ce programme externe est prévu pour tourner aussi bien sous Linux que sous Windows peut-être que le probleme du nom de la fenêtre vient de là, je suis sous Windows XP)....
bon j'arrive quand même a récupérer son handle, par sa classe,

la classe "ConsoleWindowClass" en faisant : FindWindow("ConsoleWindowClass",NULL),

ok, là j'ai son handle et je met la fenêtre au premier plan

par un SetForegroundWindow(Le_handle_de_la_fenetre), là toujours pas de problème, la

fenêtre se met bien au premier plan, et elle est bien sélectionnée.

Maintenant, je veux simuler la pression de la touche "F4" du clavier, et là problème !!

en faisant dans mon application :

PostMessage (Le_handle_de_la_fenetre,WM_KEYDOWN,VK_F4,0), il n'y à aucun effet ! il ne se ferme pas !

J'ai un moyen de le fermer quand même en faisant celà :

PostMessage (Le_handle_de_la_fenetre,WM_CLOSE,0,0) , mais en faisant celà je n'ai aucune certitude que le programme en question se termine proprement !

Voilà donc mon probleme pour résumer, je n'arrive pas à fermer ce programme externe qui lui n'attend qu'une simple pression de la touche "F4" sur le clavier pour se terminer !! j'ai pas mal fait d'essais, et là j'avoue ke je butte !! Quelqu'un pourrait-t-il m'éclairer sur la question ?

Jab

5 réponses

Messages postés
196
Date d'inscription
mercredi 6 août 2003
Statut
Membre
Dernière intervention
1 mai 2009
2
Ne faudrait il pas que tu passes par un hook pour cela, car il semble s'agir somme toute du pilotage d'un programme par un autre programme. Un handle récupéré par un FindWindow permet de modifier quelques éléments d'apparence d'une fenête d'un autre programme comme le nom de la fenêtre, la taille... En outre, je ne sais pas si pour la cloture d'un programme cela peut se faire aussi simplement.

LaPatoshe
Messages postés
36
Date d'inscription
samedi 2 octobre 2004
Statut
Membre
Dernière intervention
11 juin 2005

Peut-être avec CloseHandle ?
Messages postés
21042
Date d'inscription
jeudi 23 janvier 2003
Statut
Modérateur
Dernière intervention
21 août 2019
27
A tester:
WaitForSingleObject() sur le SHELLEXECUTEINFO.hprocess
suivi d'un TerminateProcess(SHELLEXECUTEINFO.hprocess, 0);

ciao...
BruNews, MVP VC++
Messages postés
4
Date d'inscription
vendredi 4 février 2005
Statut
Membre
Dernière intervention
4 septembre 2006

ok, j'ai éssayé le WaitForSingleObject() juste apres un ShellExecuteEx(&ExecuteInfo),

memset(&ExecuteInfo, 0, sizeof(ExecuteInfo));


ExecuteInfo.cbSize = sizeof(ExecuteInfo);
ExecuteInfo.fMask = SEE_MASK_NOCLOSEPROCESS;
ExecuteInfo.hwnd = 0;
ExecuteInfo.lpVerb = "open";
ExecuteInfo.lpFile = "leprog";
ExecuteInfo.lpParameters = mes_parametres; //parametres pour leprog
ExecuteInfo.lpDirectory = 0;
ExecuteInfo.nShow = SW_SHOW;
ExecuteInfo.hInstApp = 0;


if(ShellExecuteEx(&ExecuteInfo) == FALSE)
{
// erreur
}else{}


DWORD test;


test = WaitForSingleObject(ExecuteInfo.hProcess,INFINITE);


if (test== WAIT_OBJECT_0 ) {

MessageBox(NULL,"Coucou signale","Boite coucou",MB_ICONEXCLAMATION|MB_OK|MB_TASKMODAL);


}else{}

Voila donc au debut quand j'ai ajouté WaitForSingleObject, je me suis aperçu que ExecuteInfo.hProcess n'était pas alimenté, je suis allé faire un tour dans l'aide, pour savoir comment était alimenté la structure SHELLEXECUTEINFO, et j'ai vu qu'il fallait spécifier le masque SEE_MASK_NOCLOSEPROCESS dans ExecuteInfo.fMask, pour avoir le handle du programme démarré par ShellExecuteEx ().

Ok en ayant fait tout ça j'ai aussi, paramétré INFINITE dans mon WaitForSingleObject() leprog s'execute tant que je n'irai pas cliquer sur un bouton "Fermer" de mon application leprog. Ce qui me pose probleme, car à aucun momment je peux aller appuyer sur mon boutton "Fermer" puisque mon application est bloquée par WaitForSingleObject()

J'ai donc testé cette fonction pour voir ce qu'elle me retournait, en allant sélectionner la fenêtre et presser "F4" sur le clavier pour fermer leprog et elle me retourne un WAIT_OBJECT_0, qui signifie donc si j'ai bien lu la doc, que l'état de l'objet spécifié est signalé. Là bien sur mon application se débloque.

Ensuite j'ai essayé TerminateProcess(ExecuteInfo.hProcess, 0) le tout en pas-à-pas juste pour voir si ça fermait leprog :

memset(&ExecuteInfo, 0, sizeof(ExecuteInfo));


ExecuteInfo.cbSize = sizeof(ExecuteInfo);
ExecuteInfo.fMask = SEE_MASK_NOCLOSEPROCESS;
ExecuteInfo.hwnd = 0;
ExecuteInfo.lpVerb = "open";
ExecuteInfo.lpFile = "leprog";
ExecuteInfo.lpParameters = mes_parametres; // parametres pour leprog
ExecuteInfo.lpDirectory = 0;
ExecuteInfo.nShow = SW_SHOW;
ExecuteInfo.hInstApp = 0;


if(ShellExecuteEx(&ExecuteInfo) == FALSE)
{
// erreur
}else{}


TerminateProcess(ExecuteInfo.hProcess, 0); //on tente de fermer leprog

Resultat : ok ça le ferme, mais malheureusement je ne sais toujours pas si ça le ferme proprement.

En faisant comme tu m'a conseillé BruNews ça bloque au niveau du WaitForSingleObject, comme j'ai mis INFINITE, et je débloque le tout en allant moi même appuyer sur "F4" sur le clavier, de ce fait étant donné que leprog se ferme, je ne sais pas si l'appel de la fonction TerminateProcess() juste apres à un vraiment un effet étant donné que le prog est déjà fermé. Mais j'ai testé et je te donne les résultats, pour te donner une idée de la chose.

Y'aurais t-il un moyen d'intercepter, le message, ou le signal envoyé, quand j'appui sur "F4" sur mon clavier, dans la fenêtre de commandes de leprog ? (Je rappel que leprog est un programme que je ne peux pa modifier)

Si ça se trouve ce n'est peut-être pas le bon message que je lui envoi quand je fait mon :

PostMessage(Le_handle_de_la_fenetre,WM_KEYDOWN,VK_F4,0);

Ou tout simplement est-ce ma façon de simuler le clavier qui ne va pas ?

J'ai fait un éssai en lançant une fenêtre de commande au lieu de leprog, et elle reçoit bien la touche que j'ai simulé, ou est la différence ? c'est au niveau processus que ça se passe ? je n'agis peut-être pas au bon niveau ?

En tout cas merci pour vos réponses, si vous pouvez me décoincer, je suis toujours ouvert à toute propositions.

et merci aux courageux qui ont eut la patience de lire en entier ce post !! promis je tenterai de faire moins long, mais j'aime bien rentrer dans les détails .

JAb
Messages postés
21042
Date d'inscription
jeudi 23 janvier 2003
Statut
Modérateur
Dernière intervention
21 août 2019
27
pour ne pas bloquer tu mets cela dans un thread, allait sans dire, non ?

ensuite dans ton thread, si tu veux pouvoir aussi l'arrêter proprement, tu boucles sur WaitForSingleObject() 1 fois par seconde par exemple tant que hprocess non signale. Un flag global pour indiquer si tu dois continuer à boucler ou non et le tour est joué.

ciao...
BruNews, MVP VC++