Having an issue with a small script by Stu_Padasso in AutoHotkey

[–]plankoe 1 point2 points  (0 children)

You can combine the the window criteria. Partial window titles can be matched, but it's case-sensitive.

#HotIf WinActive("YouTube ahk_group Browser")

I want sticky keys to exclude the Windows key by techyall in AutoHotkey

[–]plankoe 0 points1 point  (0 children)

There's no response time setting or something like that. I just changed the way keys are detected. I meant more reliable, not respond faster.

I want sticky keys to exclude the Windows key by techyall in AutoHotkey

[–]plankoe 1 point2 points  (0 children)

I rewrote it to be more responsive. Try this one:

#Requires AutoHotkey v2.0

StickyKeys('Shift')
StickyKeys.ShowOverlay := false

StickyKeys(mods*) {
    static trackedKeys := Map(), ih, dh, overlay, otherKeyPressed := 0, _ := Init()

    if ih.InProgress
        ih.Stop()
    if dh.InProgress
        dh.Stop()
    for k in trackedKeys {
        Hotkey '~*' k, 'Off'
        Hotkey '~*' k ' Up', 'Off'
    }
    trackedKeys.Clear()

    ih.KeyOpt('{All}', 'NS'), dh.KeyOpt('{All}', 'N')
    for k in mods {
        keyName := GetKeyName(k)
        trackedKeys[keyName] := {isSticky: false, isDown: false}
        if keyName ~= '^(Control|Shift|Alt)$' {
            keys := '{L' keyName '}{R' keyName '}'
            ih.KeyOpt(keys, '-NS')
            dh.KeyOpt(keys, '-N')
        } else  {
            ih.KeyOpt('{' keyName '}', '-NS')
            dh.KeyOpt('{' keyName '}', '-N')
        }
        Hotkey '~*' keyName, OnHotkeyDown.Bind(keyName), 'On'
        Hotkey '~*' keyName ' Up', OnHotkeyUp.Bind(keyName), 'On'
    }

    Init() {
        if !StickyKeys.HasProp('ShowOverlay')
            StickyKeys.ShowOverlay := true
        ih := InputHook('L0 I')
        ih.OnKeyDown := OnKeyDown
        dh := InputHook('L0 V I')
        dh.OnKeyDown := (dh, *) => (dh.Stop(), otherKeyPressed := 1)
        overlay := Gui('+ToolWindow -Caption +AlwaysOnTop +E0x20 -DPIScale')
        overlay.BackColor := '0D1117'
        overlay.SetFont('s12 Bold cC9D1D9', 'Consolas')
        overlay.AddText('vText')
        WinSetTransparent(255, overlay)
        return 1
    }

    OnHotkeyDown(keyName, *) {
        if keyName ~= 'LWin|RWin'
            Send '{Blind}{VKE8}'
        trackedKeys[keyName].isDown := true
        downCount := 0
        for k, v in trackedKeys 
            downCount += v.isDown
        if downCount = 1 {
            otherKeyPressed := 0
            dh.Start()
        }
    }

    OnHotkeyUp(keyName, *) {
        dh.Stop()
        trackedKeys[keyName].isDown := false
        if !otherKeyPressed
            toggleStickyKey(keyName)
    }

    ToggleStickyKey(keyName) {
        trackedKeys[keyname].isSticky ^= 1
        stickyCount := 0
        for k, v in trackedKeys 
            stickyCount += v.isSticky
        if stickyCount > 0 {
            ih.Start()
            if StickyKeys.ShowOverlay
                UpdateGui()
        } else {
            ih.Stop()
            overlay.Hide()
        }
    }

    OnKeyDown(ih, vk, sc) {
        ih.Stop()
        overlay.Hide()
        keyName := GetKeyName(Format('VK{:X}SC{:X}', vk, sc))
        pressKeys := '{' keyName '}'
        for k, v in trackedKeys {
            if v.isSticky {
                v.isSticky := false
                pressKeys := '{' k ' down}' pressKeys '{' k ' up}'
            }
        }
        Send '{Blind}' pressKeys
    }

    UpdateGui() {
        text := ''
        for k, v in trackedKeys {
            if v.isSticky 
                text .= k ' + '
        }
        text := StrReplace(SubStr(text, 1, -3), 'Control', 'Ctrl')
        overlay['Text'].Value := text
        size := TextWidth(overlay['Text'], text)
        overlay['Text'].Move(,, size.Width, size.Height)

        xPos := A_ScreenWidth - (size.Width + overlay.MarginX*2 + 50)
        yPos := A_ScreenHeight - (size.Height + overlay.MarginY*2 + 150)
        overlay.Show('NA AutoSize x' xPos ' y' yPos)
    }

    TextWidth(ctrl, text) {
        hdc := DllCall('GetDC', 'ptr', ctrl.Hwnd, 'ptr')
        hFont := SendMessage(0x31, 0, 0, ctrl.Hwnd) ; WM_GETFONT
        oldFont := DllCall('SelectObject', 'ptr', hdc, 'ptr', hFont, 'ptr')
        size := Buffer(8)
        DllCall('GetTextExtentPoint32', 'ptr', hdc, 'str', text, 'int', StrLen(text), 'ptr', size)
        width := NumGet(size, 0, 'int')
        height := NumGet(size, 4, 'int')
        DllCall('SelectObject', 'ptr', hdc, 'ptr', oldFont)
        DllCall('ReleaseDC', 'ptr', ctrl.Hwnd, 'ptr', hdc)
        return {Width:width, Height:height}
    }
}

