2009-07-28 9 views
5

MSDN indica che la funzione RegisterWindowMessage() viene utilizzata solo per la registrazione dei messaggi da inviare tra i processi. Se un messaggio è necessario per l'invio all'interno di un processo, può essere selezionato in modo sicuro nell'intervallo da WM_APP a 0xBFFF.L'abusare di RegisterWindowMessage può portare all'esaurimento delle risorse?

Tuttavia nel nostro codebase spesso vedo che RegisterWindowMessage() viene utilizzato per i messaggi inviati solo all'interno di un processo. Suppongo che ciò sia avvenuto grazie alla semplicità percepita dell'uso di RegisterWindowMessage() poiché non richiede la distribuzione manuale degli identificatori di messaggio nell'intervallo WM_APP..0xBFFF.

Ho capito correttamente che se molte applicazioni sono eseguite su una macchina e chiamano tutte RegisterWindowMessage() con stringhe diverse, potrebbero esaurire la gamma di identificatori di messaggi consentiti per il reso da RegisterWindowMessage() e per alcuni di essi sarà solo restituire un valore che indica un errore? Quale potrebbe essere un motivo valido per l'utilizzo dei messaggi RegisterWindowMessage() nei casi in cui i messaggi dell'intervallo WM_APP..0xBFFF sarebbero sufficienti?

risposta

4

IMHO non v'è alcun motivo valido per utilizzare RegisterWindowMessage se si sta inviando messaggi solo a te stesso

Non c'è (documentato) modo per annullare la registrazione di un messaggio, così dopo la vostra applicazione si chiude, che il messaggio registrato rimarrà nella tabella atom fino al riavvio/disconnessione (non riesco a ricordare esattamente dove questa tabella atom è memorizzata, probabilmente l'istanza di sessione della stazione finestra o del server terminal)

5

Il motivo per cui è necessario utilizzare RegisterWindowMessage anche quando si invia un messaggio a se stessi è quello ti protegge dall'idiota che trasmette messaggi nell'intervallo WM_APP + N.

Sì, questo succede.

3

Un possibile vantaggio è che Spy ++ può visualizzare più testo informativo, pertanto il debug è un po 'più semplice. Confronta

<00058> 00330CA2 S message:0x0419 [User-defined:WM_USER+25] wParam:00000000 lParam:00000000 

con

<00129> 004F0DA0 S message:0xC2B0 [Registered:"AFX_WM_ONCHANGE_ACTIVE_TAB"] wParam:00000001 lParam:02B596E8 

Naturalmente, in linea di principio non v'è la possibilità di corto di ID dei messaggi. D'altra parte, nel codice sorgente del Feature Pack MFC ci sono 52 chiamate a RegisterWindowMessage. Quindi rimangono ancora 16300 ID per altre applicazioni.

5

Abusing RegisterWindowMessage può potenzialmente rendere inutilizzabile una finestra di Windows. Questo è particolarmente vero se i nomi dei messaggi delle finestre sono generati dinamicamente e un bug causa l'allocazione dei messaggi di windows fuori controllo. In questo caso la tabella globale degli atomi nella stazione di Windows/desktop si riempirà e qualsiasi processo che utilizza User32.dll (in pratica, qualsiasi app) non si avvierà, creerà Windows, ecc.

C'è un bug in Prodotti Delphi/Borland che registra i messaggi che iniziano con ControlOfsXXXXXX dove XXXX è un indirizzo di memoria (o un altro modificatore dinamico). Le app avviate e fermate frequentemente registreranno più atomi ControlOfsXXXX e alla fine esauriranno lo spazio atomico. Per maggiori dettagli si veda:

http://blogs.msdn.com/b/ntdebugging/archive/2012/01/31/identifying-global-atom-table-leaks.aspx

E

https://forums.embarcadero.com/thread.jspa?threadID=47678

+0

non sapeva di quel bug in C++ Builder/Delphi! Nasty ... –

+0

C++ Builder/Delphi (VCL) genera il nome del messaggio da 'HInstance' (' GetModuleHandle') e ID thread.Per quanto riguarda il normale eseguibile, 'HInstance' non varia e la gamma di ID thread è limitata, è improbabile che l'applicazione VCL esaurisca la tabella atom. Più plausibile è nel caso della DLL integrata in VCL. O quando il file eseguibile ha impostato ASLR (che è un requisito per la certificazione di Windows 8). –

Problemi correlati