0
votes

I want to define a shortcut using autohotkey that automates navigation to the Cell Width text box in Word's ribbon menu (i.e. sends the keys Alt,j,l,w while in Word).

My initial attempt at a script introduces an issue where the Up actions of the physical key presses haven't completed before the keys are sent by the script, causing it to fail.

Although I have a workaround (using sleep 250, shown further below), I would like to understand whether there is a more elegant solution - e.g. this value was chosen by trial and error, and this workaround may fail on a different machine, or if my laptop is having a bad day.

Essentially, I would like to find a solution that avoids hardcoding a wait duration.

Any suggestions?


The issue

In my initial script I tried to define the hotkey Alt+Shift+p in Word, to send Alt,j,l,w in sequence. This fails and enters the text "jlw" into the active table cell instead.

This is because for keys physically pressed (marked with # in comments below), the Up actions are yet to run when the script has already begun sending keys (indicated with $). This disrupts the send sequence Alt,j,l,w so it fails.

Also note events marked with ? may be a byproduct of the failed actions.

Script

; Jump to table cell width entry when Alt+Shift+p pressed in Word only
#IfWinActive, ahk_exe WINWORD.EXE
!+p::
Send, {RAlt down}{RAlt up}jlw
Return

Key history

VK  SC  Type    Up/Dn   Elapsed Key     Comment
-------------------------------------------------------------------------------------------------------------
A4  038     d   1.03    LAlt            #
A0  02A     d   0.14    LShift          #
50  019 h   d   0.13    p               #, h=Hook Hotkey
A5  138 i   d   0.02    RAlt            $
A5  138 i   u   0.00    RAlt            $
11  01D i   d   0.00    Control         ?
11  01D i   u   0.00    Control         ?
A4  038 i   u   0.00    LAlt            #
A0  02A i   u   0.00    LShift          #
4A  024 i   d   0.00    j               $
4A  024 i   u   0.00    j               $
4C  026 i   d   0.00    l               $
4C  026 i   u   0.00    l               $
57  011 i   d   0.00    w               $
57  011 i   u   0.00    w               $
11  01D i   d   0.00    Control         ?
A4  038 i   d   0.00    LAlt            ?
11  01D i   u   0.00    Control         ?
A0  02A i   d   0.00    LShift          ?
50  019 s   u   0.08    p               #
A0  02A     u   0.25    LShift          ?
A4  038     u   0.00    LAlt            ?

Workaround

By adding a sleep 250 statement, the hotkey and sent keys run in the intended sequence. Note no other keys are triggered (nothing indicated with ?).

Script

; Jump to table cell width entry when Alt+Shift+p pressed in Word only
#IfWinActive, ahk_exe WINWORD.EXE
!+p::
Sleep 250
Send, {RAlt down}{RAlt up}jlw
Return

Key history

VK  SC  Type    Up/Dn   Elapsed Key     Comment
-------------------------------------------------------------------------------------------------------------
A4  038     d   0.39    LAlt            #
A0  02A     d   0.20    LShift          #
50  019 h   d   0.20    p               #, h=Hook Hotkey
50  019 s   u   0.11    p               #
A0  02A     u   0.11    LShift          #
A4  038     u   0.00    LAlt            #
A5  138 i   d   0.03    RAlt            $
A5  138 i   u   0.00    RAlt            $
4A  024 i   d   0.00    j               $
4A  024 i   u   0.00    j               $
4C  026 i   d   0.00    l               $
4C  026 i   u   0.00    l               $
57  011 i   d   0.00    w               $
57  011 i   u   0.00    w               $, SUCCESS!
3

3 Answers

0
votes

If the target window does not receive the keystrokes reliably, you can try increasing the press duration in the send command via the second parameter of SetKeyDelay, eg.

!+p::
    SetKeyDelay, 10, 10
    Send, {RAlt down}{RAlt up}jlw
Return
0
votes

Not sure why you're using right alt, don't think that's supposed to work even. Just use "Alt". And I think your hotkey is not very good for this. Word gets confused with the input.
But I think maybe doing this, could work

!+p up:: ;up means it'll run once u release p, might help a bit
    SetKeyDelay, 500, 10 ;good amount of delay, can probably do with less
    Send, {Shift Up}{Alt Up}{Alt}jlw ;send shift and alt up first
Return

And now for a better alternative option, automating it with the Word ComObject. Usage of VBA for this is the normal and intended way, but you can AHK (or any other language) just as well.
Here's a quick AHK example of changing the first table's first cell's width:

Word := ComObjActive("Word.Application")
Word.ActiveDocument.Tables(1).Cell(1, 1).Width := 500

Of course that's not a very good way to go about this, I'm sure you can reference the active table and active cell somehow, I just quickly read the docs and wrote that. Haven't actually ever used any of this stuff in practice myself.

0
votes

I found a more elegant solution using KeyWait. Compared to my earlier workaround script, I consider this more elegant since it doesn't require hardcoding a wait duration. This simply waits for the pressed keys to come up before the script continues, preventing any conflict:

Script

#IfWinActive, ahk_exe WINWORD.EXE
!+p::
KeyWait Alt
KeyWait Shift
KeyWait p
Send, {Alt Down}{Alt Up}jlw
Return

Key history

VK  SC  Type    Up/Dn   Elapsed Key     Comment using previous notation
-------------------------------------------------------------------------------------------------------------
A4  038     d   0.63    LAlt            #
A0  02A     d   0.11    LShift          #
50  019 h   d   0.11    p               #
50  019 s   u   0.06    p               #
A0  02A     u   0.19    LShift          #
A4  038     u   0.00    LAlt            #
12  038 i   d   0.01    Alt             $
12  038 i   u   0.00    Alt             $
4A  024 i   d   0.00    j               $
4A  024 i   u   0.00    j               $
4C  026 i   d   0.00    l               $
4C  026 i   u   0.00    l               $
57  011 i   d   0.00    w               $
57  011 i   u   0.00    w               $

Interestingly, the above script modified to use Send, !jlw works (i.e. navigates to the Cell Width box) but the sent keys come Up out of sequence as follows. I won't use this, just to avoid any unintended consequences of this occurring out of sequence.

VK  SC  Type    Up/Dn   Elapsed Key     Comment 
-------------------------------------------------------------------------------------------------------------
A4  038     d   1.17    LAlt            
A0  02A     d   0.11    LShift          
50  019 h   d   0.14    p               
50  019 s   u   0.09    p               
A0  02A     u   0.16    LShift          
A4  038     u   0.00    LAlt            
A4  038 i   d   0.02    LAlt            <--
4A  024 i   d   0.00    j               
4A  024 i   u   0.00    j               
A4  038 i   u   0.00    LAlt            <--
4C  026 i   d   0.00    l               
4C  026 i   u   0.00    l               
57  011 i   d   0.00    w               
57  011 i   u   0.00    w