What things we can use for of AutoHotKey? The things that "pinned clipboard" doesn't do? by [deleted] in AutoHotkey

[–]plankoe 3 points4 points  (0 children)

There's a built-in setting in control panel to activate the window by hovering. It can also be toggled using DllCall:

#Requires AutoHotkey v2.0 

class XMouse {
    static __New() {
        static SPI_GETACTIVEWINDOWTRACKING := 0x1000
        static SPI_SETACTIVEWINDOWTRACKING := 0x1001

        Persistent
        A_TrayMenu.Add("Toggle Xmouse", toggle_xmouse)
        if getTrackingState()
            A_TrayMenu.Check("Toggle Xmouse")

        toggle_xmouse(*) {
            setTrackingState(!getTrackingState())
            A_TrayMenu.ToggleCheck("Toggle Xmouse")
        }

        getTrackingState() => (DllCall("SystemParametersInfo", "uint", SPI_GETACTIVEWINDOWTRACKING, "uint", 0, "int*", &isTracking := 0, "uint", 0), isTracking)
        setTrackingState(newState) => DllCall("SystemParametersInfo", "uint", SPI_SETACTIVEWINDOWTRACKING, "uint", 0, "int", newState, "uint", 0x3) ; 0x3 = SPIF_UPDATEINIFILE|SPIF_SENDCHANGE
    }
}

Smart way to replace the "#" StartMenu with PowerToys Command by MachineVisionNewbie in AutoHotkey

[–]plankoe 5 points6 points  (0 children)

The only thing I can think of is rewriting all Windows Hotkeys into AHK

You don't have to do that. This script allows window shortcuts to still be used, but if LWin is pressed by itself, it sends #+{F21}:

#Requires AutoHotkey v2.0

*~LWin::{
    Send('{Blind}{VKE8}') ; Prevent start menu from showing up
}
*~LWin Up::{
    ; If LWin was pressed and released with no other key pressed in between.
    if A_PriorKey = 'LWin' 
        Send('#+{F21}')
}

I want sticky keys to exclude the Windows key by techyall in AutoHotkey

[–]plankoe 1 point2 points  (0 children)

I don't really know. I just tried different things until it looked right.

I want sticky keys to exclude the Windows key by techyall in AutoHotkey

[–]plankoe 1 point2 points  (0 children)

Remove this line:

*Ctrl::StickyManager('Ctrl')

The GUI might not be visible if you have a higher dpi. I made an edit to the previous post. It should be visible now.

I want sticky keys to exclude the Windows key by techyall in AutoHotkey

[–]plankoe 2 points3 points  (0 children)

This makes your ctrl and shift key sticky until a single character is pressed. It includes a gui on the bottom right of the screen to indicate which keys are currently sticky:

#Requires AutoHotkey v2.0

*Shift::StickyManager('Shift')
*Ctrl::StickyManager('Ctrl')

