;--------------------------------------------------------------------------------------------------------------- ; CHANGELOG: ; ; Dec 16 2021: Initial release by Glisense ltd ; ; Current script is designed for use together with Keyboard Extension® (https://keyboardextension.com) ; ; For the latest version, description and licensing terms go to https://keyboardextension.com/plugins/02194f9d ; ;--------------------------------------------------------------------------------------------------------------- #NoEnv ; Avoid checking empty variables if they are environment variables #NoTrayIcon ; Hide tray icon SetBatchLines, -1 Msg := new Messaging SendParam := ObjBindMethod(Msg, "SendParam") Timer := Func("SendTime").Bind(SendParam) SetTimer, % Timer, -10 Return SendTime(SendParam) { systemTime := A_DD . "." . A_MM . "." . A_YEAR . "`n" . A_Hour . ":" . A_Min . ":" . A_Sec . "." . A_MSec SendParam.Call("systemTime", systemTime) ; outgoing parameter SetTimer,, -20 } class Messaging { /* The Messaging class implements messaging between Keyboard Extension® for Windows (KEW) and the script. When the instance of the class Messaging is created, a Func Object or a function name can optionally be passed to the constructor of the class. This object or function is required to process incoming messages from KEW. In order to send messages to KEW, SendParam(param, value) method is used, where param is the name of the outgoing parameter value is its corresponding value UserOnMessageFunc — a custom Func Object or a function name that will be called when messages are received from KEW It accepts two mandatory parameters: param - the name of the incoming parameter value - the value of the incoming parameter */ __New(UserOnMessageFunc := "") { if UserOnMessageFunc { UserFunc := IsObject(UserOnMessageFunc) ? UserOnMessageFunc : Func(UserOnMessageFunc) this.OnMessageReceive := new this.Receiving(UserFunc) } } __Delete() { if this.OnMessageReceive { this.OnMessageReceive.Clear() this.OnMessageReceive := "" } } SendParam(param, value) { ; these gobal variables get values ​​when the plugin starts, they are required to send messages to KEW global HostWindowHandle, HostEngineThreadId while !(HostWindowHandle && HostEngineThreadId) Sleep, 10 this._SendData(HostWindowHandle, HostEngineThreadId, param . ":" . value) } _SendData(hWnd, EngineThreadId, StringData) { VarSetCapacity(message, size := StrPut(StringData, "UTF-16")*2, 0) StrPut(StringData, &message, "UTF-16") VarSetCapacity(COPYDATASTRUCT, A_PtrSize*3, 0) NumPut(EngineThreadId, COPYDATASTRUCT, 0, "UInt") NumPut(size, COPYDATASTRUCT, A_PtrSize, "UInt") NumPut(&message, COPYDATASTRUCT, A_PtrSize*2) DllCall("SendMessage", Ptr, hWnd, UInt, WM_COPYDATA := 0x4A, Ptr, 0, Ptr, ©DATASTRUCT) } class Receiving { WM_COPYDATA := 0x4A __New(UserFunc) { this.dataArr := [] this.UserFunc := UserFunc this.timer := ObjBindMethod(this, "MessageProcessing") this.OnMsg := ObjBindMethod(this, "CopyDataRead") OnMessage(this.WM_COPYDATA, this.OnMsg) } CopyDataRead(wp, lp) { data := StrGet(NumGet(lp + A_PtrSize*2), "UTF-16") this.dataArr.Push(data) timer := this.timer SetTimer, % timer, -10 Return true } MessageProcessing() { while this.dataArr[1] != "" { data := this.dataArr.RemoveAt(1) RegExMatch(data, "^(.*?):(.*)", m) param := m1, value := m2 this.UserFunc.Call(param, value) } } Clear() { OnMessage(this.WM_COPYDATA, this.OnMsg, 0) this.OnMsg := "" this.timer := "" } } }