如何将 WM_COPYDATA 从 C++ 发送到 AutoHotKey?
How to send WM_COPYDATA from C++ to AutoHotKey?
尝试使用 WM_COPYDATA
从 C++ 应用程序 SendMessage 到 AutoHotkey 脚本。
我尝试按照文档中的示例进行操作:
https://docs.microsoft.com/en-us/windows/win32/dataxchg/using-data-copy
然后我做了:
HWND htarget_window = FindWindow(NULL, L"MyGui");
std::string str = "Hello World";
COPYDATASTRUCT cds;
cds.dwData = 1;
cds.lpData = (PVOID) str.c_str();
cds.cbData = strlen((char*)cds.lpData);
auto Response = SendMessage(htarget_window, WM_COPYDATA, (WPARAM)htarget_window, (LPARAM)&cds);
并且在 Autohotkey 脚本中:
OnMessage(0x4a , "Receive_WM_COPYDATA")
Receive_WM_COPYDATA(wParam, lParam) {
; Retrieves the CopyDataStruct's lpData member.
StringAddress := NumGet(lParam + 2*A_PtrSize)
; Copy the string out of the structure.
Data := StrGet(StringAddress)
MsgBox Received the following string: %Data%
}
正在接收消息,但这是输出:
应该是:Hello World
.
我还在 SendMessage
之后检查了 GetLastError()
,它输出 0
。
我一定是在 COPYDATASTRUCT
里面做错了什么。
AutoHotkey x64.
你对StrGet()
的使用是错误的:
您没有在发送的数据中包含 std::string
的空终止符,但您没有将 COPYDATASTRUCT::cbData
字段的值传递给 StrGet()
,因此它将寻找一个不存在的空终止符。所以你需要在 COPYDATASTRUCT::cbData
字段中指定长度,例如:
StringLen := NumGet(lParam + A_PtrSize, "int");
StringAddress := NumGet(lParam + 2*A_PtrSize);
Data := StrGet(StringAddress, StringLen, Encoding);
更重要的是,您没有为 StrGet()
指定 Encoding
,因此它将以脚本的本机编码解释原始数据(请参阅A_IsUnicode
)。不要那样做。明确 C++ 代码使用的编码。如果 std::string
包含 UTF-8 字符串,请指定 "UTF-8"
。如果 std::string
包含用户默认 ANSI 语言环境中的字符串,请指定 "CP0"
。等等。您所看到的情况通常称为 Mojibake,当单字节字符数据在错误的编码中被错误解释时会发生这种情况。
尝试使用 WM_COPYDATA
从 C++ 应用程序 SendMessage 到 AutoHotkey 脚本。
我尝试按照文档中的示例进行操作:
https://docs.microsoft.com/en-us/windows/win32/dataxchg/using-data-copy
然后我做了:
HWND htarget_window = FindWindow(NULL, L"MyGui");
std::string str = "Hello World";
COPYDATASTRUCT cds;
cds.dwData = 1;
cds.lpData = (PVOID) str.c_str();
cds.cbData = strlen((char*)cds.lpData);
auto Response = SendMessage(htarget_window, WM_COPYDATA, (WPARAM)htarget_window, (LPARAM)&cds);
并且在 Autohotkey 脚本中:
OnMessage(0x4a , "Receive_WM_COPYDATA")
Receive_WM_COPYDATA(wParam, lParam) {
; Retrieves the CopyDataStruct's lpData member.
StringAddress := NumGet(lParam + 2*A_PtrSize)
; Copy the string out of the structure.
Data := StrGet(StringAddress)
MsgBox Received the following string: %Data%
}
正在接收消息,但这是输出:
应该是:Hello World
.
我还在 SendMessage
之后检查了 GetLastError()
,它输出 0
。
我一定是在 COPYDATASTRUCT
里面做错了什么。
AutoHotkey x64.
你对StrGet()
的使用是错误的:
您没有在发送的数据中包含
std::string
的空终止符,但您没有将COPYDATASTRUCT::cbData
字段的值传递给StrGet()
,因此它将寻找一个不存在的空终止符。所以你需要在COPYDATASTRUCT::cbData
字段中指定长度,例如:StringLen := NumGet(lParam + A_PtrSize, "int"); StringAddress := NumGet(lParam + 2*A_PtrSize); Data := StrGet(StringAddress, StringLen, Encoding);
更重要的是,您没有为
StrGet()
指定Encoding
,因此它将以脚本的本机编码解释原始数据(请参阅A_IsUnicode
)。不要那样做。明确 C++ 代码使用的编码。如果std::string
包含 UTF-8 字符串,请指定"UTF-8"
。如果std::string
包含用户默认 ANSI 语言环境中的字符串,请指定"CP0"
。等等。您所看到的情况通常称为 Mojibake,当单字节字符数据在错误的编码中被错误解释时会发生这种情况。