mirror of
https://github.com/Ylianst/MeshAgent
synced 2026-02-06 19:53:14 +00:00
Added support for trapping child window events
Added first rev of support for mouse over cursor changes
This commit is contained in:
@@ -113,6 +113,7 @@ typedef uintptr_t(__stdcall *Z2)(uintptr_t V1, VARIANT V2, uintptr_t V3);
|
||||
#define ILibDuktape_GenericMarshal_CUSTOM_HANDLER 0x80000000
|
||||
#define ILibDuktape_GenericMarshal_CUSTOM_HANDLER_VERIFY 0x40000000
|
||||
#define ILibDuktape_GenericMarshal_CUSTOM_HANDLER_MASK 0x3FFFFFFF
|
||||
ILibHashtable marshal_data = NULL;
|
||||
|
||||
uintptr_t ILibDuktape_GenericMarshal_MethodInvoke_CustomEx(int parms, void *fptr, uintptr_t *vars, int check, int index)
|
||||
{
|
||||
@@ -207,10 +208,9 @@ void GenericMarshal_CustomEventHandler_Dispatch_Chain(void *chain, void *user)
|
||||
duk_del_prop_string(data->emitter->ctx, -1, "callbackDispatched");
|
||||
sem_post(&(data->waiter));
|
||||
}
|
||||
uintptr_t GenericMarshal_CustomEventHandler_Dispatch(uintptr_t *args, size_t argsLen, uint32_t index)
|
||||
uintptr_t GenericMarshal_CustomEventHandler_Dispatch2(ILibDuktape_EventEmitter *emitter, uintptr_t *args, size_t argsLen)
|
||||
{
|
||||
uintptr_t ret = 0;
|
||||
ILibDuktape_EventEmitter *emitter = GenericMarshal_CustomEventHandler_Events[index];
|
||||
if (emitter != NULL && ILibMemory_CanaryOK(emitter))
|
||||
{
|
||||
int dispatch = ILibIsRunningOnChainThread(duk_ctx_chain(emitter->ctx)) == 0;
|
||||
@@ -234,6 +234,11 @@ uintptr_t GenericMarshal_CustomEventHandler_Dispatch(uintptr_t *args, size_t arg
|
||||
}
|
||||
return(ret);
|
||||
}
|
||||
uintptr_t GenericMarshal_CustomEventHandler_Dispatch(uintptr_t *args, size_t argsLen, uint32_t index)
|
||||
{
|
||||
ILibDuktape_EventEmitter *emitter = GenericMarshal_CustomEventHandler_Events[index];
|
||||
return(GenericMarshal_CustomEventHandler_Dispatch2(emitter, args, argsLen));
|
||||
}
|
||||
|
||||
#ifdef WIN32
|
||||
uintptr_t __stdcall GenericMarshal_CustomEventHandler_10(uintptr_t var1, uintptr_t var2, uintptr_t var3)
|
||||
@@ -261,6 +266,31 @@ uintptr_t __stdcall GenericMarshal_CustomEventHandler_14(uintptr_t var1, uintptr
|
||||
uintptr_t args[] = { var1, var2, var3, var4, var5 };
|
||||
return(GenericMarshal_CustomEventHandler_Dispatch(args, sizeof(args) / sizeof(uintptr_t), 14));
|
||||
}
|
||||
uintptr_t __stdcall GenericMarshal_CustomEventHandler_55(uintptr_t var1, uintptr_t var2, uintptr_t var3, uintptr_t var4)
|
||||
{
|
||||
uintptr_t args[] = { var1, var2, var3, var4 };
|
||||
uintptr_t ret = 0;
|
||||
|
||||
void **val;
|
||||
|
||||
if (marshal_data != NULL)
|
||||
{
|
||||
ILibHashtable_Lock(marshal_data);
|
||||
val = (void**)ILibHashtable_Get(marshal_data, (void*)var1, NULL, 0);
|
||||
ILibHashtable_UnLock(marshal_data);
|
||||
|
||||
if (val != NULL)
|
||||
{
|
||||
WNDPROC func = (WNDPROC)val[0];
|
||||
ret = (uintptr_t)func((HWND)var1, (UINT)var2, (WPARAM)var3, (LPARAM)var4);
|
||||
if (val[1] != NULL)
|
||||
{
|
||||
GenericMarshal_CustomEventHandler_Dispatch2(val[1], args, sizeof(args) / sizeof(uintptr_t));
|
||||
}
|
||||
}
|
||||
}
|
||||
return(ret);
|
||||
}
|
||||
#endif
|
||||
|
||||
void ILibDuktape_GenericMarshal_GetGlobalGenericCallbackEx_CustomHandler(duk_context *ctx, int paramCount, uint32_t index)
|
||||
@@ -304,6 +334,13 @@ void ILibDuktape_GenericMarshal_GetGlobalGenericCallbackEx_CustomHandler(duk_con
|
||||
ILibDuktape_GenericMarshal_GetGlobalGenericCallbackEx_CustomHandler_Setup(ctx, GenericMarshal_CustomEventHandler_14, index);
|
||||
}
|
||||
break;
|
||||
case 55:
|
||||
if (paramCount == 4)
|
||||
{
|
||||
ok = 1;
|
||||
ILibDuktape_GenericMarshal_GetGlobalGenericCallbackEx_CustomHandler_Setup(ctx, GenericMarshal_CustomEventHandler_55, index);
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
ILibDuktape_Error(ctx, "Undefined Custom Event Handler Index: %u", index);
|
||||
@@ -3032,6 +3069,7 @@ duk_ret_t ILibDuktape_GenericMarshal_MarshalFunction(duk_context *ctx)
|
||||
{
|
||||
duk_dup(ctx, 2); duk_put_prop_string(ctx, -2, "_callType");
|
||||
}
|
||||
|
||||
duk_push_string(ctx, "_MarshalledFunction"); duk_put_prop_string(ctx, -2, "_exposedName");
|
||||
return(1);
|
||||
}
|
||||
@@ -3062,7 +3100,43 @@ duk_ret_t ILibDuktape_GenericMarshal_MarshalFunctions(duk_context *ctx)
|
||||
return(ILibDuktape_Error(ctx, "Invalid Parameters"));
|
||||
}
|
||||
|
||||
duk_ret_t ILibDuktape_GenericMarshal_PutData(duk_context *ctx)
|
||||
{
|
||||
void *arg1 = Duktape_GetPointerProperty(ctx, 0, "_ptr");
|
||||
void *arg2 = Duktape_GetPointerProperty(ctx, 1, "_ptr");
|
||||
ILibDuktape_EventEmitter *e = NULL;
|
||||
if (!duk_is_null_or_undefined(ctx, 2)) { e = ILibDuktape_EventEmitter_GetEmitter(ctx, 2); }
|
||||
void **val = (void**)ILibMemory_SmartAllocate(2 * sizeof(void*));
|
||||
val[0] = arg2;
|
||||
val[1] = e;
|
||||
|
||||
if (marshal_data == NULL) { marshal_data = ILibHashtable_Create(); }
|
||||
if (!duk_is_null_or_undefined(ctx, 2))
|
||||
{
|
||||
duk_push_heap_stash(ctx); // [stash]
|
||||
if (!duk_has_prop_string(ctx, -1, ILibDutkape_GenericMarshal_INTERNAL)) { duk_push_object(ctx); duk_put_prop_string(ctx, -2, ILibDutkape_GenericMarshal_INTERNAL); } // [stash][obj]
|
||||
duk_push_sprintf(ctx, "%p", arg1); // [stash][obj][key]
|
||||
duk_dup(ctx, 2); // [stash][obj][key][val]
|
||||
duk_put_prop(ctx, -3);
|
||||
}
|
||||
|
||||
ILibHashtable_Lock(marshal_data);
|
||||
ILibHashtable_Put(marshal_data, arg1, NULL, 0, val);
|
||||
ILibHashtable_UnLock(marshal_data);
|
||||
return(0);
|
||||
}
|
||||
duk_ret_t ILibDuktape_GenericMarshal_RemoveData(duk_context *ctx)
|
||||
{
|
||||
if (marshal_data != NULL)
|
||||
{
|
||||
void *arg1 = Duktape_GetPointerProperty(ctx, 0, "_ptr");
|
||||
|
||||
ILibHashtable_Lock(marshal_data);
|
||||
ILibHashtable_Remove(marshal_data, arg1, NULL, 0);
|
||||
ILibHashtable_UnLock(marshal_data);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
void ILibDuktape_GenericMarshal_Push(duk_context *ctx, void *chain)
|
||||
{
|
||||
duk_push_object(ctx); // [obj]
|
||||
@@ -3084,7 +3158,9 @@ void ILibDuktape_GenericMarshal_Push(duk_context *ctx, void *chain)
|
||||
ILibDuktape_CreateInstanceMethod(ctx, "GetCurrentThread", ILibDuktape_GenericMarshal_GetCurrentThread, 0);
|
||||
ILibDuktape_CreateInstanceMethod(ctx, "MarshalFunction", ILibDuktape_GenericMarshal_MarshalFunction, DUK_VARARGS);
|
||||
ILibDuktape_CreateInstanceMethod(ctx, "MarshalFunctions", ILibDuktape_GenericMarshal_MarshalFunctions, 2);
|
||||
|
||||
ILibDuktape_CreateInstanceMethod(ctx, "PutData", ILibDuktape_GenericMarshal_PutData, DUK_VARARGS);
|
||||
ILibDuktape_CreateInstanceMethod(ctx, "RemoveData", ILibDuktape_GenericMarshal_RemoveData, 1);
|
||||
|
||||
|
||||
#ifdef WIN32
|
||||
duk_push_object(ctx);
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -26,10 +26,15 @@ const DEFAULT_QUALITY = 0;
|
||||
const DEFAULT_PITCH = 0;
|
||||
const FF_SWISS = (2 << 4); /* Variable stroke width, sans-serifed. */
|
||||
|
||||
const TME_HOVER = 0x00000001;
|
||||
const TME_LEAVE = 0x00000002;
|
||||
const TME_NONCLIENT = 0x00000010;
|
||||
|
||||
const WM_NCLBUTTONDOWN = 0x00A1;
|
||||
const HT_CAPTION = 2;
|
||||
const WM_WINDOWPOSCHANGING = 70;
|
||||
const IDC_ARROW = 32512;
|
||||
const IDC_HAND = 32649;
|
||||
|
||||
const SW_SHOW = 5;
|
||||
const SW_HIDE = 0;
|
||||
@@ -40,10 +45,16 @@ const WM_MOUSEMOVE = 0x0200;
|
||||
const WM_SETFONT = 0x0030;
|
||||
const WM_LBUTTONDOWN = 0x0201;
|
||||
const WM_USER = 0x0400;
|
||||
|
||||
const WM_MOUSEHOVER = 0x02A1;
|
||||
const WM_MOUSELEAVE = 0x02A3;
|
||||
const WM_NCMOUSEHOVER = 0x02A0;
|
||||
const WM_NCMOUSELEAVE = 0x02A2;
|
||||
const WS_CHILD = 0x40000000;
|
||||
const WS_TABSTOP = 0x00010000;
|
||||
const WS_VISIBLE = 0x10000000;
|
||||
const WM_SETCURSOR = 0x0020;
|
||||
const GCL_HCURSOR = -12;
|
||||
const GCLP_HCURSOR = -12;
|
||||
|
||||
const STM_SETIMAGE = 0x0172;
|
||||
const STM_GETIMAGE = 0x0173;
|
||||
@@ -294,6 +305,11 @@ function windows_notifybar_local(title, bar_options)
|
||||
this.notifybar._pumps.peek().on('hwnd', function (h)
|
||||
{
|
||||
this._HANDLE = h;
|
||||
this._HAND = this._user32.LoadCursorA(0, IDC_HAND);
|
||||
this._ARROW = this._user32.LoadCursorA(0, IDC_ARROW);
|
||||
|
||||
this._addAsyncMethodCall(this._user32.SetClassLongPtrA.async, [h, GCLP_HCURSOR, this._ARROW]).then(function (z) { console.log('SetClassLong: ' + z.Val, z._LastError); });
|
||||
|
||||
this._icon = getScaledImage(x_icon, this.height * 0.75, this.height * 0.75, bar_options);
|
||||
this._addCreateWindowEx(0, GM.CreateVariable('STATIC', { wide: true }), GM.CreateVariable('X', { wide: true }), WS_TABSTOP | WS_VISIBLE | WS_CHILD | SS_BITMAP | SS_CENTERIMAGE | SS_NOTIFY,
|
||||
this.width - (this.height * 0.75) - (this.height * 0.125), // x position
|
||||
@@ -323,6 +339,17 @@ function windows_notifybar_local(title, bar_options)
|
||||
this.pump._pushpin = c;
|
||||
this.pump._pinned = true;
|
||||
this.pump._addAsyncMethodCall(this.pump._user32.SendMessageW.async, [c, STM_SETIMAGE, IMAGE_BITMAP, this.pump._pin1.Deref()]);
|
||||
c.x = this.pump.height * 0.125;
|
||||
c.y = this.pump.height * 0.0625;
|
||||
c.w = this.pump.height * 0.75;
|
||||
c.h = this.pump.height * 0.75;
|
||||
|
||||
var r = GM.CreateVariable(4);
|
||||
r.increment(4294967284, true);
|
||||
|
||||
this.pump._addAsyncMethodCall(this.pump._user32.SetClassLongPtrA.async, [c, GCLP_HCURSOR, this.pump._HAND]).then(function (z) { console.log('SetClassLong: ' + z.Val, z._LastError); });
|
||||
|
||||
//this.pump.hookChild(c);
|
||||
}).parentPromise.pump = this;
|
||||
this._addCreateWindowEx(0, GM.CreateVariable('STATIC', { wide: true }), GM.CreateVariable(this._title, { wide: true }), WS_TABSTOP | WS_VISIBLE | WS_CHILD | SS_LEFT | SS_CENTERIMAGE | SS_WORDELLIPSIS,
|
||||
this.height, // x position
|
||||
@@ -419,6 +446,26 @@ function windows_notifybar_local(title, bar_options)
|
||||
}
|
||||
break;
|
||||
case WM_MOUSEMOVE:
|
||||
if (msg.hwnd.Val == this._pushpin.Val)
|
||||
{
|
||||
if (this.pushpincursor == null || this.pushpincursor === false)
|
||||
{
|
||||
this.pushpincursor = true;
|
||||
|
||||
console.log('PUSHPIN!');
|
||||
var v = GM.CreateVariable(24);
|
||||
v.toBuffer().writeUInt32LE(24);
|
||||
v.toBuffer().writeUInt32LE(TME_LEAVE, 4);
|
||||
this._pushpin.pointerBuffer().copy(v.Deref(8, 8).toBuffer());
|
||||
this._user32.TrackMouseEvent(v);
|
||||
|
||||
//this._addAsyncMethodCall(this._user32.LoadCursorA.async, [0, IDC_HAND]).then(function (cs)
|
||||
//{
|
||||
// this.pump._addAsyncMethodCall(this.pump._user32.SetCursor.async, [cs]);
|
||||
//}).parentPromise.pump = this;
|
||||
//break;
|
||||
}
|
||||
}
|
||||
if (!this._pinned)
|
||||
{
|
||||
if (this._minimized)
|
||||
@@ -431,6 +478,29 @@ function windows_notifybar_local(title, bar_options)
|
||||
this._idle = setTimeout(this._idleTimeout.bind(this), 3000);
|
||||
}
|
||||
break;
|
||||
case WM_MOUSELEAVE:
|
||||
case WM_NCMOUSELEAVE:
|
||||
console.log('LEAVE!');
|
||||
this.pushpincursor = false;
|
||||
this._addAsyncMethodCall(this._user32.LoadCursorA.async, [0, IDC_ARROW]).then(function (cs)
|
||||
{
|
||||
this.pump._addAsyncMethodCall(this.pump._user32.SetCursor.async, [cs]);
|
||||
}).parentPromise.pump = this;
|
||||
break;
|
||||
case WM_SETCURSOR:
|
||||
console.log('SETCURSOR', this._HANDLE.Val == msg.hwnd.Val);
|
||||
if (this._HANDLE.Val == msg.hwnd.Val)
|
||||
{
|
||||
//if(this.pushpincursor === true)
|
||||
//{
|
||||
// return (this._HAND);
|
||||
//}
|
||||
//else
|
||||
//{
|
||||
// return (this._ARROW);
|
||||
//}
|
||||
}
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ var WH_CALLWNDPROC = 4;
|
||||
var WM_QUIT = 0x0012;
|
||||
var WM_CLOSE = 0x0010;
|
||||
var GM = require('_GenericMarshal');
|
||||
const GWLP_WNDPROC = -4;
|
||||
|
||||
function WindowsMessagePump(options)
|
||||
{
|
||||
@@ -55,11 +56,15 @@ function WindowsMessagePump(options)
|
||||
this._user32.CreateMethod('RegisterClassExW');
|
||||
this._user32.CreateMethod('ReleaseCapture');
|
||||
this._user32.CreateMethod('SendMessageW');
|
||||
this._user32.CreateMethod('SetClassLongA');
|
||||
this._user32.CreateMethod('SetClassLongPtrA');
|
||||
this._user32.CreateMethod('SetCursor');
|
||||
this._user32.CreateMethod('SetWindowLongPtrA');
|
||||
this._user32.CreateMethod('SetWindowPos');
|
||||
this._user32.CreateMethod('SetWindowTextW');
|
||||
this._user32.CreateMethod('ShowWindow');
|
||||
this._user32.CreateMethod('SystemParametersInfoA');
|
||||
this._user32.CreateMethod('TrackMouseEvent');
|
||||
this._user32.CreateMethod('TranslateMessage');
|
||||
this._user32.CreateMethod('UnregisterClassW');
|
||||
|
||||
@@ -101,6 +106,7 @@ function WindowsMessagePump(options)
|
||||
this.wndclass.wndproc.on('GlobalCallback', function onWndProc(xhwnd, xmsg, wparam, lparam)
|
||||
{
|
||||
var processed = false;
|
||||
|
||||
if (this.mp._hwnd != null && this.mp._hwnd.Val == xhwnd.Val)
|
||||
{
|
||||
// This is for us
|
||||
@@ -186,6 +192,7 @@ function WindowsMessagePump(options)
|
||||
if (!this.nativeProxy.mp._options) { this.nativeProxy.mp._options = {}; }
|
||||
if (!this.nativeProxy.mp._options.window) { this.nativeProxy.mp._options.window = {}; }
|
||||
if (this.nativeProxy.mp._options.window.exstyles == null) { this.nativeProxy.mp._options.window.exstyles = 0x00000088; } // TopMost Tool Window
|
||||
//if (this.nativeProxy.mp._options.window.exstyles == null) { this.nativeProxy.mp._options.window.exstyles = 0x00000080; } // Tool Window
|
||||
if (this.nativeProxy.mp._options.window.winstyles == null) { this.nativeProxy.mp._options.window.winstyles = 0x00800000; } // WS_BORDER
|
||||
if (this.nativeProxy.mp._options.window.x == null) { this.nativeProxy.mp._options.window.x = 0; }
|
||||
if (this.nativeProxy.mp._options.window.y == null) { this.nativeProxy.mp._options.window.y = 0; }
|
||||
@@ -230,7 +237,8 @@ function WindowsMessagePump(options)
|
||||
this._startPump_continuation = function _startPump_continuation(h)
|
||||
{
|
||||
this.finalpromise.resolve(h);
|
||||
this.nativeProxy.mp._startPump();
|
||||
//this.nativeProxy.mp._startPump();
|
||||
this.mp._startPump();
|
||||
}
|
||||
this._startPump = function _startPump()
|
||||
{
|
||||
@@ -241,6 +249,7 @@ function WindowsMessagePump(options)
|
||||
args.unshift(this._user32.RegisterClassExW.async);
|
||||
var p2 = j.func.apply(this._user32, args);
|
||||
p2.finalpromise = j.p;
|
||||
p2.mp = this;
|
||||
p2.then(this._startPump_continuation);
|
||||
return;
|
||||
}
|
||||
@@ -294,6 +303,36 @@ function WindowsMessagePump(options)
|
||||
{
|
||||
this.stop();
|
||||
});
|
||||
|
||||
this.hookChild = function hookChild(childHwnd)
|
||||
{
|
||||
if (this.wndclass.wndproc.hooks == null) { this.wndclass.wndproc.hooks = []; }
|
||||
|
||||
var newval = GM.GetGenericGlobalCallbackEx(4, 55);
|
||||
newval.childHwnd = childHwnd;
|
||||
newval.mp = this;
|
||||
newval.on('GlobalCallback', function hookedWndProc(xhwnd, xmsg, wparam, lparam)
|
||||
{
|
||||
if (this.childHwnd.Val == xhwnd.Val)
|
||||
{
|
||||
try
|
||||
{
|
||||
this.mp.emit('message', { message: xmsg.Val, wparam: wparam.Val, lparam: lparam.Val, lparam_hex: lparam.pointerBuffer().toString('hex'), lparam_raw: lparam, hwnd: xhwnd });
|
||||
}
|
||||
catch (zz)
|
||||
{
|
||||
console.info1(zz);
|
||||
}
|
||||
}
|
||||
});
|
||||
var old = this._user32.SetWindowLongPtrA(childHwnd, GWLP_WNDPROC, newval);
|
||||
if (old.Val != 0)
|
||||
{
|
||||
GM.PutData(childHwnd, old, newval);
|
||||
return (true);
|
||||
}
|
||||
return (false);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = WindowsMessagePump;
|
||||
|
||||
Reference in New Issue
Block a user