2009-12-26 15 views
6

Deseo iniciar un hilo separado para manejar mensajes de ventana (a través de un bucle de bloqueo de GetMessage), pero aún crear las ventanas en el hilo inicial, después.¿Cómo puedo manejar los mensajes de ventana de un hilo separado?

Dentro del hilo separado, tan pronto como se pone en marcha, yo estoy llamando PeekMessage con PM_NOREMOVE para asegurar una cola de mensajes existe (es necesario?), Seguido por ..

AttachThreadInput(initial thread id,GetCurrentThreadId(),true) 

..before finalmente entrar el bucle de mensaje

Todavía no estoy usando un mutex o cs para asegurar que esto esté sucediendo a tiempo, pero estoy simplemente usando una declaración Sleep en mi hilo inicial por simplicidad.

Independientemente, los mensajes de ventana no parecen ser interceptados por el hilo separado.

No estoy seguro de si estoy haciendo esto correctamente y agradecería cualquier orientación posible. Ambos hilos están en el mismo proceso

Gracias a todos

+1

Esto es casi siempre una idea terrible. Para empezar, es probable que desee manejar mensajes * que en realidad no se publican * en la cola de entrada del subproceso de interfaz de usuario ... De lo contrario, al menos querrá * enviar * mensajes a Windows propiedad del subproceso de interfaz de usuario, y eso tampoco funcionará En realidad, debería procesar mensajes en el hilo de la interfaz de usuario y usar el hilo separado para las operaciones que consumen mucho tiempo, sin intentar compartir la cola de entrada entre ellos. Ver: http://stackoverflow.com/questions/783073/processing-messages-is-too-slow-resulting-in-a-jerky-unresponsive-ui-how-can – Shog9

+0

Para todos los efectos, deseo utilizar el hilo separado como el hilo de la interfaz de usuario. Solo deseo tener la capacidad de instigar la creación de ventanas desde el – ProPuke

+0

primario @ProPuke: y no puedes hacer eso. Windows debe ser propiedad y manipulado por un * y solo un hilo *: todo el sistema está diseñado con esta suposición. – Shog9

Respuesta

2

Parece que la mejor manera de instigar la creación de ventanas a partir del hilo principal, mientras se manejan los mensajes en un hilo separado y en bucle, es usar un mensaje personalizado, que se puede enviar al hilo separado. De este modo, crear la ventana, pero todavía permite que la acción para ser invocado desde la rosca inicial:

1) Asignar un mensaje personalizado, y crear una estructura para mantener los parámetros de ventana de inicialización:

message_create_window = WM_USER + 0; 
class Message_create_window{ 
    Message_create_window(...); 
}; 

2) en lugar de llamando al CreateWindow (Ex), use algo similar a lo siguiente, pasando el relavant parámetros de creación de ventana:

PostThreadMessage(
    thread.id, 
    message_create_window, 
    new Message_create_window(...), 
    0 
); 

3) controla el mensaje personalizado en el suministro de mensajes de la interfaz de usuario de hilo manejo, extraer los parámetros de creación, & libre después:

MSG msg; 
GetMessage(&msg,0,0,0); 
... 
switch(msg->message){ 
    ... 
    case message_create_window:{ 
     Message_create_window *data=msg->wParam; 
     CreateWindowEx(data->...); 
     delete data; 
    }break; 
    ... 

Esto, sin embargo, tienen la siguientes efectos secundarios:

  • La ventana se creará de forma asíncrona.Si se requiere que el bloque de subprocesos inicial hasta que se cree la ventana (o, de hecho, que la existencia de la ventana se pueda afirmar alguna vez) se debe utilizar una herramienta de sincronización de subprocesos (como un evento)
  • Se debe tener cuidado cuando interactuando con la ventana (es una aplicación multiproceso, después de todo)

Si hay algún problema importante en esta respuesta, o si esto parece un enfoque terrible, por favor corrígeme. (Esta es todavía mi pregunta, & Estoy tratando de encontrar la mejor manera de lograr esto)

7

Eso no lo hace AttachThreadInput. Incluso después de adjuntar la cola de entrada a otro hilo, Windows todavía tiene afinidad por el hilo. Los mensajes en la cola para una ventana determinada solo se pueden eliminar de la cola mediante el hilo de dicha ventana.

Lo que hace AttachTheadInput es hacer que dos subprocesos compartan una cola de entrada. Esto les permite consultar información sobre el estado de entrada y saber que el otro subproceso obtendrá la misma respuesta para la misma consulta. Por ejemplo, un hilo podría llamar al GetAsyncKeyState y saber que la respuesta reflejaba el estado de la clave del otro hilo.

Permite que dos o más hilos tengan la misma relación con la cola de entrada y entre sí como los procesos que tuvieron en Windows 3x. Esta es la razón por la que existe esta API; para que las aplicaciones complejas de multiproceso se puedan portar de Win 3x a Win95/WinNT.

+0

Ahh ya veo. Yo había malinterpretado el propósito de las funciones. En realidad, basé la suposición original en la siguiente respuesta: http://stackoverflow.com/questions/617248/can-the-hwnd-from-createwindow-createdialog-be-getmessaged-from-another-thread/621631#621631 ¿Conocerá alguna forma alternativa de lograr esta funcionalidad? – ProPuke

+0

Haz que el hilo original maneje la cola, y el nuevo hilo haga lo que quisieras que hiciera el hilo original. Alternativamente, crea todas tus ventanas en el nuevo hilo. –

Cuestiones relacionadas