Reputation:
Trying to SendMessage with WM_COPYDATA
from a C++ application to an AutoHotkey script.
I tried to follow the example found in the docs:
https://learn.microsoft.com/en-us/windows/win32/dataxchg/using-data-copy
Then I did:
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);
And in the Autohotkey script:
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%
}
The message is being received, but this is the output:
When it should be: Hello World
.
I have also checked for GetLastError()
after the SendMessage
and it output 0
.
I must be doing something wrong inside of the COPYDATASTRUCT
.
AutoHotkey x64.
Upvotes: 3
Views: 411
Reputation: 596287
Your use of StrGet()
is wrong:
You are not including the std::string
's null terminator in the sent data, but you are not passing the value of the COPYDATASTRUCT::cbData
field to StrGet()
, so it is going to be looking for a null terminator that does not exist. So you need to specify the length that is in the COPYDATASTRUCT::cbData
field, eg:
StringLen := NumGet(lParam + A_PtrSize, "int");
StringAddress := NumGet(lParam + 2*A_PtrSize);
Data := StrGet(StringAddress, StringLen, Encoding);
More importantly, you are not specifying an Encoding
for StrGet()
, so it is going to interpret the raw data in whatever the native encoding of the script is (see A_IsUnicode
). Don't do that. Be explicit about the encoding used by the C++ code. If the std::string
holds a UTF-8 string, specify "UTF-8"
. If the std::string
holds a string in the user's default ANSI locale, specify "CP0"
. And so on. What you are seeing happen is commonly known as Mojibake, which happens when single-byte character data is mis-interpreted in the wrong encoding.
Upvotes: 2