El bucle de mensajes es una sección de código obligatoria en todos los programas que utilizan una interfaz gráfica de usuario en Microsoft Windows . Los programas de Windows que tienen una GUI están controlados por eventos . Windows mantiene una cola de mensajes individual para cada hilo que ha creado una ventana. Por lo general, solo el primer hilo crea ventanas. Windows coloca mensajesen esa cola siempre que ocurra actividad del mouse en la ventana de ese hilo, siempre que ocurra actividad del teclado mientras esa ventana tiene el foco, y en otros momentos. Un proceso también puede agregar mensajes a su propia cola. Para aceptar la entrada del usuario, y por otras razones, cada hilo con una ventana debe recuperar continuamente mensajes de su cola y actuar en consecuencia. Un programador hace que el proceso lo haga escribiendo un bucle que llama a GetMessage (que bloquea un mensaje y lo recupera), y luego llama a DispatchMessage (que envía el mensaje) y se repite indefinidamente. Este es el bucle de mensajes. Por lo general, hay un bucle de mensaje en el programa principal , que se ejecuta en el hilo principal , y un bucle de mensaje adicional en cada cuadro de diálogo modal creado . Los mensajes de cada ventana del proceso pasan por su cola de mensajes y son manejados por su bucle de mensajes. Un bucle de mensajes es un tipo de bucle de eventos .
Aparece un bucle de mensaje básico de la siguiente manera:
int WINAPI WinMain ( hInstance HINSTANCE , hPrevInstance HINSTANCE , LPSTR lpCmdLine , int nCmdShow ) { MSG msg ; BOOL bRet ; while ( 1 ) { bRet = GetMessage ( & msg , NULL , 0 , 0 ); if ( bRet > 0 ) // (bRet> 0 indica un mensaje que debe procesarse) { TranslateMessage ( & msg ); DispatchMessage ( & msg ); } else if ( bRet < 0 ) // (bRet == -1 indica un error.) { // Manejar o registrar el error; posiblemente salir. // ... } else // (bRet == 0 indica "salir del programa".) { break ; } } return msg . wParam ; }
Es convencional que el bucle de eventos invoque TranslateMessage
cada mensaje que puede traducir las pulsaciones de teclas virtuales en cadenas . La llamada TranslateMessage
no es técnicamente necesaria, pero pueden surgir problemas si no se llama. El bucle de mensajes debe llamar DispatchMessage
.
El bucle de mensajes no actúa directamente sobre los mensajes que maneja. Los envía llamando DispatchMessage
, lo que transfiere el mensaje al "procedimiento de ventana" de la ventana a la que se dirigió el mensaje. (El "procedimiento de ventana" es un procedimiento de devolución de llamada , que se asoció con la clase de ventana cuando se registró). (Más de una ventana puede usar el mismo procedimiento de ventana).
El código también puede enviar mensajes directamente a un procedimiento de ventana. Estos se denominan mensajes no en cola.
Un ciclo de mensajes estricto no es la única opción. El código en otras partes del programa también puede aceptar y enviar mensajes. PeekMessage
es una llamada sin bloqueo que regresa inmediatamente, con un mensaje si hay alguien esperando, o ningún mensaje si no hay nadie esperando. WaitMessage
permite que un hilo duerma hasta que haya un mensaje en la cola.
Los marcos de interfaz gráfica modernos , como Windows Forms , Windows Presentation Foundation , MFC , Delphi , Qt y otros, no requieren que las aplicaciones codifiquen un bucle de mensajes de Windows, ya que enrutan automáticamente eventos como pulsaciones de teclas y clics del mouse a sus controladores apropiados como definido en el marco. Sin embargo, cada marco implementa un bucle de mensajes en algún lugar y, por lo general, se puede acceder al bucle de mensajes o reemplazarlo cuando se requiere un control más directo.
Ver también
- Xlib para el bucle de eventos en el sistema X Window
enlaces externos
- Meandering Through the Maze of MFC Message and Command Routing (MSJ, julio de 1995)
- La odisea de una tecla: la ruta de un mensaje de pulsación de tecla a través de la VCL
- Platform SDK: mensajes y colas de mensajes
- Platform SDK: API de Windows: ingresar al bucle de mensajes
- Uso de mensajes y colas de mensajes (MSDN)
- Función GetMessage
- Función PeekMessage