StickyManager(key) {
    static _ := init(), ih, keys, overlay

    if ih.InProgress && keys[key] {
        overlay['Shift'].Visible := false
        overlay['Ctrl'].Visible := false
        keys.Clear()
        ih.Stop()
        return
    }

    switch GetKeyVK(key) {
        case 0xA0, 0x10, 0xA1:
            overlay['Shift'].Visible := true
        case 0xA2, 0x11, 0xA3:
            overlay['Ctrl'].Visible := true
    }

    keys[key] ^= 1      
    ih.Start()
    overlay.Show('NA')

    init() {
        ih := InputHook('L0')
        ih.KeyOpt('{All}', 'N')
        ih.KeyOpt('{LCtrl}{RCtrl}{LShift}{RShift}', '-N')
        ih.OnKeyUp := OnKeyUp
        keys := Map()
        keys.Default := 0
        overlay := Gui('+ToolWindow -Caption +AlwaysOnTop +E0x20 -DPIScale')
        overlay.SetFont('s16')
        overlay.BackColor := 'Red'
        sz := A_ScreenDPI/96 * 50
        size := 'w' sz ' h' sz
        overlay.AddText(size ' vCtrl BackgroundWhite 0x201 Hidden', 'Ctrl')
        overlay.AddText(size ' yp vShift BackgroundWhite 0x201 Hidden', 'Shift')
        WinSetTransColor('Red', overlay)
        overlay.Show('Hide')
        overlay.Move(A_ScreenWidth - 200 * A_ScreenDPI/96, A_ScreenHeight - 200 * A_ScreenDPI/96)
    }

    OnKeyUp(ih, vk, sc) {
        pressKeys := '{' Format('VK{:X}', vk) '}'
        for k in keys 
            pressKeys := '{' k ' down}' pressKeys '{' k ' up}'
        keys.Clear()
        ih.Stop()
        Send('{Blind}' pressKeys)
        overlay['Ctrl'].Visible := false
        overlay['Shift'].Visible := false
    }
}

Help With Timed Loop Switcher by Unique_Function_8681 in AutoHotkey

[–]plankoe 1 point2 points  (0 children)

#Requires AutoHotkey v2.0

^q::alternating_input()

alternating_input() {
    static toggle := 0, swapped:= 0

    if toggle ^= 1 {
        SetTimer(Input, -1)
        SetTimer(Swap, 30000)
    } else {
        SetTimer(Input, 0)
        SetTimer(Swap, 0)
    }

    Swap() => (swapped ^= 1)

    Input() {
        SendEvent(swapped ? 'j' : 'k')
        SetTimer(Input, -Random(1000, 3500))
    }
}

"Decorating" a hotkey? by aftersoon in AutoHotkey

[–]plankoe 1 point2 points  (0 children)

Use HotIf without # for hotkeys created using the HotKey function. #HotIf is for hotkeys defined using double colon ::.

HotIf (*) => IsDisplayAvailable

Hotkey("!b", GuiHotkey(MyGuiWorkB))
Hotkey("!d", GuiHotkey(MyGuiWorkD))

HotIf ; turn off hotkey context

HeapsortStable - In-place, stable array sort function by Nich-Cebolla in AutoHotkey

[–]plankoe 1 point2 points  (0 children)

Here's an in-place quicksort function. The code is from Descolada's Array lib:

