Newsgroup: it.comp.lang.c++
Titolo: chiudere delle applicazioni

ho la necessità di chiudere delle applicazioni da un programma realizzato in
Visual C++ 5.0.
da questo programma tramite la funzione WinExec() lancio, ad esempio,
l'applicazione calc.exe.
Come faccio a chiuderla dal mio programma?  qualcuno può aiutarmi?
Grazie comunque!

Innanzitutto dovresti usare CreateProcess anziché WinExec; questo perché
CreateProcess restituisce l'ID del thread principale del processo creato. I
parametri sono tanti, ma in questo caso vanno quasi tutti impostati a 0 o
NULL; per esempio:
 char szCmd[] = "c:\\windows\\calc.exe";
 STARTUPINFO si;
 PROCESS_INFORMATION pi;
 ZeroMemory(&si,sizeof(si));               // IMPORTANTE !!!
 si.cb = sizeof(STARTUPINFO);
 if(CreateProcess(NULL,szCmd,NULL,NULL,FALSE,0,NULL,NULL,&si,&pi))
 {
  CloseHandle(pi.hThread);
  CloseHandle(pi.hProcess);
 }
Ora che il nuovo processo è stato creato dobbiamo chiuderlo; qui entra in
gioco l'ID del thread. Devi usare la funzione EnumThreadWindows. Questa
funzione enumera tutte le finestre principali associate all'ID di thread
specificato e ne passa l'handle a una funzione callback; bisogna per prima
cosa scrivere la funzione callback:
 BOOL CALLBACK EnumThreadWndProc(HWND hWnd, LPARAM lParam)
 {
  char szNomeClasse[50];
 
  GetClassName(hWnd,szNomeClasse,50);
  if(0 == lstrcmp(globale_szNomeClasse,szNomeClasse))
  {
   SendMessage(hWnd,WM_CLOSE,0,0L);
   return FALSE;
  }
  return TRUE;
 }
Per prima cosa si rileva il nome di classe della finestra identificata da
hWnd; se questo è identico al nome di classe della finestra principale
dell'applicazione che hai lanciato si può inviare un messaggio di chiusura
e ritornare FALSE per interrompere l'enumerazione. Segue la chiamata ad
EnumThreadWindows:
 EnumThreaWindows(pi.dwThreadId,(WNDENUMPROC)EnumThreadWndProc,0);
 
Per conoscere a priori il nome di classe di un programma che vuoi lanciare
puoi usare il programma Microsoft Spy++ oppure scrivere un'applicazione
apposta per questo scopo.

Non farti attirare dalle funzioni TerminateProcess e TerminateThread.
Queste funzioni non permettono al processo in chiusura di notificare alle
DLL questo evento. Questo significa che la chiusura non sarà effettuata
correttamente.


Puoi evitare di ricorrere al nome della classe se utilizzi
GetWindowThreadProcessID e confronti il valore ritornato nella DWORD puntata
da LPARAM con il process ID che ti ha tornato CreateProcess.
Oltre al messaggio di WM_CLOSE esistono altri sistemi per chiudere
un'applicazione:
- WM_SYSCOMMAND e SC_CLOSE come WPARAM: provoca la chiusura del programma in
modo analogo a quello utilizzato dall'utente (Alt+F4) e dovrebbe provocare
anche la visualizzazione dei messaggi per salvare/abbandonare il lavoro non
salvato.
- WM_ENDSESSION: è utilizzato da Windows per segnalare che è in corso uno
shutdown del sistema.
L'estrema risorsa consiste nell'utilizzo di TerminateProcess che,
effettivamente, può causare qualche problema in termini di risorse non
rilasciate (soprattutto sotto win '95).
---
Valter Minute
min...@fortech.it
 (the reply address of this message is invalid)
---
Are you looking for a good freeware ScreenSaver? Try FOYD!
http://www.winsite.com/info/pc/win95/desktop/foyd1395.zip/
if you want, I can send you the (free) C++ source code.