L.Nにメッセージを送りたい方はこちら。
特定記事に限らない話題はこの記事のコメント欄にどぞ。
AutoHotkey v1で、アクティブなウィンドウに対応するスクリプトを自動起動/終了するようにしてみた
メインの常駐AHKが肥大化するのを防ぐため、「アクティブなウィンドウの実行ファイルに対応するスクリプトがあれば自動起動」「ウィンドウを閉じたらそれを自動終了」するスクリプトを書いた。AHKには動的includeがないので。対応するスクリプトとは、実行ファイルのパス.ahk。例えばc:\windows\notepad.exe.ahk
偶に使うアプリや、クリアしたらおしまいなゲーム等で便利。ジョイパッドのボタン(Joy1~32)をホットキーにするとCPUリソースドカ食いすることがあるので、被害を最小限に抑えられる。
ウィンドウ切り替わりイベント(と終了イベント)をフックしてるので応用が利く。勝手にアクティブになってしまうブラウザを押さえつけるとか。
pBuf := RegisterCallback("cbWinEvent")
DllCall("SetWinEventHook", "uint", 0x0003, "uint", 0x0003, "uint", 0, "ptr", pBuf, "uint", 0, "uint", 0, "uint", 0, "uint", 0)
DllCall("SetWinEventHook", "uint", 0x8001, "uint", 0x8001, "uint", 0, "ptr", pBuf, "uint", 0, "uint", 0, "uint", 0, "uint", 0)
pBuf := ""
return
cbWinEvent(hWinEventHook, event, hwnd, idObject, idChild, dwEventThread, dwmsEventTime) {
static oHwndAHK := {}
switch event
{
case 0x0003: { ; アクティブウィンドウ切り替え
evForeground(hwnd, oHwndAHK)
}
case 0x8001: { ; オブジェクト破棄
if (0 == idObject) ; 破棄されたのがウィンドウなら
evObjDestroy(hwnd, oHwndAHK)
}
}
}
evObjDestroy(hwnd, oHwndAHK) {
if !oHwndAHK.HasKey(hwnd)
return
if oHwndAHK[hwnd].path {
if hwnd2 := WinExist("ahk_exe " SubStr(oHwndAHK[hwnd].path, 1, -4)) {
evForeground(hwnd2, oHwndAHK) ; 他のウィンドウが生きてれば託す
} else {
DetectHiddenWindows, On
WinClose, % oHwndAHK[hwnd].path " ahk_class AutoHotkey"
}
}
oHwndAHK.Delete(hwnd)
}
evForeground(hwnd, oHwndAHK) {
if (!oHwndAHK.HasKey(hwnd)) {
WinGet, ProcPath, ProcessPath, A
if FileExist(ProcPath ".ahk") {
oHwndAHK[hwnd] := {path: ProcPath ".ahk", TickDelay: 0}
} else {
oHwndAHK[hwnd] := ""
return
}
}
if (oHwndAHK[hwnd].path && A_TickCount >= oHwndAHK[hwnd].TickDelay) {
DetectHiddenWindows, On
If !WinExist(oHwndAHK[hwnd].path " ahk_class AutoHotkey") {
oHwndAHK[hwnd].TickDelay := 2000 + A_TickCount
Run, % A_AhkPath " """ oHwndAHK[hwnd].path """"
}
}
}
AutoHotKeyで、マウス速度を一時的に変更してみた。
マウス速度を最大かつ加速度も上げると、わずかな動きで端から端まで移動できるようになるが、1pxの精密動作ができなくなる。そこで、左Altを押してる間だけ速度を最低にするAHKを書いた。
~LAlt:: ; https://www.autohotkey.com/docs/commands/DllCall.htm#ExMouseSpeed
SPI_GETMOUSESPEED := 0x70
SPI_SETMOUSESPEED := 0x71
; DllCall("SystemParametersInfo", "UInt", SPI_GETMOUSESPEED, "UInt", 0, "UIntP", OrigMouseSpeed, "UInt", 0); 現在値取得
DllCall("SystemParametersInfo", "UInt", SPI_SETMOUSESPEED, "UInt", 0, "Ptr", 1, "UInt", 0); 1に
KeyWait, LAlt
DllCall("SystemParametersInfo", "UInt", SPI_SETMOUSESPEED, "UInt", 0, "Ptr", 20, "UInt", 0); 20に(決め打ちが嫌なら上で取得してここで戻す)
return
他のキー(Appsとか)でもいいが、CtrlとShiftはお勧めできない。GUIで複数選択する時によくやるので。
ちなみにマウス加速度の編集は「マウスポインタの加速調整ツール for XP」が便利。プリセット3で、低速域をちょっと傾斜上げてる。早すぎと感じても使ってる内に慣れる人体凄い。
OxygenNotIncludedで、Shoebox boilerを作った備忘録。
基地開発ゲー「OxygenNotIncluded」で、先人の天然ガス蒸留設備「Shoebox boiler」を真似した時のメモ。
- 宇宙素材を多用した小型設備。酸性ガスを冷却して作った天然ガスと硫黄で酸性ガスを冷却する自転車操業めいた仕組みで、起動と停止が難しい。天然ガスの搬出先もあらかじめ必要。
- 上手く回さないと経路に石油や液化硫黄が詰まって建て直し。その際にガスを抜くのが大変。
- 上部経路に機械式エアロックを仕込んでおくと閉じるだけで済む。セーブロードで運悪く硫黄が溶けることもあるのでリカバリ大事。
- 原油オーバーフロー(加熱失敗)、パイプ凍結破損(給油途絶えて冷気が逆流)、硫黄溶融(パケットが小さすぎて溶けた/タービン停止で溶けた)、吸気ポンプオーバーヒート(冷却失敗で熱が気体プールに逆流)で5敗。
- テルミウム必須は液体クーラーのみだが、念のため掃除機とローダー、輻射パイプもテルミウムがよいかも。バルブと吸気ポンプもテルミウムだと万全(上記事故があったので)。
- ボイラー内の液体ブリッジは火成岩か黒曜石が安心(詰まった石油を気化させようと無茶したら溶けた)
- ボイラー内の融解鉛は熱交換プレートが楽。宇宙ならブリッジ等で。
- 蒸気タービンが止まると硫黄が詰まるので重要。水は100kg/tile位? 順調なら自己冷却可能なはずだが、搬出した硫黄で冷やすとよい(100度以下なので溶けない)。
- バルブは1700g/s弱(それ以上作っても搬出できないし、加熱/冷却も間に合わない)
- 下画像のように液体メタンが吸気ポンプを阻害することがあるので、熱交換パネルを貼る方がよいだろうか。
- プールは先人の設定温度だとメタンが凍結して取り残される可能性があるので、ギリギリ(<-176度位)がいいかも。
- ローダーはタイマー制御で硫黄パケットを大きくすると安心。
- 起動は、まずは空焚きから始め、そののち少しずつ原油を注入してボイラーとプールを適温にする。天然ガス生産が軌道に乗り始めたら天然ガス搬出開始、レール上の酸化ガス温度が150度程度に安定してから硫黄搬出開始。
- 停止は、原油の注入速度を最低にしてプールの温度を維持しつつ酸性ガスの生産量と温度を下げ、すべて天然ガス化する(経路を真空にする)。というか、別に液体クーラーを用意しプールだけ冷やし続けるのがよい。
AutoHotKeyで、Everything DLLを利用してみた。
高速ファイル名検索のEverythingには外部から利用する方法がいくつかある。普段は最も手軽なes.exeを利用しているのだが、ふとDLLを利用してみた所、少しクセがあったが手順自体はシンプルで、それなりに高速化された。
DLLは公式DLページのEverything SDK内にある。関数はSDKのドキュメントに。なお別途Everythingが動いている必要がある。
SetWorkingDir %A_ScriptDir%
searchStr := "test ext:txt"
hModule := DllCall("LoadLibrary", "Str","Everything64.dll", "Ptr")
VarSetCapacity(resBuf, 65534) ; NTFSのPATH最大長*2(UTF-16)
DllCall("Everything64.dll\Everything_SetSearch", "Str",searchStr) ; クエリ発行
DllCall("Everything64.dll\Everything_Query", "Int",1) ; 実行
resNum:=DllCall("Everything64.dll\Everything_GetNumResults") ; 結果の総数を取得
hEv_GRFP := DllCall("GetProcAddress", "Ptr", hModule, "AStr", "Everything_GetResultFullPathNameW", "Ptr") ; 関数アドレス取得
res := ""
Loop, %resNum%
{
DllCall(hEv_GRFP, "int",A_Index - 1, "str",resBuf, "int",32767) ; 結果をひとつ取得
res .= resBuf "`n"
}
MsgBox, % res
DllCall("FreeLibrary", "Ptr", hModule)
GetProcAddress
でEverything_GetResultFullPathName
が見つからなくて困ってたらEverything_GetResultFullPathNameW
だった、という備忘録。ちゃんとdumpbinとかDLL Export Viewerで見なきゃダメね……。まあ、そもそも普通に呼んでも早いので高速化してるのかわからん。