2012-05-24 10 views
9

Sto avendo l'applicazione Tray.Rileva se la chiusura di Windows o l'applicazione tenta di chiudere dal menu di sistema (WM_CLOSE)

Onj FormCloseQuery posso controllare se il programma deve goto vassoio e, invece di chiuderlo ho messo in vassoio (CanClose: = False)

Ma se Windows tenta di chiudere la mia domanda a causa della chiusura di Windows voglio di non muoversi la mia app nel vassoio ma per chiuderla.

Win7 termina la mia app, ma XP non si chiude perché la mia app rimane nel vassoio.

Come posso rilevare se Windows è una modalità di "spegnimento" o no?

Grazie!

+4

Sei provato intrappolando il messaggio [ 'WM_QUERYENDSESSION'] (http://msdn.microsoft.com/en-us/library/aa376890%28VS.85%29.aspx)? – RRUZ

+0

Ho spostato il mio commento a una risposta. –

risposta

7

I tuoi problemi derivano dall'uso di OnCloseQuery che è l'evento sbagliato da utilizzare. La risposta di Remy spiega come risolvere il problema dell'arresto di Windows bloccato dalla gestione predefinita dei messaggi della sessione finale VCL. E questo a sua volta è causato dall'impostazione di CanClose a False nell'evento OnCloseQuery.

Questa soluzione risolve il problema ma c'è un modo molto più semplice per gestire questo problema. Invece di interrompere la chiusura del modulo, lasciarlo andare avanti e chiudere. Rimuovi del tutto l'evento OnCloseQuery. Sostituirlo con un evento OnClose.

procedure TMainForm.FormClose(Sender: TObject; var Action: TCloseAction); 
begin 
    Action := caNone; 
    Visible := False; 
end; 

Questo bit piuttosto banale di codice è sufficiente a rendere la vostra applicazione minimizzare al vassoio quando la forma principale è chiusa.

+0

Ciò accade perché il codice non sta utilizzando l'evento 'OnCloseQuery'.Sta usando invece l'evento 'OnClose', che non è legato al messaggio' WM_QUERYENDSESSION' come 'OnCloseQuery' è. –

+0

@Remy Sì, sono un po 'lento nell'assorbimento, no ?! Sembrerebbe che OnClose sia la soluzione giusta qui. Inutile coinvolgerlo nei messaggi di fine sessione. –

+0

Ho bisogno sia di WM_QUERYENDSESSION che di WM_ENDSESSION: utilizzo già OnCanCloseQuery per posizionare il programma nel vassoio quando viene attivato WM_CLOSE. –

13

Se l'evento OnCloseQuery viene attivato in risposta ad un messaggio WM_QUERYENDSESSION, impostando CanClose=False farà sì che il messaggio per tornare FALSE.

Su XP e precedenti, questo annullerà l'arresto di Windows. Fino a quel momento, qualsiasi app che aveva ricevuto un messaggio WM_QUERYENDSESSION riceverà un messaggio WM_ENDSESSION con il suo valore wParam impostato su FALSE che dice a quelle applicazioni NON di terminarsi. Questo è il motivo per cui la tua app va nel vassoio e non esce durante l'arresto di Windows.

Microsoft ha modificato questo comportamento in Windows Vista in modo che le app non possano più annullare l'arresto di Windows tramite WM_QUERYENDSESSION. Questo è il motivo per cui Windows Vista e versioni successive interromperanno la tua app. È stata introdotta un'intera nuova API se un'applicazione deve interrompere l'arresto di Windows di proposito.

Questo è documentato su MSDN:

Application Shutdown Changes in Windows Vista

Per fare che cosa state chiedendo, è necessario intercettare direttamente il messaggio WM_QUERYENDSESSION modo da poter determinare se OnCloseQuery è chiamata a causa di arresto di Windows oppure no. Per esempio:

type 
    TForm1 = class(TForm) 
    private 
    procedure WMQueryEndSession(var Message: TWMQueryEndSession); message WM_QUERYENDSESSION; 
    procedure WMEndSession(var Message: TWMEndSession); message WM_ENDSESSION; 
    end; 

var 
    ShuttingDown: Boolean = False; 

procedure TForm1.WMQueryEndSession(var Message: TWMQueryEndSession); 
begin 
    ShuttingDown := True; 
    inherited; 
end; 

procedure TForm1.WMEndSession(var Message: TWMEndSession); 
begin 
    ShuttingDown := Message.EndSession; 
    inherited; 
end; 

procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: Boolean); 
begin 
    CanClose := ShuttingDown; 
    if not ShuttingDown then 
    begin 
    // your Tray logic here ... 
    end; 
end; 
+0

Grazie per l'aiuto Remy. Apprezzo la tua risposta rapida. –

+0

Le soluzioni di David, your e Remy sono identiche. Tutto ciò di cui avevo bisogno sono questi messaggi - e quando il sistema li invia. Entrambi mi aiutate e vi ho dato PIÙ, ma Remy l'ha fatto sotto forma di risposta, quindi ho accettato come aiuto. Ma entrambe le soluzioni sono le stesse. L'idea (logica) è quasi identica. –

+0

No, la mia risposta è molto diversa. Forse non hai aggiornato la pagina. Stai parlando del mio commento. Credo che il codice di Remy in questa risposta sia molto più complicato del necessario. –

Problemi correlati