Hi
@teadrinker
Your reply kept me digging into
WM_COPYDATA and I managed to pinpoint the issue. The problem was that I based by CopyDataStructure on the code from 32-bit VBA shown in the link from my first post. However, while analyzing the pointer math:
Code: Select all
CopyDataStruct := Buffer(3*A_PtrSize)
This line made me hear a bell ringing: data structure's size should be of three pointers. Mine was initially two times Long (2 * 4 bytes) and then one pointer (8 byte). After changing the structure, everything worked fine.
The code for 64-bit VBA, for posterity:
AHK (script runs at startup, saves its handle into file to be accessed by VBA):
Code: Select all
DetectHiddenWindows, on
ThisScriptsHWND := WinExist("Ahk_PID " DllCall("GetCurrentProcessId"))
hWndNum := ThisScriptsHWND+0
file := FileOpen("C:\Scripts\AHK\Test\hwnd.txt", "w")
file.Write(hWndNum)
file.Close()
OnMessage(0x4a, "Receive_WM_COPYDATA")
Receive_WM_COPYDATA(wParam, lParam)
{
StringAddress := NumGet(lParam + 2*A_PtrSize) ; lParam in this context is an address of the CopyDataStructure, we are jumping to the address two pointers further, which contains lpData member - a String pointer
CopyOfData := StrGet(StringAddress) ; Copy the string out of the structure.
msgbox, %CopyOfData%
return true ; Returning 1 (true) is the traditional way to acknowledge this message.
}
VBA:
Code: Select all
Private Declare PtrSafe Function SendMessage Lib "user32" Alias "SendMessageA" _
(ByVal hwnd As LongPtr, ByVal wMsg As Long, ByVal wParam As LongPtr, lParam As Any) As LongPtr
Const WM_COPYDATA = &H4A
Const LNULL = 0&
Type COPYDATASTRUCT
dwData As LongPtr
cbData As LongPtr
lpData As LongPtr
End Type
Sub Main()
Dim fso As FileSystemObject
Set fso = New FileSystemObject
Dim ts As Scripting.TextStream
Set ts = fso.OpenTextFile("C:\Scripts\AHK\Test\hwnd.txt", ForReading)
Dim sLine As String
sLine = ts.ReadLine
ts.Close
Dim hwnd As LongPtr
hwnd = CLngPtr(sLine)
Dim sendStr As String
sendStr = "test message"
Dim sendPtr As LongPtr
sendPtr = StrPtr(sendStr)
Dim cds As COPYDATASTRUCT
cds.dwData = 0
cds.cbData = (Len(sendStr) + 1) * 2
cds.lpData = StrPtr(sendStr)
Dim lReturn As LongPtr
lReturn = SendMessage(hwnd, WM_COPYDATA, LNULL, cds)
End Sub
Thanks!