Help with using ahk id with win messages

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
User avatar
dangerdogL2121
Posts: 173
Joined: 01 Oct 2013, 23:11

Help with using ahk id with win messages

24 May 2014, 00:46

I have two scripts

exam1:

Code: Select all

hwnd := WinExist("Ahk_PID " DllCall("GetCurrentProcessId"))
OnMessage(0x919191, "returnfunct")
Run, %A_ScriptDir%\exam2.ahk %hwnd%
return



returnfunct()
{
msgbox, returned
}
return
exam2:

Code: Select all

if 1 =
msgbox, Error
PostMessage, 0x919191, , , , ahk_id %1%
ExitApp
exam1 is supposed to run exam2 which sends a win message to fire a message box in exam1. Right now though, it isn't working.

I'm guessing the problem is that I'm using a unique ID for the postmessage in exam2. Can unique IDs even be used in this sort of situation?
thanks
User avatar
trismarck
Posts: 506
Joined: 30 Sep 2013, 01:48
Location: Poland

Re: Help with using ahk id with win messages

24 May 2014, 05:21

  • the default Autohotkey window is a hidden window, so DetectHiddenWindows is required in exam1.ahk for WinExist() and in exam2.ahk for PostMessage
  • the message number is invalid. Use the WM_COPYDATA message instead
User avatar
Menixator
Posts: 69
Joined: 30 Sep 2013, 04:10

Re: Help with using ahk id with win messages

24 May 2014, 13:49

Here is an example(taken from the documentation) on how to use the WM_COPYDATA message:

Save this as Receiver.ahk:

Code: Select all

; Example: Send a string of any length from one script to another.  This is a working example.
; To use it, save and run both of the following scripts then press Win+Space to show an
; InputBox that will prompt you to type in a string.

; Save the following script as "Receiver.ahk" then launch it:
#SingleInstance
OnMessage(0x4a, "Receive_WM_COPYDATA")  ; 0x4a is WM_COPYDATA
return

Receive_WM_COPYDATA(wParam, lParam)
{
    StringAddress := NumGet(lParam + 2*A_PtrSize)  ; Retrieves the CopyDataStruct's lpData member.
    CopyOfData := StrGet(StringAddress)  ; Copy the string out of the structure.
    ; Show it with ToolTip vs. MsgBox so we can return in a timely fashion:
    ToolTip %A_ScriptName%`nReceived the following string:`n%CopyOfData%
    return true  ; Returning 1 (true) is the traditional way to acknowledge this message.
}
Save this as Sender.ahk:

Code: Select all

; Save the following script as "Sender.ahk" then launch it.  After that, press the Win+Space hotkey.
TargetScriptTitle = Receiver.ahk ahk_class AutoHotkey

#space::  ; Win+Space hotkey. Press it to show an InputBox for entry of a message string.
InputBox, StringToSend, Send text via WM_COPYDATA, Enter some text to Send:
if ErrorLevel  ; User pressed the Cancel button.
    return
