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

Get help with using AutoHotkey and its commands and hotkeys
User avatar
jeeswg
Posts: 6648
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 window/control hWnd)
ControlSend, , %vOutput%, ahk_id %hWnd%

;send raw secure (where hWnd is window/control hWnd)
Loop, Parse, vOutput
PostMessage, 0x102, % Asc(A_LoopField), 1, , ahk_id %hWnd% ;WM_CHAR
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.
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: 6648
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)?
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: 6648
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("GetCurrentThreadId", Ptr)
VarSetCapacity(PBYTE1, 256, 0)
DllCall("GetKeyboardState", Ptr,&PBYTE1)

vTID := DllCall("GetWindowThreadProcessId", Ptr,hWnd, UPtr,0)
DllCall("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("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("AttachThreadInput", UInt,vTIDAhk, UInt,vTID, Int,0)
DllCall("SetKeyboardState", Ptr,&PBYTE1)
return
Last edited by jeeswg on 23 Apr 2017, 15:52, 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: 6648
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 before i return), AttachThreadInput (to detach) and SetKeyboardState to 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 17 Feb 2019, 15:11, 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: 6648
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%
SendMessage, 0x100, 0x10, 0x002A0001, , ahk_id %hWnd%
SendMessage, 0x100, 0x25, 0x014B0001, , ahk_id %hWnd%
Sleep 200
SendMessage, 0x101, 0x25, 0xC14B0001, , ahk_id %hWnd%
SendMessage, 0x101, 0x11, 0xC01D0001, , ahk_id %hWnd%
SendMessage, 0x101, 0x10, 0xC02A0001, , ahk_id %hWnd%
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
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: Bing [Bot], effel, Google [Bot], MannyKSoSo and 171 guests