Stratos: Punto de Encuentro de Desarrolladores

¡Bienvenido a Stratos!

Acceder

Foros





Funcionamiento de los Mensajes Fuera de la Cola de Mensajes

Iniciado por Vanch, 04 de Octubre de 2002, 03:46:08 PM

« anterior - próximo »

Vanch

                                ¿Alguien puede explicarme el funcionamiento exacto de los mensajes que no van a la cola de mensajes? Si van directos, al porocedimiento ventana, ¿ pueden procesarse dos eventos de ventana a la vez ?, y si no, en algun formato esperaran, pila, lista, cola..., por lo que tenemos otra cola ( o lo que sea ) de mensajes en el procedimiento ventana. ¿Alguien me puede aclarar esta duda?, en la MSDN no encontre nada sobre el funcionamiento interno de los mensajes fuera de la cola de mensajes. :o

Otra cosa, alguien sabe la razón de pq a la gran mayoria de estructuras en programacion api Win32, es necesario rellemar un campo del estilo cbSize con el tamaño de la estructura. ¿Pq no hace el mismo el sizeof? :?:

Gracias a todos.  :D                                
anch!!! Vanch!!!, don't let me alone.

Astharoth

                                Hola.

>¿Alguien puede explicarme el funcionamiento exacto de los mensajes que no van a la cola de mensajes?

Bueno, voy a ver si me puedo explicar bien por aqui:

[Rollo mode on]

Cuando una aplicacion envia un mensaje (postmessage) o un mensaje es generado por un thread del propio sistema, este se introduce en la cola de mensajes destinada a la aplicacion (esto siempre sucede).

La aplicacion para gestionar los mensajes en un thread debe de tener una rutina de tipo "GetMessage" o "PeekMessage" para cachear estos mensajes.

Analizando:

Una determinada aplicacion o un thread de sistema(este puede ser de GDI) envia un mensaje a una aplicacion (postmessage).
Este mensaje es almacenado en la cola de mensajes para la aplicacion y retorna al programa que lo llamo. A partir de aqui la aplicacion o el thread de sistema continua su ejecucion.

Una determinada aplicacion en uno de sus threads tiene una rutina de cacheo de mensajes (GetMessage o PeekMessage). Esta obtiene un mensaje de su cola pero NO se llama a la WindowProc.
Cuando esa rutina de mensajes llama a la funcion de Dispatch, entonces se llama a la WindowProc en contexto de ese thread.
Una vez WindowProc termina, el thread continua su ejecucion normalmente en la rutina de cacheo de mensajes.

De esto se deduce:

1- Los mensajes siempre pasan por la cola.
2- Desde un solo bucle de mensajes podemos obtener los mensajes destinados a todas las ventanas de una aplicacion.
3- Se pueden ejecutar tantas llamadas a la "WindowProc" como threads tengamos escuchando mensajes y dispacheandolos (aunque esto no es recomendable).


Por ejemplo, en vez de llamar a DispatchMsg podriamos llamar directamente a nuestra rutina "WindowProc" con el mismo efecto (realmente DispatchMsg llama a la rutina de WindowProc configurada al crear la ventana con el mensaje pasado y punto).

Para enviar un mensaje directamente *sin* pasar por la cola, deberias conocer el offset en memoria de la rutina "windowproc" , redactar una estructura MSG y llamar a ese WindowProc pasandole directamente el mensaje. Esto se atenderia en el contexto del thread desde el que realizas la llamada y en principio no tendria porque interferir con el uso normal de la ventana y los mensajes recibidos desde otro thread por la rutina de cacheo de mensajes. (esto es solo valido para enviar mensajes directos siempre y cuando sean threads de un mismo proceso, aunque no se que utilidad le puedes ver a esto cuando puedes hacer un PostMessage con el mismo efecto).


>Otra cosa, alguien sabe la razón de pq a la gran mayoria de estructuras

Esto basicamente es por compatibilidad.

Hay muchas funciones que aceptan mas parametros en un operativo que en otro. Rellenando la estructura cbSize, la DLL de sistema puede saber a que "tipo" de llamada se enfrenta y obrar en consecuencia.

[Rollo mode off]

Espero que la chapa te sirva de ayuda.
Te aconsejo que te hagas un pequeño esqueleto con una ventana y hagas unas *cuantas* pruebas con los mensajes ;)


