2011-08-01 21 views
6

El objetivo es crear comunicación entre los dos hilos, uno de los cuales es el hilo principal. Lo que estoy buscando es crear una ventana que requiera menos recursos y usarla solo para recibir mensajes.Cómo crear una ventana pura de winapi

¿A qué me puede referir?

+2

Es posible que desee echar un vistazo a ['AllocateHWnd'] (http://docs.embarcadero.com/products/rad_studio/delphiAndcpp2009/HelpUpdate2/EN/html/delphivclwin32/Classes_AllocateHWnd.html). –

+0

@Sertac Akyuz, lo siento, he secuestrado su sugerencia involuntariamente, solo me di cuenta después de escribir mi propia respuesta :-( –

+0

La desventaja de AllocateHwnd es que no es seguro. Por supuesto, esto se puede solucionar –

Respuesta

7

Lo que necesita hacer es configurar un bucle de mensajes en su hilo, y usar AllocateHWnd en su hilo principal para enviar mensajes hacia adelante y hacia atrás. Es bastante simple.

En su hilo de ejecutar la función de tener lo siguiente:

procedure TMyThread.Execute; 
begin 
    // this sets up the thread message loop 
    PeekMessage(LMessage, 0, WM_USER, WM_USER, PM_NOREMOVE); 

    // your main loop 
    while not terminated do 
    begin 
    // look for messages in the threads message queue and process them in turn. 
    // You can use GetMessage here instead and it will block waiting for messages 
    // which is good if you don't have anything else to do in your thread. 
    while PeekMessage(LMessage, 0, WM_USER, $7FFF, PM_REMOVE) do 
    begin 
     case LMessage.Msg of 
     //process the messages 
     end; 
    end; 

    // do other things. There would probably be a wait of some 
    // kind in here. I'm just putting a Sleep call for brevity 
    Sleep(500); 

    end; 
end; 

Para enviar un mensaje a su hilo, hacer algo como lo siguiente:

PostThreadMessage(MyThread.Handle, WM_USER, 0, 0); 

En el lado del hilo principal de las cosas, establecer hasta un identificador de ventana utilizando AllocateHWnd (en la unidad Clases), pasándole un método WndProc. AllocateHWnd es muy ligero y es fácil de usar:

TMyMessageReciever = class 
private 
    FHandle: integer; 

    procedure WndProc(var Msg: TMessage); 

public 
    constructor Create; 
    drestructor Destroy; override; 

    property Handle: integer read FHandle; 

end; 

implementation 

constructor TMyMessageReciever.Create; 
begin 
    inherited Create; 
    FHandle := Classes.AllocateHWnd(WndProc); 
end; 

destructor TMyMessageReciever.Destroy; 
begin 
    DeallocateHWnd(FHandle); 
    inherited Destroy; 
end; 

procedure TMyMessageReciever.WndProc(var Msg: TMessage); 
begin 
    case Msg.Msg of 
    //handle your messages here 
    end; 
end; 

y enviar mensajes, ya sea con SendMessage, que bloqueará hasta que el mensaje haya sido manipulado, o PostMessage la que lo hace de forma asíncrona.

Espero que esto ayude.

+3

Alternativamente, realmente no necesitas 'AllocateHwnd()' en el hilo principal, especialmente si desea reducir recursos. Use 'PostThreadMessage()' para publicar mensajes directamente en la cola de mensajes del subproceso principal utilizando la variable 'MainThreadID' como ID de la cadena de destino, luego use el evento' TApplication.OnMessage' para recibir los mensajes. Puede distinguir un mensaje de subproceso de un mensaje de ventana mirando el miembro 'TMsg.hwnd', que será cero para los mensajes de subproceso. –

+0

Ha intentado ambos, pero ninguno funcionó en una aplicación de consola. Mi código -> http://pastebin.com/jm5K4EHN – netboy

+0

No me di cuenta de que estaba en una aplicación de consola ... Veo el problema en su código ... No está revisando la cola de mensajes periódicamente para ver si hay algún mensaje ... Tu código está sentado en el Readln. Para la aplicación "sin consola", debe llamar periódicamente a los mensajes de Application.Process. En la versión de consola necesita un mensaje de bomba. Creo que deberías ver el ejemplo de Andreas, que hace exactamente lo que quieres hacer. – Nat

7

Esto es lo que message-only windows son para. He escrito una muestra del sistema de envío + recepción de Delphi al a previous question.

+0

Tipo de marcas esta pregunta es una tontería, excepto que la pregunta vinculada fue muy específica, y esta es general, y por lo tanto, esta pregunta es más útil. Quizás en tales casos sería mejor pegar todo el ejemplo del código (duplicarlo) aquí .. Tus pensamientos? –

2

En OmniThread Library por Gabr ofrece una unidad pequeña y agradable DSiWin32, la usa para crear ventanas de mensajes, o simplemente puede usar OmniThread para hacer la comunicación por usted.

+0

Esto es superior a hacer un poco de hackeo de bajo nivel. –

Cuestiones relacionadas