#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](https://private-user-images.githubusercontent.com/57631333/271673920-18335498-89e8-4b25-a3b3-86dd6bb1c841.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MDQ1NjI0NDAsIm5iZiI6MTcwNDU2MjE0MCwicGF0aCI6Ii81NzYzMTMzMy8yNzE2NzM5MjAtMTgzMzU0OTgtODllOC00YjI1LWEzYjMtODZkZDZiYjFjODQxLnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNDAxMDYlMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjQwMTA2VDE3MjkwMFomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPWEzMmJkOTY1NmMwNWRhZjg3MjU5ZmUxZDZhYzVkMGVjYmVkOGUzZmZmMjRjZjc1YzFlNzU1OGMxNWIxZDkyOTcmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0JmFjdG9yX2lkPTAma2V5X2lkPTAmcmVwb19pZD0wIn0.zNsTHBodwQ2K4UqunPQKUO5DjKig33F9xMoe73K-DUg)
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