AutoHotkey source code: Send/ControlSend (modifier keys) Topic is solved

Get help with using AutoHotkey and its commands and hotkeys
User avatar
jeeswg
Posts: 6904
Joined: 19 Dec 2016, 01:58
Location: UK

AutoHotkey source code: Send/ControlSend (modifier keys)

07 Jan 2017, 11:50

I have been able to understand the AutoHotkey source code for most commands/functions when needed, however the Send/ControlSend source code seems to be rather complicated.
If anyone understands it well, would they please give me or point me to a summary of some of the main issues/techniques.

My main questions are:
- How does AutoHotkey do shift/ctrl/win/alt + letter?
- How can an AutoHotkey GUI detect shift/ctrl/win/alt + letter, i.e. what should it check for in the message queue.

One problem I've had with Send is that if the active window changes, it sends key presses to the wrong window.
So I created 'secure' versions:

Code: Select all

;send secure (where hWnd is a window/control hWnd):
ControlSend,, % vOutput, % "ahk_id " hWnd

;send raw secure (where hWnd is a window/control hWnd):
Loop Parse, vOutput
	PostMessage, 0x102, % Ord(A_LoopField), 1,, % "ahk_id " hWnd ;WM_CHAR := 0x102
Another problem I had is, for example, the euro character would not send properly.
I believe AutoHotkey tries to send (or used to in the past) ctrl+alt+4.
However, WM_CHAR, as used above, seems to work consistently.
Another example is é and ctrl+alt+e.
Last edited by jeeswg on 20 Sep 2019, 21:41, edited 1 time in total.
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
User avatar
jeeswg
Posts: 6904
Joined: 19 Dec 2016, 01:58
Location: UK

Re: AutoHotkey source code: Send/ControlSend (modifier keys)

12 Jan 2017, 14:33

