Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate
Photo

Sending Strings Via SendMessage


  • Please log in to reply
8 replies to this topic
Ripture
  • Members
  • 17 posts
  • Last active: Jun 07 2014 07:23 AM
  • Joined: 19 Aug 2013

Hello,

 

I've been trying to see if there is a way to send a string through w/lParam to another script using Post/SendMessage and OnMessage.  The manual page for PostMessage states that "a string may be sent via wParam or lParam by specifying the address of a variable" but doesn't go into much detail about retrieving the string.  If I send a string either by directly typing it in the command or sending a variable by reference, the receiving script just sees a number 8 or 9 digits long.  Is this supposed to be a memory address?  If so, how do I retrieve the string at that location?

 

I know the manual page for OnMessage has an example of sending a string utilizing WM_COPYDATA or some such but it feels kind of messy to me.  Is this the only way to send a string from one script to another?  Why can't I just send a string simply through wParam of PostMessage like the manual page outlines?

 

Thanks.



Leef_me
  • Moderators
  • 8510 posts
  • Last active: Sep 10 2015 05:50 AM
  • Joined: 08 Apr 2009

Every thing you have written (with the exception of "...utilizing WM_COPYDATA ...seems messy") is true.

You appear to want something else to satisfy your "non-messy" requirement.

 

Each of your questions is answered by the helpfile references for SendMessage, PostMessage andOnMessage

For example:

 

>>Why can't I just send a string simply through wParam of PostMessage like the manual page outlines?

 

From PostMessage:

...

The parameters Msg, wParam, and lParam should all be integers between -2147483648 and 4294967295 (0xFFFFFFFF).

..

A string may be sent via wParam or lParam by specifying the address of a variable.

...

To have a script receive a message, use OnMessage().

...

 

 

An alternate method would be to create a control on a gui; then use commands such as GuiControl, GuiControlGet, ControlGetText and ControlSetText.



Ripture
  • Members
  • 17 posts
  • Last active: Jun 07 2014 07:23 AM
  • Joined: 19 Aug 2013

Thanks for your response.  As I said, I acknowledged the entry in PostMessage's manual page regarding being able to send strings through w/lParam but when I attempted this, I did not receive a string on the other end, I received a large integer.  Being that the manual page goes into no further detail about sending strings using the address through w/lParam, I assumed it to be a simple task and as such, and am even more confused as to what I am doing incorrectly.

 

The scripts I'm trying to send to are not designed to use a GUI so creating one just to try and finagle with controls and setting text would be equally undesirable.  Do you know what I might be doing incorrectly that when I send a string through w/lParam it turns into a large integer on the other side?



Leef_me
  • Moderators
  • 8510 posts
  • Last active: Sep 10 2015 05:50 AM
  • Joined: 08 Apr 2009

>>Being that the manual page goes into no further detail about sending strings using the address through w/lParam, ...

 

Did you see the working example in the OnMessge() documentation?

 

; Example: Send a string of any length from one script to another.  This is a working example.

 

Please notice that there are two scripts:   Receiver.ahk and Sender.ahk



Ripture
  • Members
  • 17 posts
  • Last active: Jun 07 2014 07:23 AM
  • Joined: 19 Aug 2013

Yeah I did see that, that's precisely the example that I'm referring to in the second part of my first post that I feel is kind of "hacky."  There's a bit of massaging you have to do to get it to function.  So are you saying that example is the only way it can be done?



Leef_me
  • Moderators
  • 8510 posts
  • Last active: Sep 10 2015 05:50 AM
  • Joined: 08 Apr 2009

It is the only way I have seen how to do it.

 

Let's flip the questioning around, why do you want to communicate a string of text between scripts?



szujeq
  • Members
  • 304 posts
  • Last active: Jan 12 2017 09:11 PM
  • Joined: 28 Mar 2011
Send_WM_COPYDATA(Hwnd, dwData, lpData="") {
; dwData = Command
; cbData = String lenght
; lpData = String
	static WM_COPYDATA := 0x4A
	VarSetCapacity(COPYDATASTRUCT, 3*A_PtrSize, 0)
		cbData := (StrLen(lpData) + 1) * (A_IsUnicode ? 2 : 1)
		NumPut(dwData,  COPYDATASTRUCT, 0*A_PtrSize)
		NumPut(cbData,  COPYDATASTRUCT, 1*A_PtrSize)
		NumPut(&lpData, COPYDATASTRUCT, 2*A_PtrSize)
	
	SendMessage, WM_COPYDATA, 0, &COPYDATASTRUCT,, ahk_id %Hwnd%
	return ErrorLevel == "FAIL" ? false : true
}

On_WM_COPYDATA(wParam, lParam, msg, hwnd) {
; dwData = Command
; cbData = String lenght
; lpData = String
	dwData := NumGet(lParam+0, 0)
	cbData := NumGet(lParam + A_PtrSize)
	lpData := NumGet(lParam + 2*A_PtrSize)
	lpData := StrGet(lpData)
	
	If  (dwData = 0x50000007) ; CMD_CURRENTPOSITION
	{
		For example if you Send:
                Send_WM_COPYDATA(Hwnd, 0x50000007, "Something")
                Then you receive here in lpData "something" String
	}
}

It is very important to use SenMessage instead of PostMessage because it send only pointer to string and if you use PostMessage then On_WM_COPYDATA way not be fast enought to read string. Also in On_WM_COPYDATA() you shouldn put anything time consumtions because it may freez program that send this message untill On_WM_COPYDATA() end. It wont freez if you use postmessage but if ur "send" program clear poiner/variable before On_WM_COPYDATA() read it then you do not receive properly string.



noname
  • Members
  • 650 posts
  • Last active:
  • Joined: 12 Nov 2011

An easy way is to use the "out of the box" functions that wraps the Onmessage by Avi   talk()

 

http://www.autohotke...e-updated-2707/


winXP  and ahk unicode


Ripture
  • Members
  • 17 posts
  • Last active: Jun 07 2014 07:23 AM
  • Joined: 19 Aug 2013

It is the only way I have seen how to do it.

 

Let's flip the questioning around, why do you want to communicate a string of text between scripts?

 

Well, essentially what I am building is a master script that will govern the behavior of slave scripts and I was attempting to make it somewhat modular and have the ability to attach additional slave scripts easily.  One piece of information that each slave script needs to keep track of on it's own is an identifier string.  So what I want to do is create the slave script within the master script and send it a message telling it what it's identifier is.  It would be ideal obviously if I could just send it the exact string and be done with it.  So far, I've compromised and done some if-else blocks within the master script and hard-coded the available identifiers and depending on which one it is, I send a different "msg" hex value to that slave script.  There is then logic on the slave script's side to decode that message back into a series of hard-coded identifiers.  

 

Honestly, this way would be sufficient to me in terms of end-function.  When I script, I tend to want to make things that are a bit slicker than I probably need and it usually ends up making things more difficult.

 

Thank you for the suggestions szujeq and noname.  That talk() class does look interesting and at first glance, it does seem to function similarly to that example on OnMessage's manual page.  I will keep that bookmarked in the event I decide I want or need that functionality but I think I've decided for simplicity's sake I will stick to hard-coding things.