2013-07-19 5 views
9

In einem Windows Nodejs Addon habe ich ein Fenster zum Empfang von Nachrichten erstellt.Wie pumpe ich Fenstermeldungen in einem Nodejs Addon?

Handle<Value> MakeMessageWindow(const Arguments &args) { // exposed to JS 
    ... 
    CreateWindow(L"ClassName", NULL, 0, 0, 0, 0, 0, HWND_MESSAGE, 0, 0, 0); 
    ... 
} 

Ich habe eine Wndproc-Funktion.

Local<Function> wndProc; 
LRESULT APIENTRY WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { 
    // pack up the arguments into Local<Value> argv 
    wndProc->Call(Context::GetCurrent()->Global(), 3, argv); 
} 

Jetzt muss ich Nachrichten pumpen. Normalerweise würde man so etwas wie

MSG msg; 
while (GetMessage(&msg, NULL, 0, 0)) 
{ 
    TranslateMessage(&msg); 
    DispatchMessage(&msg); 
} 

tun ... aber das wird nicht funktionieren, da es nur die v8 Ereignisschleife blockieren würde.

Wie pumpe ich Windows-Nachrichten in einer Weise, die v8 nicht blockiert und erlaubt mir, eine JS-Funktion aufzurufen, wenn mein Fenster Nachrichten empfängt?

Ich nehme an, libuv wird eine Rolle spielen, aber ich bin mir nicht sicher, wie genau eine JS-Funktion von C auf einem separaten Thread aufrufen, vor allem seit uv_async_send is not guaranteed to invoke a callback every time you call it, und ich muss sicherstellen, dass mein JS-Callback jedes Mal aufgerufen wird Eine Fensternachricht wird empfangen.

Antwort

11

Mein Fehler war versucht, das Fenster auf dem V8-Thread zu erstellen. Stattdessen sollte uv_thread_create verwendet werden, um eine Funktion aufzurufen, die das Fenster auf einem neuen Thread erstellt und dann fortfährt, seine eigene Nachrichtenpumpenschleife zu tun.

Die wndproc-Funktion muss dann empfangene Nachrichten in einer Warteschlange threadsicher speichern und dann uv_async_send verwenden, um den V8-Thread darüber zu informieren, dass Nachrichten angekommen sind.

Eine Funktion im V8-Thread (die an uv_async_init übergeben wurde) wird dann aufgerufen, nachdem Nachrichten in die Warteschlange eingereiht wurden. Die Funktion (Thread-sicher) löscht jede ausstehende Nachricht aus der Warteschlange und ruft den JS-Rückruf auf.

+3

Tolle Infos. Haben Sie zufällig ein Repo- oder Knotenmodul, das dies ermöglicht? Ich versuche das Gleiche zu tun. – Charlie

+0

Hat Ihr Ansatz funktioniert? Ich habe Probleme, Rückruffunktion in uv_async_send zu übergeben, sobald die Funktion uv_thread_create aufgerufen wird, kann ich die Rückruffunktion nicht erhalten. Selbst hartnäckige Griffe funktionieren nicht - ich habe diese Frage auch in SO geschrieben. Http://stackoverflow.com/questions/31159029/how-to-use-persistent-handles-for-callback-functions-in-v8 – opensourcegeek

+0

Haben oder kennen Sie einen Code Repo, der diese Technik verwendet? Dies ist genau der Ansatz, den ich nehme. – Niall

Verwandte Themen