Search code examples
winapiautohotkey

What does ControlSend do in AHK?


A feature of AHK scripts is that they can send keystrokes to a window, the window interprets the keystokes and displays them accordingly. The function that is used is called ControlSend in AHK.

I am curious about what this function actually does underneath in the Win32 API. I assumed it would make use of SendMessage/PostMessage; however, I tested both of them to send a message to the window using WM_KEYDOWN, and the window could not interpret it.

It's not simulating the keyboard with keybd_event or SendInput either, because it manages to send keystrokes even when the process window is in the background and unfocused.

So, which functions does ControlSend in AHK actually rely on in the Win32 API?

This is an example AHK script:

Loop{
    sendKey("a")
}

F1::
if (mypid == 0){
    WinGet, var, PID, A
    mypid = %var%
    MsgBox, Found client %mypid%
}

sendKey(key)
{
    global mypid
    WinClose
    ControlSend,,{%key%}, ahk_pid %mypid%
}

Solution

  • AutoHotkey is open source, and you can view the underlying C++ code directly on Lexikos' GitHub.

    Here is the function in question you'll want to look at.
    The aTargetWindow HWND will be non-null if you're control sending.
    All kinds of checks and magic is done in there, but in the end, you'll more often than not arrive at this function, where the key is sent by posting a WM_KEYDOWN and WM_KEYUP message to the target window.
    In some special cases (if the the key doesn't seem to have a VK or SC), it is sent by posting a WM_CHAR message.

    This is what I could tell by taking a quick look at the source, but as said, there's a lot in there. I'd recommend taking a look yourself an reading through those very helpful comments it has a lot of