2009-07-28 14 views
5

MSDN informa que la función RegisterWindowMessage() solo se usa para registrar mensajes que se enviarán entre los procesos. Si se necesita un mensaje para enviar dentro de un proceso, se puede seleccionar de forma segura desde el rango WM_APP hasta 0xBFFF.¿Puede abusar de RegisterWindowMessage llevar al agotamiento de recursos?

Sin embargo, en nuestra base de código, a menudo veo que RegisterWindowMessage() se usa solo para mensajes enviados dentro de un proceso. Supongo que esto se hizo debido a la simplicidad percibida de usar RegisterWindowMessage() ya que no requiere la distribución manual de los identificadores de mensaje en el rango WM_APP..0xBFFF.

Entiendo correctamente que si muchas aplicaciones se ejecutan en una máquina y todas llaman a RegisterWindowMessage() con diferentes cadenas, podrían agotar el rango de identificadores de mensajes a los que se les permite devolver mediante RegisterWindowMessage() y para algunos de ellos solo devolver un valor que indique una falla? ¿Cuál podría ser una razón válida para utilizar los mensajes RegisterWindowMessage() en los casos en que los mensajes de rango WM_APP..0xBFFF serían suficientes?

Respuesta

4

mi humilde opinión, no hay ninguna razón válida para utilizar RegisterWindowMessage si sólo se está enviando mensajes a sí mismo

No hay (documentado) manera de eliminar el registro de un mensaje, así que después de su aplicación se cierra, ese mensaje registrado se quedará en la tabla de átomos hasta reiniciar/cerrar sesión (no recuerdo exactamente dónde está almacenada esta tabla de átomos, la estación de ventana o la sesión de sesión del servidor de terminal)

5

La razón por la que necesita usar RegisterWindowMessage incluso cuando se envía un mensaje a usted es que te protege del idiota que transmite mensajes en el rango WM_APP + N.

Sí, esto sucede.

3

Una posible ventaja es que Spy ++ puede mostrar texto más informativo, por lo que la depuración es un poco más fácil. Comparar

<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 

Por supuesto, en principio, existe la posibilidad de quedarse sin identificadores de mensaje. Por otro lado, en el código fuente del paquete de características MFC hay 52 llamadas al RegisterWindowMessage. Entonces todavía quedan 16300 ID para otras aplicaciones.

5

Abusar RegisterWindowMessage puede hacer que una ventana sea inutilizable. Esto es especialmente cierto si los nombres de los mensajes de ventana se generan dinámicamente y un error causa la asignación de mensajes de Windows fuera de control. En este caso, la tabla global atom en su estación de Windows/escritorio se llenará y cualquier proceso que use User32.dll (básicamente, cualquier aplicación) no podrá iniciarse, crear ventanas, etc.

Hay un error en Productos Delphi/Borland que registra mensajes que comienzan con ControlOfsXXXXXX donde XXXX es una dirección de memoria (u otro modificador dinámico). Las aplicaciones que se inician y detienen con frecuencia registrarán múltiples átomos ControlOfsXXXX y eventualmente agotarán el espacio del átomo. Para más detalles ver:

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

Y

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

+0

no sabía nada de ese error en C++ Builder/Delphi! Nasty ... –

+0

C++ Builder/Delphi (VCL) genera el nombre del mensaje de 'HInstance' (' GetModuleHandle') y Thread ID.En cuanto al ejecutable normal, la 'HInstance' no varía y el rango de identificadores de subprocesos es limitado, es poco probable que la aplicación VCL agote la tabla de átomos. Más plausible es en el caso de una DLL integrada en VCL. O cuando el ejecutable tiene establecido ASLR (lo que es un requisito para la certificación de Windows 8). –

Cuestiones relacionadas