StrGet - problem with pointer received from VBA StrPtr()

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
hwnd_ahk
Posts: 6
Joined: 13 Jan 2023, 16:52

StrGet - problem with pointer received from VBA StrPtr()

Post by hwnd_ahk » 13 Jan 2023, 17:32

Hi Everyone,

I am trying to send a string value from x64 VBA to AHK script acting as a listener.

In AHK I have very basic script, just for testing:

Code: Select all

OnMessage(5000, "POPUP")

POPUP(wParam, lParam){
	msgbox, StrPtr: %wParam%
	msg := StrGet(wParam)
	msgbox, message: %msg%
}
In VBA, I am using WinAPI to post a message to AHK window:

Code: Select all

    Dim sendStr As String
    sendStr = "test message" & vbNullChar

    Dim sendPtr As LongPtr
    sendPtr = StrPtr(sendStr)

    Call PostMessage(hwnd, 5000, sendPtr, 0&)
hwnd from the VBA code is the handle to the hidden window of AHK script in question. The message seems to be received correctly, because the first Message Box displays the pointer address, but the script fails during StrGet method. I think that the cause for this issue might be the fact, that my 64-bit VBA generates much longer address value (signed 8-byte number), than the StrGet expects (it seems to work fine for 32-bit VBA, where the address is 4-byte long). Any ideas how to overcome this? Maybe I am doing something wrong?

I have also tried the approach presented here:
https://www.autohotkey.com/board/topic/102577-excel-sendmessage-wm-copydata-to-ahk-script/
But I have the same issue. StrPtr() in my VBA returns the 8-byte LongPtr type value, not 4-byte Long and I am getting Type Mismatch errors.
teadrinker
Posts: 4412
Joined: 29 Mar 2015, 09:41
Contact:

Re: StrGet - problem with pointer received from VBA StrPtr()

Post by teadrinker » 13 Jan 2023, 18:25

Hi
Each application has its own address space. An address from one application doesn't make sence in another. Use WM_COPYDATA to exchange data.
hwnd_ahk
Posts: 6
Joined: 13 Jan 2023, 16:52

Re: StrGet - problem with pointer received from VBA StrPtr()

Post by hwnd_ahk » 13 Jan 2023, 19:21

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!
teadrinker
Posts: 4412
Joined: 29 Mar 2015, 09:41
Contact:

Re: StrGet - problem with pointer received from VBA StrPtr()

Post by teadrinker » 13 Jan 2023, 19:33

Of course, the AHK script must be 64 bit, otherwise you will run into problems, albeit solvable.
crypter
Posts: 90
Joined: 15 Dec 2020, 09:57

Re: StrGet - problem with pointer received from VBA StrPtr()

Post by crypter » 13 Jan 2023, 21:07

Here is an example of how you can send a string value from a 64-bit VBA script to an AutoHotkey script using the SendMessage function with COPYDATASTRUCT:

AHK script:

Code: Select all

OnMessage(WM_COPYDATA, "POPUP")

POPUP(wParam, lParam) {
    cds := *(COPYDATASTRUCT*)lParam
    msg := DllCall("RtlMoveMemory", "Ptr", &msg, "Ptr", cds.lpData, "UInt", cds.cbData)
    msgbox, message: %msg%
}
VBA script:

Code: Select all

Dim sendStr As String
sendStr = "test message"

Dim cds As COPYDATASTRUCT
cds.dwData = 0
cds.cbData = Len(sendStr)
cds.lpData = StrPtr(sendStr)

Call SendMessage(hwnd, WM_COPYDATA, 0, VarPtr(cds))
Make sure to add the following declarations to your VBA code:

Code: Select all

Private Type COPYDATASTRUCT
    dwData As Long
    cbData As Long
    lpData As LongPtr
End Type
Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long

Note that WM_COPYDATA is a message that allows you to send and receive data of any type in a simple and efficient way, without the need to use pointers, which can be tricky when working with 64-bit processes. Also, make sure that in VBA hwnd is the handle to the hidden window of AHK script in question.
hwnd_ahk
Posts: 6
Joined: 13 Jan 2023, 16:52

Re: StrGet - problem with pointer received from VBA StrPtr()

Post by hwnd_ahk » 14 Jan 2023, 05:13

crypter wrote:
13 Jan 2023, 21:07
Here is an example of how you can send a string value from a 64-bit VBA script to an AutoHotkey script using the SendMessage function with COPYDATASTRUCT:
(...)
Are you sure? It doesn't work for me. Even the line

Code: Select all

Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
throws compilation error, because it is not 64-bit declaration.

I have added PtrSafe modifier for it to work, added definitions of WM_COPYDATA constant in both VBA and AHK and the message is being sent and received, but msgbox displays some number, not a string.
I do not think I fully grasp what the line

Code: Select all

cds := *(COPYDATASTRUCT*)lParam
is supposed to do. I assume that lParam is a pointer from VBA; we are trying for 'cds' to get the data that the pointer points to, and we are also casting (? I am not even sure if this is the syntax for casting in AHK) COPYDATASTRUCT pointer on it? But what is COPYDATASTRUCT here? It hasn't been defined anywhere... Sheesh, I am confused.
User avatar
boiler
Posts: 17404
Joined: 21 Dec 2014, 02:44

Re: StrGet - problem with pointer received from VBA StrPtr()

Post by boiler » 14 Jan 2023, 07:40

hwnd_ahk wrote: Are you sure? It doesn't work for me. Even the line...throws compilation error, because it is not 64-bit declaration.

...But what is COPYDATASTRUCT here? It hasn't been defined anywhere... Sheesh, I am confused.
It appears likely that those scripts are not necessarily working or were tested but are the output of an AI bot which is notoriously bad a producing code.

@crypter - Can you describe how you came up with those scripts? Did you test them? Do you understand the code yourself? It looks like you have posted ChatGPT-generated code several times now. Please stop doing so. Its output is very often wrong and even nonsensical, with made-up syntax. It won't be hard to spot if you continue posting it. It wastes people's time to take it at face value and try to use and/or fix it, as was the case here.
User avatar
boiler
Posts: 17404
Joined: 21 Dec 2014, 02:44

Re: StrGet - problem with pointer received from VBA StrPtr()

Post by boiler » 15 Jan 2023, 07:47

@crypter - Since you’ve been back on the forum and have not replied to my post, I’ll take that as an admission of using ChatGPT and will add an official warning to your account so the moderators have a flag to pay attention to further posts, as will be done with other accounts posting ChatGPT content, especially without representing it as such.
Post Reply

Return to “Ask for Help (v1)”