2009-12-23 14 views
11

Quando uso la funzione SendMessage con HWND_BROADCAST, l'applicazione si blocca su. Non v'è alcuna risposta dalla domanda di lungo periodo di tempo.SendMessage (HWND_BROADCAST pende

Qualcuno può spiegare perché?

risposta

2

Questo perché SendMessage chiamato con HWND_BROADCAST innanzitutto enumera tutte le finestre disponibili e quindi chiama SendMessage per ciascuna di queste finestre.MessageMessage non verrà restituito finché la finestra non avrà elaborato il messaggio.Se una singola finestra impiegherà molto tempo per elaborare il messaggio, l'intera chiamata verrà ritardata

+1

Peggio ancora, se uno delle procedure di finestra chiamate * mai * non restituirà né SendMessage(), e l'applicazione si bloccherà in modo permanente. In generale, non è possibile sapere in che modo la finestra di un'altra applicazione risponderà a un messaggio arbitrario (anche se creato con RegisterMessage()). In poche parole, non si dovrebbe mai chiamare SendMessage() per inviare un messaggio a una finestra a meno che non si sappia esattamente quale sia la finestra e come risponderà. –

0

C'è un SendMessageTimeout che limiterà il tempo di blocco dell'applicazione durante l'attesa dell'accettazione da parte del ricevitore.

Un'altra soluzione consiste nell'avviare più thread e farli recapitare più messaggi contemporaneamente (ad esempio in parallelo). Quindi, se uno dei ricevitori è bloccato, non si uccide l'intera app.

0

C'è almeno un processo là fuori che ha un messaggio pompa ma non sta pompando messaggi. SendMessage non viene restituito finché tutti i destinatari non hanno elaborato il messaggio ... quindi non restituisce. Puoi provare a utilizzare SendMessageTimeout per ovviare a questo problema.

Per inciso, è per questo che avviare un processo e attendere l'handle del processo può essere irto di problemi. Lo descrivo sul mio sito web here.

15

Ciò si verifica quando è presente un processo con una finestra di livello superiore, ma non chiama GetMessage o PeekMessage sul thread che ha creato la finestra.

Per retrocompatibilità con Windows 3.0, SendMessage non verrà restituito finché tutte le finestre di livello superiore nel sistema non avranno risposto alla trasmissione. Questo comportamento aveva senso prima che Windows fosse multithread, perché SendMessage(), anche se l'invio ad altri processi non avrebbe mai bloccato.

Ma a partire da Win32, quando si InviaMessaggio a una finestra in un altro processo, ciò che effettivamente accade è il blocco del thread finché il thread nell'altro processo non si riattiva e gestisce il messaggio. Se quel thread è occupato, o semplicemente non sta pompando messaggi, allora aspetti per sempre.

Per questo motivo è necessario utilizzare sempre SendNotifyMessage o SendMessageTimeout quando si utilizza HWND_BROADCAST o altrimenti si inviano messaggi a finestre di proprietà di altri processi.

Problemi correlati