Processus et tache de fond [C++Builder] - C++ - Programmation
Marsh Posté le 10-04-2002 à 15:52:03
Faudrait que l'appli "fille" envoye un message convenu à l'application "mère" avant qu'elle ne se ferme. Les WM_USER (+0 à + 255 ?) sont faits pour ça.
Si ca peut servir, un bout de code (C, 16 bits, bon aussi en 32) que j'avais écrit pr savoir si la même appli tourne déja et lui donner l'ordre de se fermer.
void MetFinAIdem(void)
{
HWND hWnd;
long TL;
hWnd = GetTopWindow(NULL);
while (hWnd != NULL)
{
if (IsWindowVisible(hWnd) != 0 && IsWindowEnabled(hWnd) != 0)
{
/* On n'a ici que les noms de feuilles ppales "visibles"
Si on fait pas de test, on trouve aussi ce qui est en "arrière-plan" */
TL = GetWindowLong(hWnd, GWL_STYLE);
if ((TL & WS_POPUP) != WS_POPUP)
{ /* != WS_POPUP donne nom de titres de fenêtres
== WS_POPUP donne le nom des applications */
char WName[257];
WName[0] = '\0';
GetWindowText(hWnd, WName, sizeof(WName));
if (hWnd != hWndMain && (strstr(WName, szTitle) != NULL ||
strstr(WName, szAppName) != NULL))
{ // Envoie message à l'autre application
SendMessage(hWnd, WM_USER + 8, (WPARAM)0, (LPARAM)0);
}
}
}
hWnd = GetWindow(hWnd, GW_HWNDNEXT);
}
}
// fin de module MetFinAIdem
hWndMain est le hWnd de l'appli courante (peu utile ici car on charche pas un doublon mais un "étranger" )
szTitle est le titre de la barre de texte de la feuille principale de mon programme.
szAppName est le nom de baptême du programme.
Si l'on connait le nom du prog à maximiser (ou rendre "normal" ), suffit de prendre les bonnes chaînes. Le but est d'explorer les noms des progs qui tournent et savoir lequel est visé puis de lui envoyer un message "privé" convenu (ici WM_USER + 8 car les autres me servent déja).
C'est peut être pas clean, mais suis pas du métier.
Dans la boucle de test de message du prog "à maximiser quand fini", faut mettre
case WM_USER + 8:
// maximisation, ou remise comme avant
break;
J'espère que c'est pas trop obscur (??).
Marsh Posté le 11-04-2002 à 08:51:51
L'application qui doit se terminer cherche quel est le hWnd de l'application qui doit se maximiser/restaurer afin de lui envoyer un message (il faut le hWnd de l'appli destination pour envoyer des messages !) convenu entre elles (par le développeur).
L'application en "sommeil", quand elle reçoit ce message (avec éventuellement des paramètres passés par LPARAM et WPARAM) agit selon ce qu'on y demande.
Y a sans doute mieux. Aux connaisseurs de le dire.
Mon code (à ADAPTER !!) cherche dans toutes les applis lancées laquelle a le nom (ou titre de feuille) cherché. Pour suivre l'effet des paramètres de GetWindowLong(), on peut mettre WName dans MessageBox() pour se rendre compte de ce qu'on récupère...
Marsh Posté le 11-04-2002 à 10:12:03
confirme si g bien compris: ici hWndMain c l'appli courante ki tourne en "avant-plan". Donc pour la définir, il fo faire appel à la fonction GetTopWindow en début de routine.
C bien ça...?
Marsh Posté le 11-04-2002 à 11:05:08
En C++, je sais pas (pas encore j'ai du mal à m'y plonger, trop vieux ), mais en C, c'est quand on crée la "feuille" principale du programme qu'on a ce hWnd (?CreateWindow()).
Ici, le seul truc qui compte c'est le hWnd du programme "à réveiller". Je voulais détecter (au lancement) si mon application tournait déja, le hWndMain servait à savoir si, dans la liste des trucs qui tournent, on ne se trouvait pas soi-même (!!)
Le test devrait pouvoir être
if (strstr(WName, szTitle) != NULL ||
strstr(WName, szAppName) != NULL))
voire juste
if (strstr(WName, "LeNomDeLAppliAReveiller" ) != NULL))
Marsh Posté le 11-04-2002 à 11:22:56
ouaip, ca c ok... Maintenant je dois recevoir le message WM_USER+8 de l'autre coté. Tu c comment ça marche (toujours en c win32)...?
Marsh Posté le 11-04-2002 à 13:15:54
Quand c'est une application qu'on a écrite, on peut la modifier. Si c'est un soft "étranger", faudrait voir quel message lui envoyer (on peut déja le remettre en avant plan).
Dans mon prog C (16/32 bits), j'ai une boucle de traitement de message Windows comme ça (en C++, ca ressemble ?)
LRESULT FAR PASCAL XX_Proc(HWND hWnd,
UINT message,
WPARAM wParam,
LPARAM lParam)
switch (message)
{
case WM_CREATE:
break;
case WM_PAINT:
return 0L;
case (WM_USER + 6):
//
break;
case (WM_USER + 7): // met à jour positions et dessins des boutons
//
break;
case (WM_USER + 8): // envoyé si y a doublon
//
break;
case WM_KEYDOWN: // frappe sur une touche
break;
case WM_KEYUP: // relevé de touche (CTRL relaché pr Affich Diff)
break;
case WM_SIZE:
switch (wParam)
{
case SIZE_RESTORED:
break;
case SIZE_MAXIMIZED:
break;
case SIZE_MINIMIZED: // la feuille a été minimisée (icône)
}
break;
case WM_QUIT:
case WM_DESTROY:
PrepareQuit();
PostQuitMessage(0);
return 0L;
case WM_COMMAND:
break;
default:
return (DefWindowProc(hWnd, message, wParam, lParam));
}
return 0L;
}
// fin de module XX_Proc
Marsh Posté le 10-04-2002 à 13:59:00
J'utilise un programme C++Builder(p1) ki lui-même lance une application (un exécutable)(p2) et se minimise (il entre en tache de fond). Donc p1 peut agir sur p2 mais pas le contraire...
J'aimerais pourtant qu'à la sortie de p2, p1 se maximise, cad lorsk p2 recoit l'ordre de sortir, il cherche p1 qui tourne en processus de fond avec zindoz, l'identifie (avec son nom par ex) et le maximise...
Comment ça marche...?
MERCI D'AVANCE