For example, can anyone tell me how to send Ctrl+Shift+Left/Ctrl+Shift+Right via SendMessage (or Acc (MSAA)/UI Automation if that's possible)?
Last edited by jeeswg on 20 Sep 2019, 21:42, edited 1 time in total.
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
User avatar
jeeswg
Posts: 6904
Joined: 19 Dec 2016, 01:58
Location: UK

Re: AutoHotkey source code: Send/ControlSend (modifier keys)  Topic is solved

30 Jan 2017, 14:24

Alternatives to Send/SendInput/ControlSend:
To send text (individual Unicode characters): WM_CHAR.
To send an individual key press: WM_KEYDOWN, WM_KEYUP.
To send an individual key press plus modifiers:
WM_KEYDOWN, WM_KEYUP, but also use SetKeyboardState as in the example below.

To receive an individual key press, and to work out the correct parameter values for WM_KEYDOWN, WM_KEYUP, that you would use to send a key press:
Use OnMessage to check for the 2 messages, and receive the parameters, for when keys are pressed manually or sent via Send/SendInput.

To receive an individual key press, and modifiers:
Use OnMessage to check for the key press and use GetKeyState to check for modifiers.
Instead of GetKeyState, the dll function GetKeyboardState can be used.

The reasons for investigating Send/SendInput, were to understand how best to receive input when creating GUIs via AutoHotkey, and to be able to send key presses to a specific hWnd unlike via Send/SendInput.
Further reasons are to understand how key presses can be sent in programming languages generally, without standard AutoHotkey functions, and to understand the AutoHotkey source code.
To find out how AutoHotkey does this, search the cpp source code files for 'GetKeyboardState' and 'SetKeyboardState'.

Note: regarding methods outlined here, there may be other methods.
Note: the code below worked although it is possible that improvements could be made.

If anyone has any further comments regarding these issues, or the code, or regarding AutoHotkey and receiving/sending key presses, they would be most welcome.

Code: Select all

q:: ;send ctrl+shift+left without using Send/SendInput/ControlSend
;e.g. tested on Notepad (Windows 7)
WinGet, hWnd, ID, A
ControlGetFocus, vCtlClassNN, % "ahk_id " hWnd
if !(vCtlClassNN = "")
	ControlGet, hWnd, Hwnd,, % vCtlClassNN, % "ahk_id " hWnd

vTIDAhk := DllCall("kernel32\GetCurrentThreadId", "UInt")
VarSetCapacity(PBYTE1, 256, 0)
DllCall("user32\GetKeyboardState", "Ptr",&PBYTE1)

vTID := DllCall("user32\GetWindowThreadProcessId", "Ptr",hWnd, "Ptr",0, "UInt")
DllCall("user32\AttachThreadInput", "UInt",vTIDAhk, "UInt",vTID, "Int",1)
VarSetCapacity(PBYTE2, 256, 0)
NumPut(0x80, PBYTE2, 0x10, "UChar") ;VK_SHIFT := 0x10
NumPut(0x80, PBYTE2, 0x11, "UChar") ;VK_CONTROL := 0x11
DllCall("user32\SetKeyboardState", "Ptr",&PBYTE2)

;VK_LEFT := 0x25
SendMessage, 0x100, 0x25, 0x014B0001,, % "ahk_id " hWnd ;WM_KEYDOWN := 0x100
SendMessage, 0x101, 0x25, 0xC14B0001,, % "ahk_id " hWnd ;WM_KEYUP := 0x101
DllCall("user32\AttachThreadInput", "UInt",vTIDAhk, "UInt",vTID, "Int",0)
DllCall("user32\SetKeyboardState", "Ptr",&PBYTE1)
return
Last edited by jeeswg on 20 Sep 2019, 21:46, edited 2 times in total.
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
User avatar
jeeswg
Posts: 6904
Joined: 19 Dec 2016, 01:58
Location: UK

Re: AutoHotkey source code: Send/ControlSend (modifier keys)

30 Jan 2017, 14:40

Useful links:

[ list of VK constants]
Virtual-Key Codes (Windows)
https://msdn.microsoft.com/en-us/library/windows/desktop/dd375731(v=vs.85).aspx

[useful code]
method to detect key combinations - Scripts and Functions - AutoHotkey Community
https://autohotkey.com/board/topic/6978-method-to-detect-key-combinations/

[useful approach comments]
Need some advice for sending CTRL in global mousehook - Ask for Help - AutoHotkey Community
https://autohotkey.com/board/topic/3051-need-some-advice-for-sending-ctrl-in-global-mousehook/

GetKeyboardState to save old state, AttachThreadInput, SetKeyboardState for SHIFT or CTRL, Send/PostMessage, Sleep (needed so foreign application can process message), AttachThreadInput (to detach) and SetKeyboardState to restore old state.

[EDIT:] Similar question to this thread (topic):
PostMessage plz help - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=5&t=30925
Last edited by jeeswg on 20 Sep 2019, 21:49, edited 3 times in total.
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
User avatar
jeeswg
Posts: 6904
Joined: 19 Dec 2016, 01:58
Location: UK

Re: AutoHotkey source code: Send/ControlSend (modifier keys)

31 Jan 2017, 03:22

Raw messages for key presses:
Btw these are the messages received when sending keys manually or using SendInput to achieve ctrl+shift+left, (the 6 messages were the same in both cases,) but sending them via SendMessage only resulted in send left.

Note: SendInput appeared to work consistently to send ctrl+shift+left, but ControlSend only appeared to work intermittently.

Code: Select all

q:: ;did not work to send ctrl+shift+left, only sent left
WinGet, hWnd, ID, A
ControlGetFocus, vCtlClassNN, % "ahk_id " hWnd
if !(vCtlClassNN = "")
	ControlGet, hWnd, Hwnd,, % vCtlClassNN, % "ahk_id " hWnd

SendMessage, 0x100, 0x11, 0x001D0001,, % "ahk_id " hWnd ;WM_KEYDOWN := 0x100
SendMessage, 0x100, 0x10, 0x002A0001,, % "ahk_id " hWnd ;WM_KEYDOWN := 0x100
SendMessage, 0x100, 0x25, 0x014B0001,, % "ahk_id " hWnd ;WM_KEYDOWN := 0x100
Sleep, 200
SendMessage, 0x101, 0x25, 0xC14B0001,, % "ahk_id " hWnd ;WM_KEYUP := 0x101
SendMessage, 0x101, 0x11, 0xC01D0001,, % "ahk_id " hWnd ;WM_KEYUP := 0x101
SendMessage, 0x101, 0x10, 0xC02A0001,, % "ahk_id " hWnd ;WM_KEYUP := 0x101
return

;==================================================

;for reference (reliable):
;q::
SendInput, ^+{Left}
return

;for reference (unreliable, worked but intermittently):
;q::
ControlSend,, ^+{Left}, A
return

;for reference (unreliable, worked but intermittently):
;q::
ControlSend, Edit1, ^+{Left}, A
return

;for reference (unreliable, worked but intermittently):
;q::
WinGet, hWnd, ID, A
ControlGetFocus, vCtlClassNN, % "ahk_id " hWnd
if !(vCtlClassNN = "")
	ControlGet, hWnd, Hwnd,, % vCtlClassNN, % "ahk_id " hWnd
ControlSend,, ^+{Left}, % "ahk_id " hWnd
return
[EDIT:] A related thread:
SendInput specify hWnd / improved ControlSend - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=5&t=37120
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA

Return to “Ask For Help”

Who is online

Users browsing this forum: Albireo, holydoji, pn4265 and 259 guests