Saludos, Astharoth                                

Vanch

                               
Cita de: "Astharoth">1- Los mensajes siempre pasan por la cola.

Bueno, lo primero es darte las gracias, pues de dos post que pongo eres el primero que me respondes  :ojo:

Yo tambien pensaba que todos los mensajes pasaban por la cola de mensajes, pero no estas en lo correcto, y es hay donde radica mi duda, mirate la documentacion de la api SendMessage, es un ejemplo de que no todos los mensajes pasan por la cola de mensajes. Y un poco mas allá...

"Nonqueued Messages

Nonqueued messages are sent immediately to the destination window procedure, bypassing the system message queue and thread message queue. The system typically sends nonqueued messages to notify a window of events that affect it. For example, when the user activates a new application window, the system sends the window a series of messages, including WM_ACTIVATE, WM_SETFOCUS, and WM_SETCURSOR... "

Extraido literalmente de la MSDN, el sistema operativo tb envia mensajes que no pasan por la cola de mensajes, mi duda es acerca de como los trata todos estos mensajes... ...sobretodo cuando uno se esta procesando aun y otro llega.


Gracias.                                
anch!!! Vanch!!!, don't let me alone.

fiero

                               
Citar
Para enviar un mensaje directamente *sin* pasar por la cola, deberias conocer el offset en memoria de la rutina "windowproc" , redactar una estructura MSG y llamar a ese WindowProc pasandole directamente el mensaje. Esto se atenderia en el contexto del thread desde el que realizas la llamada y en principio no tendria porque interferir con el uso normal de la ventana y los mensajes recibidos desde otro thread por la rutina de cacheo de mensajes. (esto es solo valido para enviar mensajes directos siempre y cuando sean threads de un mismo proceso, aunque no se que utilidad le puedes ver a esto cuando puedes hacer un PostMessage con el mismo efecto).

Esto que dice Astharoth es lo que pienso yo que hace la función SendMessage.

En cuanto a los efectos que tiene utilizar esta función, para enviar los mensajes y que se ejecuten de forma inmediata, según mi experiencia, es como llamar a una función cualquiera (o sea de esas de toda la vida que acaban con un return). Si estás en el mismo hilo en el que se procesará el mensaje, se llamará a la función que lo manipula y luego se retornará y seguirá con el programa. Si envias un SendMessage a otro hilo, simplemente el otro hilo pasa a ser el hilo activo mientras dura la función manipuladora y luego se retorna al hilo actual cuando acaba la función. La ejecución del otro hilo, cuando el sistema le vuelva a dar el control, sigue en el mismo sitio donde el sistema lo dejó, sin ningun tipo de consecuencia...

un saludo                                
www.videopanoramas.com Videopanoramas 3D player

Astharoth

                                No habia leido las respuestas a esto.. xD

A ver que no te habia captado a la primera.. yo pensaba que querias enviar mensajes directamente sin pasar por el subsistema de mensajes de windows.

Ya he visto lo que comentabas pero el tratamiento es exactamente el mismo... es decir, la ruta que lleva el mensaje es la misma, el windowproc es llamado como consecuencia de un dispatchmsg en el bucle de obtencion de mensajes,etc...

Lo que sucede es que la "definicion" de la MSDN es un tanto ambigua (como para muchas otras cosas). Cuando dice que no pasa por la cola no se refiere a que directamente desde un thread "N" se llame al windowproc automaticamente. Se refiere a que el mensaje se manda inmediatamente con preferencia sobre los que ya estuvieran.

Vamos, el mecanismo de llamada y atencion del mensaje es el mismo, el contexto en el cual se ejecuta el windowproc es el mismo con la salvedad de que estos mensajes *se colocan en la primera posicion de la cola* , esto es, se atenderan en el inmediato Get/PeekMessage / DispatchMsg.

Por curiosidad lo he probado y es cierto, lo que no he hecho y hare cuando tenga un rato sera dar una vuelta con el softice para ver si *realmente* los guarda en la cola pero en el primer lugar o bien dispone de otro area alternativa para estos "mensajes directos". Solo por curiosidad :)


Saludos,Astharoth.                                






Stratos es un servicio gratuito, cuyos costes se cubren en parte con la publicidad.
Por favor, desactiva el bloqueador de anuncios en esta web para ayudar a que siga adelante.
Muchísimas gracias.