result := Send_WM_COPYDATA(StringToSend, TargetScriptTitle)
if result = FAIL
    MsgBox SendMessage failed. Does the following WinTitle exist?:`n%TargetScriptTitle%
else if result = 0
    MsgBox Message sent but the target window responded with 0, which may mean it ignored it.
return

Send_WM_COPYDATA(ByRef StringToSend, ByRef TargetScriptTitle)  ; ByRef saves a little memory in this case.
; This function sends the specified string to the specified window and returns the reply.
; The reply is 1 if the target window processed the message, or 0 if it ignored it.
{
    VarSetCapacity(CopyDataStruct, 3*A_PtrSize, 0)  ; Set up the structure's memory area.
    ; First set the structure's cbData member to the size of the string, including its zero terminator:
    SizeInBytes := (StrLen(StringToSend) + 1) * (A_IsUnicode ? 2 : 1)
    NumPut(SizeInBytes, CopyDataStruct, A_PtrSize)  ; OS requires that this be done.
    NumPut(&StringToSend, CopyDataStruct, 2*A_PtrSize)  ; Set lpData to point to the string itself.
    Prev_DetectHiddenWindows := A_DetectHiddenWindows
    Prev_TitleMatchMode := A_TitleMatchMode
    DetectHiddenWindows On
    SetTitleMatchMode 2
    SendMessage, 0x4a, 0, &CopyDataStruct,, %TargetScriptTitle%  ; 0x4a is WM_COPYDATA. Must use Send not Post.
    DetectHiddenWindows %Prev_DetectHiddenWindows%  ; Restore original setting for the caller.
    SetTitleMatchMode %Prev_TitleMatchMode%         ; Same.
    return ErrorLevel  ; Return SendMessage's reply back to our caller.
}
User avatar
dangerdogL2121
Posts: 173
Joined: 01 Oct 2013, 23:11

Re: Help with using ahk id with win messages

24 May 2014, 23:25

@trismark
I added DetectHiddenWindows, On to exam 1 and exam 2.
I don't see what's wrong with 0x919191 but I changed it to 0x4a and returnfunct to WM_COPYDATA.
I also added #Persistent to exam 1 too.

@Menixator
The example worked!
However, I tried making some modifications to sender and receiver and it didn't work.

Sender2:

Code: Select all

; Save the following script as "Sender.ahk" then launch it.  After that, press the Win+Space hotkey.
TargetScriptTitle = Receiver2.ahk ahk_class AutoHotkey

#space::  ; Win+Space hotkey. Press it to show an InputBox for entry of a message string.
InputBox, StringToSend, Send text via WM_COPYDATA, Enter some text to Send:
if ErrorLevel  ; User pressed the Cancel button.
    return
    PostMessage, 0x99999, 0, %StringToSend%,, %TargetScriptTitle%
;ALL LINES BELOW ARE COMMENTED
;result := Send_WM_COPYDATA(StringToSend, TargetScriptTitle)
;if result = FAIL
 ;   MsgBox SendMessage failed. Does the following WinTitle exist?:`n%TargetScriptTitle%
;else if result = 0
   ; MsgBox Message sent but the target window responded with 0, which may mean it ignored it.
;return

Send_WM_COPYDATA(ByRef StringToSend, ByRef TargetScriptTitle)  ; ByRef saves a little memory in this case.
; This function sends the specified string to the specified window and returns the reply.
; The reply is 1 if the target window processed the message, or 0 if it ignored it.
{
 ;   VarSetCapacity(CopyDataStruct, 3*A_PtrSize, 0)  ; Set up the structure's memory area.
    ; First set the structure's cbData member to the size of the string, including its zero terminator:
 ;   SizeInBytes := (StrLen(StringToSend) + 1) * (A_IsUnicode ? 2 : 1)
;    NumPut(SizeInBytes, CopyDataStruct, A_PtrSize)  ; OS requires that this be done.
 ;   NumPut(&StringToSend, CopyDataStruct, 2*A_PtrSize)  ; Set lpData to point to the string itself.
 ;   Prev_DetectHiddenWindows := A_DetectHiddenWindows
 ;   Prev_TitleMatchMode := A_TitleMatchMode
    DetectHiddenWindows On
    SetTitleMatchMode 2
    PostMessage, 0x99999, 0, %StringToSend%,, %TargetScriptTitle%  ; 0x4a is WM_COPYDATA. Must use Send not Post.
;    DetectHiddenWindows %Prev_DetectHiddenWindows%  ; Restore original setting for the caller.
  ;  SetTitleMatchMode %Prev_TitleMatchMode%         ; Same.
  ;  return ErrorLevel  ; Return SendMessage's reply back to our caller.
}
Receiver2:

Code: Select all

; Save the following script as "Receiver2.ahk" then launch it:
#SingleInstance
OnMessage(0x99999, "Receive")
return

Receive(wParam, lParam)
{
    ToolTip %A_ScriptName%`nReceived the following string:`n%lParam%
}
thanks
User avatar
Menixator
Posts: 69
Joined: 30 Sep 2013, 04:10

Re: Help with using ahk id with win messages

25 May 2014, 03:15

If you want to send messages between scripts, WM_COPYDATA is the best way to go.
But if you want a custom message:

Code: Select all

;Reciever.ahk
#Persistent
messageNumber := 0x13c4

OnMessage(messageNumber, "Recieve")
return

Recieve(wParam, lParam, Msg){
	MsgBox wParam: %wParam%`nlParam: %lParam%`nMsg: %Msg%
}

Code: Select all

;Sender.ahk
DetectHiddenWindows, On
messageNumber := 0x13c4 ;5060
wParam := 20
lParam := 30

SetTitleMatchMode, 2
PostMessage, %messageNumber%,%wParam%,%lParam%,,% "ahk_id " . WinExist("Reciever.ahk ahk_class AutoHotkey")
User avatar
trismarck
Posts: 506
Joined: 30 Sep 2013, 01:48
Location: Poland

Re: Help with using ahk id with win messages

25 May 2014, 04:40

dangerdogL2121 wrote:I don't see what's wrong with 0x919191
The information of why that message was invalid was under the link in my post (as a subpage of the page in the link):
MSDN wrote:The following are the ranges of message numbers.
...
Greater than 0xFFFF
Reserved by the system.
dangerdogL2121 wrote:but I changed it to 0x4a and returnfunct to WM_COPYDATA.
If you've changed the line with OnMessage() to:

Code: Select all

OnMessage(WM_COPYDATA, "returnfunct")
then it will still fail, because the variable WM_COPYDATA has no value.

The example was tested before posting and it worked after applying the modifications mentioned.

Also, instead of:

Code: Select all

hwnd := WinExist("Ahk_PID " DllCall("GetCurrentProcessId"))
A_ScriptHwnd could have been used.
User avatar
dangerdogL2121
Posts: 173
Joined: 01 Oct 2013, 23:11

Re: Help with using ahk id with win messages

26 May 2014, 13:16

I never realized till now that things like 0x13c4 were hexidecimal numbers and that their letters mean numbers. And I now see that it talks about hexidecimal value in the postmessage docs. So 0x13c4 means 5060 when converted from hexidecimal to normal? That is from this line

Code: Select all

messageNumber := 0x13c4
in menixator's receiver script.

I couldn't get Menixator's most recent sender and receiver to work, no message box appears. I run receiver and then sender like supposed to but nothing happens. If it was supposed to work, maybe somethings wrong with my computer.

MSDN wrote:
The following are the ranges of message numbers.
...
Greater than 0xFFFF
Reserved by the system.
I didn't see that in the MSDN page.
User avatar
trismarck
Posts: 506
Joined: 30 Sep 2013, 01:48
Location: Poland

Re: Help with using ahk id with win messages

26 May 2014, 16:12

dangerdogL2121 wrote:So 0x13c4 means 5060 when converted from hexidecimal to normal?
Yes, from hexadecimal (base-16) to decimal (base-10).

0x13c4 = 0x1000 + 0x0300 + 0x00C0 + 0x0004 = (convert to decimal) = 1000*16^3 + 300*16^2 + 12*16^1 + 4*16^0 = 0x1*0x10^0x03 + 0x3*0x10^0x02 + 0xC*0x10^0x01 + 0x4*0x10^0x00 = (hex to dec) = 1*16^3 + 3*16^2 + 12*16^1 + 4*16^0 = 5060
dangerdogL2121 wrote:
MSDN wrote:
The following are the ranges of message numbers.
...
Greater than 0xFFFF
Reserved by the system.
I didn't see that in the MSDN page.
MSDN-PostMessage wrote:Remarks

[...]

The system only does marshalling for system messages (those in the range 0 to (WM_USER-1)). To send other messages (those >= WM_USER) to another process, you must do custom marshalling.
WM_USER was a hyperlink.
Last edited by trismarck on 26 May 2014, 18:28, edited 1 time in total.
User avatar
Menixator
Posts: 69
Joined: 30 Sep 2013, 04:10

Re: Help with using ahk id with win messages

26 May 2014, 16:17

dangerdogL2121 wrote:I didn't see that in the MSDN page.
It's in the ahk documentation: link
User avatar
dangerdogL2121
Posts: 173
Joined: 01 Oct 2013, 23:11

