Skip to content

Some Tips and Tricks #3

@ssweber

Description

@ssweber

#Include for imported modules

While a relative directory #Include works when calling from a script, for a module you intend to import from, you'll need to do something like:

; shared.ahk
#Include {{LIB_DIRECTORY}}/jxon.ahk
; ... other ahk commands
# shared_ahk.py
import os
from pathlib import Path
from typing import Dict

from ahkunwrapped import Script

here = Path(__file__).parent
fname = here / "shared.ahk"

# Prepare directory paths for AutoHotkey #Include directive
lib_directory = str(here / "lib")

# Get the current Python Process ID
python_pid = str(os.getpid())

format_dict: Dict[str, str] = {
    "LIB_DIRECTORY": lib_directory,
    "PYTHON_PID": python_pid,
}

AHK = Script.from_file(fname, format_dict=format_dict)
# now this will work:
from shared_ahk import AHK

Quickly kill the ahk process

I used ahkunwrapped to automate Quickbooks Desktop. This involves mouse clicks, control-clips, sendinput, etc. Sometimes it's good to have a quick "escape-hatch" and let my office worker stop what is happening.

What I did is make an .ahk script that calls the individual python apps as hotkeys:

; launcher.ahk
^!s:: RunWait, %A_ScriptDir%\order_app.pyw
; shared.ahk
AutoExec() {
    BlockInput, Mouse
    CoordMode, Mouse, Screen
    SetDefaultMouseSpeed, 0
    
    ; Delays
    SetControlDelay, 150
    SetMouseDelay, 100
    SetWinDelay, 200
    
    global lock
    lock := 0
}

!`:: ; Alt + `
    global lock
    if lock 
    {
        return
    }
    Process, Close, {{PYTHON_PID}}
    return

Then, my employee can click [ALT] + [`~], and it'll immediately kill the python process. We are using the format_dict argument from Script.from_file to pass along the python PID from os to the ahk process. Also, there were times where I DIDN'T want the process to be able to be killed (while a database connection was open), so that's where our lock can be set AHK.set("lock", 1) and reset AHK.set("lock", 0)

MsgBox Creator GUI

AHK MsgBox has a ton of options, and its hard to get right. I found MsgBoxCreatorX that makes it easy to create your own.

image

So I created a few custom MsgBox's in my shared.ahk:

MsgBoxYesNo(msgText) {
    MsgBox, 262180, Question, %msgText%
    ifMsgBox Yes
        return "Yes"
    else
        return "No"
}

And then wrapped them in a Popup class, calling them answer = Popup.yn("Are you sure you want to continue")

from .shared_ahk import AHK

class Popup:
    @staticmethod
    def ok(msg_text):
        return AHK.f("MsgBoxOK", msg_text)

    @staticmethod
    def get_input(msg_text):
        return AHK.f("InputBoxPrompt", msg_text)

    @staticmethod
    def yn(msg_text):
        return AHK.f("MsgBoxYesNo", msg_text)

    @staticmethod
    def error(msg_text):
        return AHK.f("MsgBoxError", msg_text)

Blocking, On-Top InputBox

What about InputBox? It's annoying that it doesn't have Block / Always-on-Top builtin. I've posted that here: InputBoxPrompt

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions