Intro guide: Use AutoHotkey to send Windows messages

Not everyone will want to either install or learn AutoHotkey, but I hope this will be useful anyway.

N.B.: This post assumes you’ve got AutoHotkey installed and all your permissions are correct.

Robin can grab the ‘WindowHandle’ of an application started with ‘System.RunDOSCommand’. There are lots of things you can do with that handle if you’re willing to jump through a few hoops.

AutoHotkey is a program I like to use for lots of automation tasks. I’m using it here to send a WM_SETTEXT message (please see the code for links). It changes to the title of Notepad to text I’ve determined in advance.

Here’s a screenshot of the code, formatted a little differently than I usually prefer (I notice I’ve been running out of horizontal screen real estate :grinning:):

Code:

System.GetEnvironmentVariable \
    Name: 'USERNAME' \
    Value=> UserName

System.RunApplicationAndWaitToLoad              \
    ApplicationPath: \
"C:\Windows\notepad.exe" \
    CommandLineArguments:'' \
    WorkingDirectory:'' \
    WindowStyle:System.ProcessWindowStyle.Normal \
    Timeout:0 \
    ProcessId=> ProcessId \
    WindowHandle=> NotepadWindowHandle

# We'll use the WindowHandle to send a Windows Message
# This link may be useful: https://wiki.winehq.org/List_Of_Windows_Messages
# and this one will as well: https://www.autohotkey.com/docs/misc/SendMessage.htm
# and this one: https://www.autohotkey.com/docs/misc/SendMessageList.htm

wait 0.5


# This requires AutoHotkey be installed on your system


System.RunDOSCommand \
    DOSCommandOrApplication:  \
"AutoHotkey.exe C:\Users\\" + UserName + "\Documents\Robin\9.2\AHK\sending5.AHK " \
+ NotepadWindowHandle\
    WorkingDirectory:'' \
    StandardOutput=> StandardOutput \
    StandardError=> StandardError \
    ExitCode=> ExitCode

# Just for debugging, to compare the decimal
# Robin'WindowHandle' to the
# hex format reuired by AutoHotkey
# for sending Windows messages.

Display.ShowMessage \
    Title:'' \
    Message:NotepadWindowHandle \
    Icon:Display.Icon.None \
    Buttons:Display.Buttons.OK \
    DefaultButton:Display.DefaultButton.Button1 \
    IsTopMost:False \
    ButtonPressed=> ButtonPressed

Here’s my AHK script, ‘sending5.AHK’. It needs to be in the directory specified in the Robin script.

a = %1% ; %0% is number of arguments, %1% is first arg, etc.
; The argument will be the 'NotepadWindowHandle' from our
; Robin script.

hwnd := Format("{:#x}", a) ; Format Robin WindowHandle as hex
; Why not use %1% directly? Quirk of Format() function.

;msgbox %hwnd% ; Use for debugging
WinWait ahk_exe notepad.exe ; Wait for a notepad window to exist

Sleep 200 ; wait 200ms

; Now send a Windows Message to change Notepad's title
SendMessage, 0xC, 0, "Controlled by Robin", , ahk_id %hwnd%
; 0XC is WM_SETTEXT

ExitApp

And a little animation:

This code isn’t doing anything you can’t do other ways in Robin, but that’s not really the point. Using Windows handles and Windows messages you can distinguish among different instances of the same application, and operate on them accordingly.

Regards,
burque505

2 Likes

Excellent tutorial demonstrating how Robin can utilize/be utilized from 3rd party tools.
Looking forward to the next guide!

Best regards,
J.

1 Like