2013-07-19 22 views
9

In un addon nodejs di Windows, ho creato una finestra allo scopo di ricevere messaggi.Come si pompano i messaggi della finestra in un addon nodejs?

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

Ho una funzione wndproc.

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); 
} 

Ora ho bisogno di pompare messaggi. Normalmente, si farebbe una cosa del genere

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

... ma che non funziona in quanto sarebbe solo bloccare il ciclo degli eventi v8.

Come faccio a pompare messaggi di Windows in un modo che non bloccherà la v8 e mi consente di richiamare una funzione JS quando la mia finestra riceve messaggi?

Suppongo che libuv svolgerà un ruolo, ma non sono sicuro esattamente come richiamare in modo sicuro una funzione JS da C in esecuzione su un thread separato, soprattutto dal uv_async_send is not guaranteed to invoke a callback every time you call it, e ho bisogno di assicurarmi che il mio callback JS venga chiamato ogni volta un messaggio finestra viene ricevuto.

risposta

11

L'errore stava tentando di creare la finestra sul thread V8. Invece, è necessario utilizzare uv_thread_create per chiamare una funzione che crea la finestra su una nuova discussione e quindi procede a eseguire il proprio ciclo di pompa dei messaggi.

La funzione wndproc deve quindi salvare i messaggi ricevuti in una coda in modalità thread-safe e quindi utilizzare uv_async_send per notificare al thread V8 che i messaggi sono arrivati.

Una funzione sul thread V8 (che è stata passata a uv_async_init) viene quindi richiamata dopo che i messaggi sono stati messi in coda. La funzione (thread-safe) apre ogni messaggio in sospeso dalla coda e richiama il callback JS.

+3

Grandi informazioni. Hai, per caso, un repository o un modulo nodo che realizza questo? Sto cercando di fare la stessa cosa. – Charlie

+0

Il tuo approccio ha funzionato? Ho problemi a trasferire la funzione callback in uv_async_send, una volta chiamata la funzione uv_thread_create, non riesco a ottenere la funzione di callback. Anche le maniglie persistenti non funzionano - ho postato la domanda in SO.http: //stackoverflow.com/questions/31159029/how-to-use-persistent-handles-for-callback-functions-in-v8 – opensourcegeek

+0

Hai o conosci un repository di codice che usa questa tecnica? Questo è esattamente l'approccio che sto prendendo. – Niall