2010-12-03 9 views
8

Recientemente traté de poner el bucle de mensajes de una ventana en su propio hilo, y me pregunté por qué nunca recibió ningún mensaje, pero aprendí que Windows publica mensajes en el hilo que creó la ventana. ¿Cómo se crea una ventana en un hilo y se causa otro hilo para recibir los mensajes de esa ventana? He visto la función PostThreadMessage, pero creo que también requiere que el hilo que creó la ventana escuche los mensajes, que es exactamente lo que trato de evitar, por lo que esa función no es lo que necesito.Cambiando el hilo del bucle de mensaje de una ventana

Parece que sería una pregunta común y he pasado bastante tiempo buscando en Google una respuesta, pero no encuentro ninguna.

Respuesta

11

¿Cómo se crea una ventana en una hilo y causa otro hilo a recibir mensajes de esa ventana?

Respuesta simple ... no es así. Cree la ventana en la cadena en la que desea procesar sus mensajes. Si esto no es posible, entonces necesita volver a pensar su enfoque.

+1

¿Hay una respuesta compleja o la respuesta simple es la única? – Epro

+1

@Epro: Esa es la única respuesta que me temo. – Goz

+0

¿Este enfoque sugirió el que utilizan los programas que tienen muchas ventanas abiertas a la vez? – Epro

2

Puedes ver si AttachThreadInput te funciona, te permite manejar mensajes de otras conversaciones.

Esto realmente no es una pregunta tan común, porque casi siempre manejas un mensaje de Windows en la secuencia donde fue creado. Ver la respuesta de Goz; Estoy de acuerdo.

Tenga en cuenta que no obtendrá nada al colocar el procesamiento de mensajes en otro hilo. No divida las tareas de la GUI en varios hilos, divida las tareas de procesamiento/fondo en hilos.

+0

Eso no es lo que hace ATI. Simplemente permite que dos hilos compartan el estado de entrada. Como el foco y el estado del teclado. –

+0

El uso de dos subprocesos separados para el procesamiento de mensajes podría permitir un mayor paralelismo en un U.I. Por ejemplo, dos ventanas diferentes podrían publicar mensajes en las colas de mensajes de subprocesos de las otras y ambas podrían continuar el proceso normalmente, mientras que con una sola secuencia, la publicación y el procesamiento de los mensajes se serializarían. El procesamiento de mensajes en dos hilos separados ocurriría en paralelo, mientras que con un solo hilo, los mensajes tendrían que procesarse en serie. – Triynko

7

La bomba de mensajes de Windows es realmente solo un while bucle que recoge mensajes de una cola usando PeekMessage() y llama a su función de Windows WndProc. Hay algo más que eso, pero esa es la operación básica.

Como tal, cualquier hilo que ejecute el bucle while es el único hilo en el que sus ventanas pueden "ejecutar". Así es como se construye cada aplicación de Windows que he visto.

Sin embargo, en el pasado he pensado que, dado un gran esfuerzo, debería ser posible construir una aplicación de Windows con ventanas en múltiples hilos. No tengo ningún código para mostrarle porque ha pasado mucho tiempo desde que pensé acerca de esto, pero había dos enfoques: yo consideraba

  1. mantenerse un suministro de mensajes en el hilo principal. Pero modifique el código de la bomba de mensajes para que en el while envíe mensajes a los hilos del trabajador utilizando QueueUserAPC en función del hilo en el que se está ejecutando el HWND. Se requerirá un mapa de búsqueda para esto, que puede ser computacionalmente costoso.

  2. Crear un mensaje nuevo bomba en un hilo de trabajador. Tendría que escribir todo el código while, pero esto es bastante simple, y Petzold's classic book le dará todas las herramientas que necesita para hacer esto.

Tenga en cuenta que este enfoque no tiene sentido desde el punto de vista arquitectónico para cualquier aplicación que se me ocurra. Simplemente no necesita ventanas para ejecutar en múltiples hilos si construye su aplicación razonablemente. El manejo de ventanas ocurre en un hilo, las operaciones ocurren en otro (o muchos).Sin embargo, he pensado que esta era un área de investigación interesante, y eso es lo que me llevó por este camino. Para resumir, estoy casi seguro de que no necesitas hacer esto y no deberías hacer esto, pero esta podría ser la forma en que lo harías.

+0

Tienes razón, no tiene sentido. –

5

No es posible. Cada ventana pertenece a la secuencia que lo creó, y esa propiedad no se puede transferir.

No se trata de colocar la bomba de mensajes en otro hilo. Cada hilo tiene su propia cola de mensajes. Cuando envía o publica un mensaje en una ventana, el sistema operativo verifica qué hilo posee esa ventana y dirige el mensaje a la cola de mensajes de esa secuencia. Los subprocesos no pueden leer ninguna cola de mensajes, sino la suya, por lo que no puede hacer que un subproceso procese los mensajes de las ventanas de otro subproceso.

Podría volver a enviar mensajes a otro hilo, como en the first idea in John's answer, pero como manejador de mensajes de uso general, se volverá más complicado de lo que vale. Muchos mensajes están destinados a modificar el estado de la ventana, pero no se puede modificar el estado, excepto desde el propio hilo de la ventana. Algunos mensajes se envían con la intención de obtener un valor de retorno significativo, pero no puede saber qué devolver hasta que se haya procesado el mensaje, por lo que tendría que bloquear, esperando que el hilo del trabajador procese el mensaje.

Será mejor que identifique el pequeño conjunto de mensajes que realmente se pueden descargar en un hilo de trabajo y los maneje especialmente. Una vez que lo hagas, no tendrás una ventana cuyos mensajes se manejen en un hilo diferente; solo tendrá un hilo de trabajo común, y será mucho menos confuso razonar sobre ello.

Si hay mensajes enviados a su ventana que requieren mucho tiempo de proceso, pero el remitente no necesita saber el resultado o conoce el resultado antes de terminar el procesamiento, entonces puede dar una respuesta temprana llamando al ReplyMessage. Eso permite que el hilo de envío continúe ejecutándose mientras que el hilo de la ventana hace un trabajo adicional.

+0

Esto debe marcarse como la respuesta. – Triynko

-2

ver esto:

MSDN: http://msdn.microsoft.com/en-us/library/ms644946(v=vs.85).aspx

El hilo que se contabiliza debe haber creado una cola de mensajes, o bien la llamada a PostThreadMessage falla el mensaje. Use el siguiente método para manejar esta situación.

1.Cree un objeto de evento, luego cree el hilo.

2.Utilice la función WaitForSingleObject para esperar a que el evento se establezca en el estado señalizado antes de llamar a PostThreadMessage.

3.En el hilo en el que se publicará el mensaje, llame a PeekMessage como se muestra aquí para forzar al sistema a crear la cola de mensajes.

PeekMessage(&msg, NULL, WM_USER, WM_USER, PM_NOREMOVE) 

4. Establezca el evento para indicar que el hilo está listo para recibir los mensajes publicados.

+0

Esto no recupera los mensajes de la ventana original. –

+0

Bienvenido a StackOverflow. Gracias por la respuesta, pero realmente no responde la pregunta original sobre cómo mover todo el procesamiento a otro hilo. Como tal, recomiendo eliminar esta respuesta. – Deanna

Cuestiones relacionadas