Skip to content

Instantly share code, notes, and snippets.

@anonymous1184
Last active January 8, 2024 14:49
Show Gist options
  • Star 6 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save anonymous1184/cd70e009792fc2eb866f9f5caf1e395a to your computer and use it in GitHub Desktop.
Save anonymous1184/cd70e009792fc2eb866f9f5caf1e395a to your computer and use it in GitHub Desktop.
WM_COPYDATA Messaging

WM_COPYDATA Messaging

Usage example:

  1. Run receiver.ahk
  2. Run sender.ahk

; Version: 2023.05.17.1
; https://gist.github.com/cd70e009792fc2eb866f9f5caf1e395a
/*
Message.Listen(Callback) ; Listen
Message.Listen() ; Stop listening
Message.Send(Message, Target[, Timeout := 7000ms])
ErrorLevel
-1 = Target not found
0 = Message accepted
1 = Message ignored
*/
class Message {
Listen(Callback := "") {
static WM_COPYDATA := 0x004A, bound := ""
if (Callback = "") {
OnMessage(WM_COPYDATA, bound, 0)
bound := ""
return
}
if (IsObject(Callback)) {
if (Callback.MinParams < 1)
throw Exception("Callback requires at least 1 parameter.", -1, Callback.Name)
_callback := Callback
} else {
if (!IsFunc(Callback))
throw Exception("Not a function.", -1, Callback)
_callback := Func(Callback)
}
bound := ObjBindMethod(Message, "_Receive", _callback)
OnMessage(WM_COPYDATA, bound, 1)
}
Send(Msg, Target, Timeout := 7000) {
static WM_COPYDATA := 0x004A
VarSetCapacity(COPYDATASTRUCT, 3 * A_PtrSize)
NumPut(StrPut(Msg) * 2, COPYDATASTRUCT, A_PtrSize)
NumPut(&Msg, COPYDATASTRUCT, 2 * A_PtrSize)
Message._Modes(1)
SendMessage WM_COPYDATA, 0, &COPYDATASTRUCT,, % Target,,,, % Timeout
result := ErrorLevel
Message._Modes(0)
ErrorLevel := (result = "FAIL" ? -1 : !result)
}
; Private
_Modes(Mode) {
static dhw, tmm
if (Mode) {
dhw := A_DetectHiddenWindows
tmm := A_TitleMatchMode
}
DetectHiddenWindows % {0:dhw, 1:1}[Mode]
SetTitleMatchMode % {0:tmm, 1:2}[Mode]
}
_Receive(Callback, _wParam, lParam) {
lParam := NumGet(lParam + 2 * A_PtrSize)
msg := StrGet(lParam)
return Callback.Call(msg)
}
}
#Requires AutoHotkey v1.1
#Warn All
; Wait for incoming messages
Message.Listen("MyCallback")
return ; End of auto-execute
#Include %A_LineFile%\..\Message.ahk
MyCallback(MessageText) {
if (StrLen(MessageText) < 10)
return false ; Message ignored
MsgBox 0x40040, Message received, % MessageText
return true ; Message accepted
}
#Requires AutoHotkey v1.1
#Warn All
; Send a message to non-existent script
Message.Send("Hello World!", "non-existent-script.ahk")
if (ErrorLevel = -1)
MsgBox 0x40010, Error, Target not found, message wasn't sent.
; Send a message (filtered by receiver's callback)
Message.Send("Hello", "receiver.ahk")
if (ErrorLevel)
MsgBox 0x40030, Attention!, Message was ignored (too short).
; Send a message (receiver's callback will inform)
Message.Send("Hello World!", "receiver.ahk")
ExitApp
#Include %A_LineFile%\..\Message.ahk
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment