Newsgroup: it.comp.programmare.win32
Titolo: Ottenere l'handle della finestra principale...

... a partire dall'id del processo...
Vorrei riuscire a scrivere un programma che tenta la chiusura di un
processo, il cui nome gli viene passato come parametro sulla linea di 
comando.
Le applicazioni che saranno soggette a questo trattamento possiedono
tutte almeno una finestra.
Vorrei che la chiusura del processo fosse la piu' pulita possibile,
quindi tentare prima una SendMessageTimeout di WM_CLOSE verso la
finestra principale, poi in caso di esaurimento per timeout, un
TerminateProcess brutale.
Dato il nome del processo, la strategia che vorrei seguire e' quella
di fare una scansione dei processi attivi (sotto NT, e fin qui ci
riesco) e agire di conseguenza, dopo averlo riconosciuto tra essi.
Domande :
1. Esiste un modo per ottenere l'handle della finestra principale di
un'applicazione, a partire dall'id del processo ?
Quello che riesco ad ottenere sinora e' una lista di handle delle
finestre legate ad un'applicazione, ma non ho modo di verificare quale
di essa sia la "main window".
Ho fatto questo, utilizzando EnumWindows, che, a quanto pare, dovrebbe
scandire tutte le top-level windows, figlie quindi della Desktop,
pero' ottengo comunque piu' finestre per ogni processo e non sono del
tutto sicuro che una "top-level window" sia una "main window".
Adoperando, invece, EnumProcesses, ottengo una lista dei processi
attivi (nome + PID). Mi piacerebbe sapere in che modo si ottiene
l'handle della finestra principale a partire dal PID.
2. Che succede quando si spedisce un messaggio WM_CLOSE alla finestra
principale di un'applicazione, mentre e' attiva una finestra modale di
essa ?
3. E', comunque, possibile ottenere l'handle della finestra principale
di un'applicazione, a partire dall'handle di qualsiasi finestra di
tale applicazione (ripercorrendo all'indietro l'albero dei Parent o
degli Owner) ?
--
Andrea Laforgia (
andrea_...@bigfoot.com
)
---------------------------------------------
#exclude <windows.h>

degli Owner) ?
La funzione che ti interessa dovrebbe essere GetWindow() con tutti i suoi
Flag...
Ciao!
--
- Carlo -

la principale termina anche la modale (anche se quest'ultima è attiva).
No. Se la finestra modale e' aperta ma non attiva, la finestra
principale non risponde alla spedizione di messaggi da parte del task
manager e quindi se ne puo' forzare la chiusura (kill), altrimenti, se
e' attiva, il task manager aspetta che essa venga chiusa, il che vuol
dire che il processamento dei messaggi della finestra principale si
blocca sino a che non e' chiusa la finestra modale.


Non e' che ne sia tanto convinto ! :( 
BOOL CALLBACK EsaminaFinestra( HWND hFinestra, LPARAM lParam )
{
     HANDLE  hProcesso ;
     HMODULE hModulo ;
     DWORD   idProcesso ;
     DWORD   cb ;
     char    FileName[300],
             Riga[300],
             Title[300] ;
     LONG    WindowStyle ;
     WindowStyle = GetWindowLong( hFinestra, GWL_EXSTYLE ) ;
    if ( IsWindowVisible( hFinestra ) &&
         GetParent( hFinestra ) == 0 &&
         GetWindow( hFinestra, GW_OWNER ) == 0 &&
         (WindowStyle & WS_EX_TOOLWINDOW) == 0 )
    {
       GetWindowText( hFinestra, Title, sizeof Title ) ;
       GetWindowThreadProcessId( hFinestra, &idProcesso ) ;
       hProcesso = OpenProcess( PROCESS_QUERY_INFORMATION |
                                PROCESS_VM_READ,
                                FALSE,
                                idProcesso ) ;
        EnumProcessModules( hProcesso,
                            &hModulo,
                            sizeof hModulo, &cb ) ;
        GetModuleFileNameEx( hProcesso,
                             hModulo,
                             FileName, sizeof FileName ) ;
        sprintf( Riga, 
                 "%-40s HWND:%08X HPRC:%08X PID:%08X TID:%08x",
                 Title, hFinestra, hProcesso, idProcesso, idThread ) ;
        CloseHandle( hProcesso ) ;
        Form1->ListBox1->Items->Add( Riga ) ;
    }
    return TRUE ;
}
void __fastcall TForm1::btnElencoProcessiClick(TObject *Sender)
{
     LPARAM lParam ;
     Form1->ListBox1->Items->Clear() ;
     EnumWindows( EsaminaFinestra, lParam ) ;
