Page 1 of 1

reading a xy variable from ahk/au3?

Posted: 25 Nov 2013 16:06
by autocart
Hi,
I would like to read a build in xy variable from an ahk or au3 script.
Messenger (http://www.xyplorer.com/xyfc/viewtopic. ... ger#p89555) is nice but I would like to have the information flow from XY to my script (but still calling it from my external script).

Of course I could tell XY to write it to a text file and then read that one out. But is there a better and easy way to do that?
Thx in advance, Stephan

Re: reading a xy variable from ahk/au3?

Posted: 25 Nov 2013 16:27
by binocular222
You mean which one?
1) Run an AHK script > AHK send a request to XY > XY response to AHK
2) Run XYS script > Pass info to a running AHK script?

The 1st one is already possible in Part 2 in my post http://www.xyplorer.com/xyfc/viewtopic. ... ger#p89555

the 2nd one is even easier than the 1st

Re: reading a xy variable from ahk/au3?

Posted: 25 Nov 2013 17:43
by autocart
hey binocular,
thx that's exactly what I meant :beer: :appl: (sorry, should have read it more before)
but now you made me curious...
how would you do the 2nd?

Re: reading a xy variable from ahk/au3?

Posted: 25 Nov 2013 17:55
by binocular222
Take the 1) code, remove the "AHK send request to XY" portion, then it comes like this:

Code: Select all

#notrayicon

OnMessage(0x4a, "Function_Receive_WM_COPYDATA")  ; 0x4a is WM_COPYDATA. This onhold and wait for the WM_Copydata from XYplorer then execute Function_Receive_WM_COPYDATA(wParam, lParam) below

Function_Receive_WM_COPYDATA(wParam, lParam)
{
  StringAddress := NumGet(lParam + 2*A_PtrSize) ;lParam+8 is the address of CopyDataStruct's lpData member.
  CopyOfData := StrGet(StringAddress)    ;May also specify CP0 (default) or UTF-8 or UTF-16:   StrGet(StringAddress, NumGet(lParam+A_PtrSize), "UTF-16")
  cbData := NumGet(lParam+A_PtrSize)/2  ;cbData/2 = String length
  StringLeft, Datareceived, CopyOfData, cbData
  msgbox, <curitem> is `n %Datareceived%
  exitapp
}
so the XYS can be like this:

Code: Select all

::CopyData 7409230, "<curitem>",2
7409230 is just an example of AHK's HWND (in Dec instead of Hex)

Re: reading a xy variable from ahk/au3?

Posted: 25 Nov 2013 18:04
by autocart
All righty, thx again,
To make it dynamic the ahk script could write its own HWND into a xy variable, from where the xyscript could read it, right?
Now a probably stupid question: What do i do if my ahk script does not have an HWND? Or do even ahk scripts w/o window still have an HWND?

Re: reading a xy variable from ahk/au3?

Posted: 25 Nov 2013 18:13
by binocular222
Every running AHK script (even GUIless) has a HWND:
a built-in variable: %A_ScriptHwnd% store the script's HWND (in Hex)
To convert to Dec:
SenderHWND := A_ScriptHwnd + 0

Re: reading a xy variable from ahk/au3?

Posted: 25 Nov 2013 18:17
by autocart
Thank you, Binocular!!! :biggrin: :) :D

Re: reading a xy variable from ahk/au3?

Posted: 26 Nov 2013 08:00
by autocart
So, this is my code, for anyone to use AT OWN RISK, and for anyone to make suggestions for improvement:

The ahk-help file says about SendMessage: "SendMessage waits for the target window to process the message, up until the timeout period expires." Also the XYp-help says about copydata: "The command only returns when the receiving window has fully processed the data. For example if you send a script the command will return only after the script has terminated." Therefore is should be safe to think of it as syncronious execution (always in the same order), right? (as long as there is no timeout)

Also, I wanted to make it coding-friendly and therefore use a global variable to pass the result to the calling/sending function, so that this function can be used in a totally normal way. I know the global var is not the best but I can't think of a better way and in a small script (were you can keep the overview) it should be ok, right? I know that the first definition of the global var is technically not needed but I put it there for better overview.

For any newbies: exitapp is needed because otherwise ahk would keep the script running as a side effect of the OnMessage-function.

BTW, XYplorer MUST already be running, otherwise the "return value" will be an empty string.

Code: Select all

global XYRETURN

xydata := GetVarFromXYplorer("<xydata>")
msgbox % xydata
exitapp

;***************************************************************************************
;** code from others (or based on) **
;***************************************************************************************

;heavily based on
;http://www.xyplorer.com/xyfc/viewtopic.php?f=7&t=9233&p=89555&hilit=messenger#p89555

    GetVarFromXYplorer(varName)          ;Send message to XYplorer
    {
      global XYRETURN
      SenderHWND := A_ScriptHwnd + 0  ;Return this script's hidden hwdn id.  +0 to convert from Hex to Dec
      MessagetoXYplorer := "::CopyData " SenderHWND ", """ varName """, 2"    ;resolved to sth like this:   ::CopyData 7409230, "<curitem>", 2
      SetTitleMatchMode, 2
      HWND := WinExist("XYplorer ahk_class ThunderRT6FormDC")
      Size := StrLen(MessagetoXYplorer)
      If !(A_IsUnicode)
      {
      VarSetCapacity(Data, Size * 2, 0)
      StrPut(MessagetoXYplorer, &Data, Size, "UTF-16")
      }
      Else
      Data := MessagetoXYplorer

      VarSetCapacity(COPYDATA, A_PtrSize * 3, 0)
      NumPut(4194305, COPYDATA, 0, "Ptr")
      NumPut(Size * 2, COPYDATA, A_PtrSize, "UInt")
      NumPut(&Data, COPYDATA, A_PtrSize * 2, "Ptr")
      OnMessage(0x4a, "Function_Receive_WM_COPYDATA")  ; 0x4a is WM_COPYDATA. This onhold and wait for the WM_Copydata from XYplorer then execute Function_Receive_WM_COPYDATA(wParam, lParam) below
      SendMessage, 0x4a, 0, &COPYDATA, , ahk_id %HWND% ;SendMessage waits for the target window to process the message, up until the timeout period expires.
      OnMessage(0x4a, "")
      return XYRETURN
    }

    Function_Receive_WM_COPYDATA(wParam, lParam)
    {
      global XYRETURN
      StringAddress := NumGet(lParam + 2*A_PtrSize) ;lParam+8 is the address of CopyDataStruct's lpData member.
      CopyOfData := StrGet(StringAddress)    ;May also specify CP0 (default) or UTF-8 or UTF-16:   StrGet(StringAddress, NumGet(lParam+A_PtrSize), "UTF-16")
      cbData := NumGet(lParam+A_PtrSize)/2  ;cbData/2 = String length
      StringLeft, Datareceived, CopyOfData, cbData
      XYRETURN := Datareceived
    }