[C con Clase] Parámetros de WM_QUIT y PostQuitMessage() en WinAPI

Steven Davidson srd4121 en njit.edu
Mie Jul 16 10:22:59 CEST 2008


Hola David,

David Reza wrote:
> Hola, me estoy iniciando en el curos de WIN API 32 de Windows y a
> pesar de que usa tecnicismos que desconozco, o mejor dicho,
> desconocía, he ido aprendiendo mucho; pero tengo una duda respecto a
> lo siguiente:
>  

[CORTE]

> Yo no sé muy bien que es un mensaje concretamente, o cuál debe ser su
> estructura, pero por lo que leo y a mi entender, los mensajes
> también tienen parámetros, pero en el texto de la definición de
> WinMain dice:
> 
> Entonces me confunde lo de el parámetro del mensaje WM_QUIT y el 
> parámetro de la función PostQuitMessage, porque hablan del parámetro
> wParam y no lo veo declarado en ninguna de éstas dos definiciones,
> ni en el mensaje ni en la función. También leí:
> 

Veamos. Un mensaje viene a ser un número entero a modo de identificador 
que comunica alguna acción, que puede ser desde la pulsación del botón 
izquierdo del ratón hasta conseguir la fuente actualmente seleccionada. 
Cada mensaje tiene asociado dos variables, que prácticamente hacen la 
función de parámetros, llamadas 'wParam' y 'lParam'. Esto no significa 
que todos los mensajes usan estos parámetros universales. Algunos 
mensajes ignoran ambos parámetros, mientras que otros usan uno o el otro 
y otros mensajes usan ambos.

Ahora bien, también existe la estructura MSG que la usamos en 
'WinMain()' para obtener el siguiente mensaje. Dentro de esta estructura 
tenemos al identificador del mensaje al igual que sus parámetros. Puedes 
consultar este enlace para más información: 
http://winapi.conclase.net/curso/index.php?est=MSG

> 
> Entonces me gustaría que me aclararan de quién es el parámetro wParam
> y de quién es el parámetro nExitCode.
>  
> Yo creo que wParam es del mensaje WM_QUIT y el parámetro nExitcode es
> de la función PostQuitMessage().
>  

Estás confundiendo dos cosas diferentes. 'WM_QUIT' es un mensaje: un 
código numérico. 'PostQuitMessage()' es una función "normal y 
corriente". El prototipo de esta función es la siguiente:

VOID PostQuitMessage( int nExitCode );

Obviamente, 'nExitCode' es el parámetro de la función 'PostQuitMessage()'.

> Y aprovechando el correo, me gustaría preguntar cómo es la sintáxis
> de un parámetro de un mensaje. En la definición de WM_QUIT como ya 
> mencioné, dice:
>  
> 
>     WM_QUIT nExitCode = (int) wParam; // código de salida
> 
> suponiendo que lo de nExitCode está mal y debería ser wParam,
> entonces los parámetros se declaran así nada mas, después del
> identificador del mensaje? ¿No se utilizan paréntesis o algo
> parecido?
> 

Cuando procesamos los mensajes en 'WindowProcedure()', o como hayas 
nombrado tu función, siempre tendrás 4 parámetros:
1. HWND hwnd, manipulador de la ventana,
2. UINT msg, mensaje en forma de código numérico,
3. WPARAM wParam, un parámetro universal, y
4. LPARAM lParam, otro parámetro universal.

Aquí, tienes los dos parámetros asociados con cualquier mensaje.

La sintaxis que usamos en la sección de referencias del curso del API 
simplemente dice cómo usar cada parámetro según el mensaje. En el caso 
de 'WM_QUIT', sólo usamos el parámetro 'wParam' como si fuera un número 
de tipo 'int'. Por ejemplo, podríamos escribir lo siquiente:

LRESULT CALLBACK WindowProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM 
lParam )
{
   ...
   case WM_QUIT:
   {
     int nExitCode = (int) wParam;
     // Usar 'nExitCode'
     ...
     return 0;
   }
   ...
   return DefWindowProc( hwnd, msg, wParam, lParam );
}

Sin embargo, en el caso de 'WM_QUIT', lo anterior no sucedería, porque 
'WM_QUIT' es un mensaje un tanto especial: nunca llegaría a ser 
procesado por nuestra función 'WindowProc()'. Lo que sí podríamos hacer 
es conseguir el 'wParam' en la función 'WinMain()'. Por ejemplo,

int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR 
lpszCmdLine, int nCmdShow )
{
   ...
   while( TRUE == GetMessage(&mensaje, 0, 0, 0) )
   {
     TranslateMessage( &mensaje );
     DispatchMessage( &mensaje );
   }

   // Hemos salido del bucle porque 'mensaje.message == WM_QUIT'

   return (int)mensaje.wParam;
}

Esto es justamente lo que tenemos en el capítulo 3 del curso del API. 
Básicamente, obtenemos el código que enviamos a 'PostQuitMessage()' como 
el parámetro 'wParam' del mensaje 'WM_QUIT'.


Espero que todo esto aclare las dudas.

Steven





Más información sobre la lista de distribución Cconclase