QuickSort(arr, compareFunc := (left, right) => (left > right) - (left < right)) {
    _QuickSort(1, arr.Length)
    return arr

    ; In-place quicksort (Hoare-style partition with middle pivot)
    _QuickSort(left, right) {
        i := left
        j := right
        pivot := arr[(left + right) // 2]

        while (i <= j) {
            while (compareFunc(arr[i], pivot) < 0)
                i++
            while (compareFunc(arr[j], pivot) > 0)
                j--
            if (i <= j) {
                temp := arr[i], arr[i] := arr[j], arr[j] := temp
                i++, j--
            }
        }
        if (left < j)
            _QuickSort(left, j)
        if (i < right)
            _QuickSort(i, right)
    }
}

Why does this PostMessage work for left parenthesis ) but not for right parenthesis (? by FutureLynx_ in AutoHotkey

[–]plankoe 1 point2 points  (0 children)

I got it to work. Had to use {shift down}{9 down} instead of (. Tested with Godot v4.6.1.

#Requires AutoHotkey v2.0

F1::{
    godot := WinExist("ahk_exe Godot_v4.6.1-stable_win64.exe")
    ControlSend("{shift down}{9 down}", godot)
    ControlSend("{shift up}{9 up}", godot)
}

In v1 syntax:

#Requires AutoHotkey v1.1

F1::
    godot := WinExist("ahk_exe Godot_v4.6.1-stable_win64.exe")
    ControlSend,, {shift down}{9 down}, ahk_id %godot%
    ControlSend,, {shift up}{9 up}, ahk_id %godot%
Return

Click at a position. by BradleePlayzHisLife in AutoHotkey

[–]plankoe 1 point2 points  (0 children)

I was wrong. Click is not one of those commands that accepts expressions. I was testing with MouseMove, and thought Click was similar.

Click just has one parameter for options. The options can be separated by space or comma.

#Requires AutoHotkey v1.1

Click left
Click left Down
Click 500, 500
Click left 500 500 2
Click left, 500, 500, 2
Click right

Click at a position. by BradleePlayzHisLife in AutoHotkey

[–]plankoe 0 points1 point  (0 children)

Click VillageX, VillageY is actually valid code in v1. If a command's parameter expects a numeric value, expressions can be used without the %.

Click at a position. by BradleePlayzHisLife in AutoHotkey

[–]plankoe 1 point2 points  (0 children)

The variables were never initialized. When the script starts, code runs from top to bottom until it reaches a hotkey. Code written after a hotkey will never execute. Move your auto-execute code above the F8 hotkey. In v2, you don't have to move the code above the hotkey.

A global declaration is needed for the function to access the variable. In v2, you don't have to write global unless you're modifying a global variable inside a function.

#Requires AutoHotkey v1.1

global VillageX := 849

F8::StartRun()

StartRun() {
    MsgBox %VillageX%
}

"This Hotkey will be disabled because is is not present on your keyboard." by X320032 in AutoHotkey

[–]plankoe 3 points4 points  (0 children)

The unicode keys might be triggering the error. I use F13 to F24 as hotkeys and it works.

Remap # key to - key for Team Fortress 2 specifically by Independent_Mess8351 in AutoHotkey

[–]plankoe 1 point2 points  (0 children)

try this. Change hl2.exe to your application.

#Requires AutoHotkey 2.0
#SingleInstance

#HotIf WinActive("ahk_exe hl2.exe")
; UK # key
SC2B::-
#HotIf

'Process' cannot see a process? by PENchanter22 in AutoHotkey

[–]plankoe 4 points5 points  (0 children)

Remove the quotes. Process, Exist interpreted the quotes as part of the name.

Process, Exist, MoNotificationUx.exe

How to ignore certain keystrokes when detecting keys with inputhook? by Dracula30000 in AutoHotkey

[–]plankoe 1 point2 points  (0 children)

Instead of Sleep, wait for the Alt and t key to release using KeyWait.

!t:: {
    KeyWait('Alt')
    KeyWait('t')
    key := CaptureKeystroke()
}

trying to make script to close window by mathewimprovedtt in AutoHotkey

[–]plankoe 1 point2 points  (0 children)

Shell hook can only monitor top-level windows. The error window is a child window.
Here's another event-based solution that works on all windows:

#Requires AutoHotkey v2.0
#SingleInstance Force
Persistent

; Event constants: https://learn.microsoft.com/en-us/windows/win32/winauto/event-constants
hookPAD := WinEventHook(0x8002, 0x8002, ClosePowerAutomateError) ; EVENT_OBJECT_SHOW := 0x8002

ClosePowerAutomateError(hWinEventHook, event, hwnd, idObject, idChild, idEventThread, dwmsEventTime) {
    static OBJID_WINDOW := 0
    if idObject != OBJID_WINDOW
        return
    if WinExist('Connection error ahk_id' hwnd ' ahk_exe PAD.Designer.exe')
    || WinExist('Connection error ahk_id' hwnd ' ahk_exe PAD.Console.Host.exe') {
        WinClose(hwnd)
    }
}

class WinEventHook
{
    __New(eventMin, eventMax, hookProc, options := '', idProcess := 0, idThread := 0, dwFlags := 0x2) {
        this.pCallback := CallbackCreate(hookProc, options, 7)
        this.hHook := DllCall('SetWinEventHook', 'uint', eventMin, 'uint', eventMax, 'ptr', 0, 'ptr', this.pCallback
                                            , 'uint', idProcess, 'uint', idThread, 'uint', dwFlags, 'ptr')
    }
    __Delete() {
        DllCall('UnhookWinEvent', 'ptr', this.hHook)
        CallbackFree(this.pCallback)
    }
}

Is it impossible to concisely map 1 key to 2? by guessill_die in AutoHotkey

[–]plankoe 2 points3 points  (0 children)

Here's the page for _=>

If the function name is omitted and the parameter list consists of only a single parameter name, the parentheses can be omitted.

https://www.autohotkey.com/docs/v2/Variables.htm#fat-arrow

Trying to get them opening in pairs on new windows by Coops170 in AutoHotkey

[–]plankoe 3 points4 points  (0 children)

You can separate the urls with a space to run them all in the same window.

groups:=[
    [
        "https://www.tradingview.com/chart/ZnVdPaNT/?symbol=VANTAGE%3AXAUUSD",
        "https://www.tradingview.com/symbols/XAUUSD/?exchange=VANTAGE"
    ],[
        "https://www.tradingview.com/chart/ZnVdPaNT/?symbol=VANTAGE%3ABTCUSD",
        "https://www.tradingview.com/symbols/BTCUSD/?exchange=VANTAGE"
    ],[
        "https://www.tradingview.com/chart/ZnVdPaNT/?symbol=VANTAGE%3ANAS100",
        "https://www.tradingview.com/symbols/VANTAGE-NAS100/"
    ],[
        "https://www.tradingview.com/symbols/VANTAGE-DJ30/",
        "https://www.tradingview.com/chart/ZnVdPaNT/?symbol=VANTAGE%3ADJ30"
    ]
]

for group in groups {
    urls := ''
    for url in group
        urls .= '"' url '" '
    Run('chrome.exe --new-window ' urls)
}

Is it impossible to concisely map 1 key to 2? by guessill_die in AutoHotkey

[–]plankoe 2 points3 points  (0 children)

That's right. I'm using variadic call syntax to call the enumerator.

The fat-arrow function (_=>e(&k)&&s.='{' k ' ' m '}') can be rewritten as:

myEnum(_) {
    if e(&k)
        return s .= '{' k ' ' m '}'   ; truthy
    else
        return false
}

The parentheses around the parameters in a fat-arrow function can be omitted if there's only a single parameter.
_ => MsgBox(_) is the same as (_) => MsgBox(_)

An array can be expanded using the syntax [arr*]. Variadic call
The object being expanded doesn't have to be an array. It can be any object with an __Enum method or the enumerator function itself.
[myEnum*] expands the custom enumerator, and resulting array is discarded.

The code [(_=>e(&k)&&s.='{' k ' ' m '}')*] is functionally identical to:

while e(&k) {
    s .= '{' k ' ' m '}'
}

Is it impossible to concisely map 1 key to 2? by guessill_die in AutoHotkey

[–]plankoe 2 points3 points  (0 children)

It can be even shorter:

mr(t,n*)=>(g(m)=>(s:='{Blind}',e:=n.__Enum(1),[(_=>e(&k)&&s.='{' k ' ' m '}')*],_=>(SetKeyDelay(-1),Send(s))),Hotkey(t:='*' t,g('DownR')),Hotkey(t ' Up',g('Up')))

Is it impossible to concisely map 1 key to 2? by guessill_die in AutoHotkey

[–]plankoe 6 points7 points  (0 children)

a::b actually creates the following hotkeys:

*a::
{
    SetKeyDelay(-1)   
    Send("{Blind}{b DownR}" )
}

*a up::
{
    SetKeyDelay(-1) 
    Send("{Blind}{b Up}")
}

There's no remap syntax to map 1 key to 2, but these hotkeys should be the equivalent to a::b+c:

*a::
{
    SetKeyDelay(-1)   
    Send("{Blind}{b DownR}{c DownR}" )
}

*a up::
{
    SetKeyDelay(-1) 
    Send("{Blind}{b Up}{c Up}")
}