Re: Help with using ahk id with win messages

27 May 2014, 02:45

dangerdogL2121 wrote:
So 0x13c4 means 5060 when converted from hexidecimal to normal?
Yes, from hexadecimal (base-16) to decimal (base-10).

0x13c4 = 0x1000 + 0x0300 + 0x00C0 + 0x0004 = (convert to decimal) = 1000*16^3 + 300*16^2 + 12*16^1 + 4*16^0 = 0x1*0x10^0x03 + 0x3*0x10^0x02 + 0xC*0x10^0x01 + 0x4*0x10^0x00 = (hex to dec) = 1*16^3 + 3*16^2 + 12*16^1 + 4*16^0 = 5060
Cool! Thats good to know. And even cooler, I figured out the math there, at least some of it.
WM_USER was a hyperlink.
Ok, I see it now.

It's in the ahk documentation: link
It looks to me like theres something that says the opposite of anything above 0xFFFF being reserved for the system.
PostMessage Docs:
MsgNumber
The number of the message to monitor or query, which should be between 0 and 4294967295 (0xFFFFFFFF). If you do not wish to monitor a system message (that is, one below 0x400), it is best to choose a number greater than 4096 (0x1000) to the extent you have a choice. This reduces the chance of interfering with messages used internally by current and future versions of AutoHotkey.
So I thought that 0x919191 was ok.
thanks
User avatar
trismarck
Posts: 506
Joined: 30 Sep 2013, 01:48
Location: Poland

Re: Help with using ahk id with win messages

27 May 2014, 04:28

Note that the quote is from the documentation of OnMessage(), not from PostMessage.

I guess Lexikos would say that the documentation is correct? Although message numbers >0xFFFF are reserved by the system, that doesn't mean that (in theory) a given message _can't_ have the number greater than 0xFFFF. Msg is declared as UInt. OTOH it is probably declared this way only for byte-alignment/reserved for future use purposes.

Perhaps [a link to] the ranges of message identifiers, as of in current implementation of Windows, could be added to the documentation of OnMessage / PostMessage.

As of whether Windows actually even uses message numbers higher than 0xFFFF, I guess it's not documented.
User avatar
dangerdogL2121
Posts: 173
Joined: 01 Oct 2013, 23:11

Re: Help with using ahk id with win messages

27 May 2014, 18:40


Note that the quote is from the documentation of OnMessage(), not from PostMessage.

I guess Lexikos would say that the documentation is correct? Although message numbers >0xFFFF are reserved by the system, that doesn't mean that (in theory) a given message _can't_ have the number greater than 0xFFFF. Msg is declared as UInt. OTOH it is probably declared this way only for byte-alignment/reserved for future use purposes.

Perhaps [a link to] the ranges of message identifiers, as of in current implementation of Windows, could be added to the documentation of OnMessage / PostMessage.

As of whether Windows actually even uses message numbers higher than 0xFFFF, I guess it's not documented.
Aha, so it wasn't just me.

Also, I got Menixator's previous script to work by switching

Code: Select all

PostMessage, %messageNumber%,%wParam%,%lParam%,, % "ahk_id " . WinExist("Reciever.ahk ahk_class AutoHotkey")
in sender with

Code: Select all

PostMessage, %messageNumber%,%wParam%,%lParam%,, Receiver.ahk ahk_class AutoHotkey
After a little testing I found that WinExist is returning 0x0, meaning no window is found. I don't know why that is though, receiver is running.
thanks
User avatar
trismarck
Posts: 506
Joined: 30 Sep 2013, 01:48
Location: Poland

Re: Help with using ahk id with win messages

28 May 2014, 03:08

Reciever.
User avatar
dangerdogL2121
Posts: 173
Joined: 01 Oct 2013, 23:11

Re: Help with using ahk id with win messages

28 May 2014, 19:41

Reciever.
Great catch! :D It works now.

That sort of sums up my questions about winmessage. Hopefully, someone else who needs help with winmessages will find this thread and it will be useful to them.
Thank you trismark and Menixator for your help

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: Rohwedder, ruespe and 360 guests