Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I pump window messages in a nodejs addon?

In a Windows nodejs addon, I've created a window for the purpose of receiving messages.

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

I have a wndproc function.

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

Now I need to pump messages. Normally, you'd do something like

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

...but that won't work since it would just block the v8 event loop.

How do I pump Windows messages in a manner that won't block v8 and allows me to invoke a JS function when my window receives messages?

I presume libuv will play a role, but I'm unsure exactly how to safely invoke a JS function from C running on a separate thread, especially since uv_async_send is not guaranteed to invoke a callback every time you call it, and I need to ensure that my JS callback is called every time a window message is received.

like image 892
josh3736 Avatar asked Jul 19 '13 02:07

josh3736


People also ask

Which programming languages can you use to create node JS addons?

Addons are dynamically-linked shared objects written in C++. The require() function can load addons as ordinary Node. js modules. Addons provide an interface between JavaScript and C/C++ libraries.

Can I use C++ with Nodejs?

Node. js can dynamically load an external C or C++ DLL file at runtime and utilize its API to perform some operations written inside it from a JavaScript program.

What are node JS addons?

Node. js Addons are dynamically-linked shared objects, written in C++, that can be loaded into Node. js using the require() function, and used just as if they were an ordinary Node. js module. They are used primarily to provide an interface between JavaScript running in Node.


1 Answers

I needed to do this for Canon's EDSDK, which requires a message pump.

libuv's uv_idle_t is a good candidate for this:

Despite the name, idle handles will get their callbacks called on every loop iteration, not when the loop is actually “idle”

Example:

#include <uv.h>

uv_idle_t* idle = new uv_idle_t();
uv_idle_init(uv_default_loop(), idle);
uv_idle_start(idle, idle_winmsg);

void idle_winmsg (uv_idle_t* idle) {
    MSG msg;
    if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
}
like image 107
CAMason Avatar answered Sep 20 '22 15:09

CAMason