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.
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.
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.
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.
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);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With