カテゴリー: Development

  • Maker’s Mark

    https://kozawa.tokyo/?p=1353

    タスクビュー、バグってるやん。新規に起動したときにデフォルトアイコンが表示される。スクリプトをリロードして動作確認した場合は問題なかったのに、新規で起動された場合はデフォルトのアイコンが…w これは酷い。だめだこりゃー

    バグ修正したので貼っておく。

    taskview_ext_20240623.zip

    キーのリマッピングの方は、「Alt」+「1」キーと「Alt}+「3」キーの2回目の押下で動作が違う。画面が大きくなる動作で統一した方がいいのか悪いのか、この辺りは好みの問題かもしれないけど、自分で作成すると細かいところまで自由に直せるのはいいよねえ。作りながら直しながら使えるものができるといいなぁとは思う。明日直せるかな。

    画面の移動まわりの処理を修正したので貼っておく。

    keyremap_20240623.zip

    機能追加

    ; Home/End
    !Left:: Send "{Home}"
    !Right:: Send "{End}"
    !+Left:: Send "+{Home}"
    !+Right:: Send "+{End}"
    
    ; 画面移動(上/下)
    !e:: setWindowPosition("e")
    !d:: setWindowPosition("d")
    • 上記のホットキーを追加
    • すべての画面移動についてホットキーの再押下で画面サイズを変更
    • 画面サイズの変更でユーザー定義を可能にした↓

    ユーザー定義

    初期値ではホットキーを3回押下すると元のサイズに戻ります。

    ; 画面移動ホットキーの再押下(1サイクル)
    ; 1以上の整数を指定する
    ROTATION_LENGTH := 3
    
    ; 以下の配列の先頭から「ROTATION_LENGTH」個まで使用している
    ; 再押下ごとの画面サイズを百分率で指定する
    ; Alt + [1]
    LEFT_WIDTH := [0.5, 0.6, 0.7, 0.8, 0.9, 1.0]
    ; Alt + [2]
    CENTER_WIDTH := [0.5, 0.6, 0.7, 0.8, 0.9, 1.0]
    ; Alt + [3]
    RIGHT_WIDTH := [0.5, 0.6, 0.7, 0.8, 0.9, 1.0]
    ; Alt + [qwe]
    UPPER_HEIGHT := [0.5, 0.6, 0.7, 0.8, 0.9, 1.0]
    ; Alt + [asd]
    LOWER_HEIGHT := [0.5, 0.6, 0.7, 0.8, 0.9, 1.0]

    スクリプトを編集した場合は、スクリプトの再起動が必要です。

    例1:

    ホットキーの再押下で画面サイズを変更したくない場合

    ROTATION_LENGTH := 1

    1を指定すると配列の1つ目の値だけが使用されます。0.5 = 50% の大きさで画面の幅や高さが設定されます。

    例2:

    少しずつ画面サイズを大きくする場合

    ROTATION_LENGTH := 6

    ホットキーを6回押下すると元のサイズに戻ります。

    例3:

    少しずつ画面サイズを大きくする場合2

    ; ----------------------------------------
    ; User define
    ; ----------------------------------------
    
    ;
    ; ・・・ もともとのやつ ・・・
    ;
    
    ROTATION_LENGTH := 12
    LEFT_WIDTH := [0.4, 0.5, 0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85, 0.9, 0.95, 1.0]
    CENTER_WIDTH := [0.4, 0.5, 0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85, 0.9, 0.95, 1.0]
    RIGHT_WIDTH := [0.4, 0.5, 0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85, 0.9, 0.95, 1.0]
    UPPER_HEIGHT := [0.4, 0.5, 0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85, 0.9, 0.95, 1.0]
    LOWER_HEIGHT := [0.4, 0.5, 0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85, 0.9, 0.95, 1.0]
    
    ; ----------------------------------------
    ; define
    ; ----------------------------------------

    配列の要素数や要素の値は可変です。ROTATION_LENGTHで指定した要素数だけ値を定義してください。

    変数は再代入して上書きできますので上記のようにもとものコードの下に変更した内容を追記できます。もともとのコードはコピペ時のテンプレとして使用してください。

  • Maker’s Mark

    今日はこれ。おいしーーーー! 

    メモ書き。

    タスクビュー、バグってるやん。新規に起動したときにデフォルトアイコンが表示される。スクリプトをリロードして動作確認した場合は問題なかったのに、新規で起動された場合はデフォルトのアイコンが…w これは酷い。だめだこりゃー

    キーのリマッピングの方は、「Alt」+「1」キーと「Alt}+「3」キーの2回目の押下で動作が違う。画面が大きくなる動作で統一した方がいいのか悪いのか、この辺りは好みの問題かもしれないけど、自分で作成すると細かいところまで自由に直せるのはいいよねえ。作りながら直しながら使えるものができるといいなぁとは思う。明日直せるかな。

    あとは不定期のblogの投稿よりは、1か所にまとめて記事があった方がいいよな。AutohotKey V2をインストールしてくださいみたいなところからちゃんと整理して使えるようにしたいけどしばらくはこのままかもしれない。

    パブリックドメイン

    本サイトで公開する情報は、すべてパブリックドメインに供与いたします。自由に改変していただいて構いません。著作権も含めてすべての権利を放棄いたします。

    的なことよりURLのドメインどうするかの方が悩ましい。

    https://kozawa.tokyo

    https://猫猫猫.tokyo

    実名ドメインに戻す?サブドメインとして混ぜる?

    https://猫猫猫.kozawa.tokyo

    猫猫猫さん、著名人でいたんだよなぁ。ドメイン取得前に気づくべきだった… どうしようかな。

  • タスクビュー

    少し修正したので貼っておこー

    機能追加

    • タスクトレイのアイコンに現在の仮想デスクトップの番号を表示
    • タスクトレイのアイコンのメニューからデスクトップを移動

    作ったもの

    taskview_ext_20240620.zip

    「タスクビュー」のソースファイル

    #Requires AutoHotkey v2.0+
    #SingleInstance Force
    
    ; ----------------------------------------
    ; define
    ; ----------------------------------------
    
    PREV := "Prev"
    NEXT := "Next"
    OK := True
    NG := False
    BASE_DIR := "C:\tool\taskview\"
    VDA_PATH := BASE_DIR . "VirtualDesktopAccessor.dll"
    TRAYICON_PATH := BASE_DIR . "images\"
    hVirtualDesktopAccessor := DllCall("LoadLibrary", "Str", VDA_PATH, "Ptr")
    GetDesktopCountProc := DllCall("GetProcAddress", "Ptr", hVirtualDesktopAccessor, "AStr", "GetDesktopCount", "Ptr")
    GoToDesktopNumberProc := DllCall("GetProcAddress", "Ptr", hVirtualDesktopAccessor, "AStr", "GoToDesktopNumber", "Ptr")
    GetCurrentDesktopNumberProc := DllCall("GetProcAddress", "Ptr", hVirtualDesktopAccessor, "AStr", "GetCurrentDesktopNumber", "Ptr")
    MoveWindowToDesktopNumberProc := DllCall("GetProcAddress", "Ptr", hVirtualDesktopAccessor, "AStr", "MoveWindowToDesktopNumber", "Ptr")
    
    ; ----------------------------------------
    ; helper function
    ; ----------------------------------------
    
    GetDesktopCount() {
        count := DllCall(GetDesktopCountProc, "Int")
        return count
    }
    
    GoToDesktopNumber(number) {
        if (number > GetDesktopCount())
            return
        ; Win + 左右キーのアニメーションに操作感を合わせるため、
        ; 移動前後に0.5秒の待ち時間を設定している(機能的には不要)
        Sleep 500
        DllCall(GoToDesktopNumberProc, "Int", number - 1)
        Sleep 500
    }
    
    GetCurrentDesktopNumber() {
        number := DllCall(GetCurrentDesktopNumberProc, "Int")
        number++ ; デスクトップ番号を1オリジンで指定するため + 1
        return number
    }
    
    MoveWindowToDesktopNumber(number) {
        WinWaitActive WinExist("A")
        retry := 0
        Loop
            try {
                activeHwnd := WinGetID("A")
                number-- ; dllには0オリジンで渡すため - 1
                DllCall(MoveWindowToDesktopNumberProc, "Ptr", activeHwnd, "Int", number, "Int")
                result := OK
                break
            } catch {
                Sleep 250
                result := NG
                retry++
            }
        until retry == 10
    
        return result
    }
    
    moveWindow(desktop) {
        current := GetCurrentDesktopNumber()
        max := GetDesktopCount()
        if (desktop == PREV) {
            if (current == 1) {
                result := MoveWindowToDesktopNumber(max)
            } else {
                result := MoveWindowToDesktopNumber(current - 1)
            }
        } else if (desktop == NEXT) {
            if (current == max) {
                result := MoveWindowToDesktopNumber(1)
            } else {
                result := MoveWindowToDesktopNumber(current + 1)
            }
        } else {
            result := MoveWindowToDesktopNumber(desktop)
        }
        return result
    }
    
    moveDesktop(desktop) {
        current := GetCurrentDesktopNumber()
        max := GetDesktopCount()
        if (desktop == PREV) {
            if (current == 1) {
                GoToDesktopNumber(max)
            } else {
                Send "^#{Left}"
            }
            KeyWait "Left"
        } else if (desktop == NEXT) {
            if (current == max) {
                GoToDesktopNumber(1)
            } else {
                Send "^#{Right}"
            }
            KeyWait "Right"
        } else {
            GoToDesktopNumber(desktop)
        }
    }
    
    moveWindowMoveDesktop(desktop) {
        result := moveWindow(desktop)
        if (result == OK)
            moveDesktop(desktop)
    }
    
    ; ----------------------------------------
    ; tasktray
    ; ----------------------------------------
    
    ; メニュー追加
    A_TrayMenu.Add()
    num := 1
    Loop GetDesktopCount() {
        A_TrayMenu.Add("desktop " . num, MenuHandler)
        num++
    }
    MenuHandler(itemName, itemPos, myMenu) {
        itemCount := DllCall("GetMenuItemCount", "ptr", A_TrayMenu.Handle)
        startNum := itemCount - GetDesktopCount()
        newNum := itemPos - startNum
        moveDesktop(newNum)
    }
    
    ; タスクトレイ更新
    iconNum := 1
    Loop {
        currNum := GetCurrentDesktopNumber()
        if (iconNum != currNum) {
            try {
                ; アイコン
                TraySetIcon(TRAYICON_PATH . currNum . ".png")
                ; メニュー
                num := 1
                Loop GetDesktopCount() {
                    A_TrayMenu.Uncheck("desktop " . num)
                    num++
                }
                A_TrayMenu.Check("desktop " . currNum)
            }
            iconNum := currNum
        }
        Sleep 1000
    }
    
    ; ----------------------------------------
    ; main
    ; ----------------------------------------
    
    ; アクティブ画面移動
    ^+Left:: moveWindow(PREV)
    ^+Right:: moveWindow(NEXT)
    ^+F1:: moveWindow(1)
    ^+F2:: moveWindow(2)
    ^+F3:: moveWindow(3)
    ^+F4:: moveWindow(4)
    ^+F5:: moveWindow(5)
    ^+F6:: moveWindow(6)
    
    ; デスクトップ移動
    ^#Left:: moveDesktop(PREV)
    ^#Right:: moveDesktop(NEXT)
    ^#F1:: moveDesktop(1)
    ^#F2:: moveDesktop(2)
    ^#F3:: moveDesktop(3)
    ^#F4:: moveDesktop(4)
    ^#F5:: moveDesktop(5)
    ^#F6:: moveDesktop(6)
    
    ; アクティブ画面/デスクトップ移動
    ^#+Left:: moveWindowMoveDesktop(PREV)
    ^#+Right:: moveWindowMoveDesktop(NEXT)
    ^#+F1:: moveWindowMoveDesktop(1)
    ^#+F2:: moveWindowMoveDesktop(2)
    ^#+F3:: moveWindowMoveDesktop(3)
    ^#+F4:: moveWindowMoveDesktop(4)
    ^#+F5:: moveWindowMoveDesktop(5)
    ^#+F6:: moveWindowMoveDesktop(6)
  • キーのリマッピング

    少し修正したので貼っておこー

    バグ修正

    • デスクトップのアイコンを移動させてしまう動作を修正
    • 最大化した画面を移動する場合、最大化を解除してから移動するように変更

    機能追加

    • 「Alt」+「1」「3」の再押下で画面サイズを変更
    • マルチモニターに対応(コードは入れたけどテストは未実施)

    その他

    • タスクトレイのアイコンを1つにまとめるため、以下のスクリプトが存在していたら読み込むように修正。
      「C:\tool\taskview\taskview_ext.ahk」

    作ったもの

    keyremap_20240620.zip

    「キーのリマッピング」のソースファイル

    https://ahkscript.github.io/ja/docs/v2/misc/Remap.htm

    #Requires AutoHotkey v2.0+
    #SingleInstance Force
    
    ; ----------------------------------------
    ; define
    ; ----------------------------------------
    ; デスクトップ情報
    DESKTOP_CLASS := "ahk_class Progman"
    DESKTOP_CLASS2 := "ahk_class WorkerW"
    DESKTOP_EXE := "ahk_exe explorer.exe"
    ; Alt「1」/「3」
    ROTATION_WIDTH_MINI := 0.3
    ROTATION_WIDTH_MAX := 1 - ROTATION_WIDTH_MINI
    ; Alt「2」
    CENTER_WIDTH_SIZE := 0.8
    CENTER_WIDTH_START := (1 - CENTER_WIDTH_SIZE) / 2
    
    ; グローバル変数
    previousKey := ""
    
    ; ----------------------------------------
    ; helper function
    ; ----------------------------------------
    
    ; OS情報取得
    getWinOSVersion()
    {
    	osVersion := StrSplit(A_OSVersion, ".")
    	major := osVersion[1]
    	minor := osVersion[2]
    	build := osVersion[3]
    	if (major == "10")
    		if (minor == "0")
    			if (build >= "20000")
    				return 11
    	return 10
    }
    
    ; アクティブ画面のモニター番号取得
    getMonitorNumberOfActiveWindow()
    {
    	WinGetPos(&x, &y, , , "A")
    	monitorCount := MonitorGetCount()
    	Loop monitorCount {
    		MonitorGet(A_Index, &left, &top, &right, &bottom)
    		if (x >= left
    			and x <= right
    			and y >= top
    			and y <= bottom) {
    			return A_Index
    		}
    	}
    	return 1
    }
    
    ; ディスプレイ情報取得
    getDisplayInfo(monitorNum, &x, &y, &width, &height)
    {
    	if (monitorNum.Length > 0) {
    		displayNum := monitorNum[1]
    	} else {
    		displayNum := getMonitorNumberOfActiveWindow()
    	}
    	MonitorGetWorkArea(displayNum, &left, &top, &right, &bottom)
    	x := left
    	y := top
    	width := right - left
    	height := bottom - top
    }
    
    ; 画面位置取得
    getWindowPosition(monitorNum, windowPosition, &x, &y, &width, &height)
    {
    	; ディスプレイ情報取得
    	getDisplayInfo(monitorNum, &x, &y, &width, &height)
    
    	; 画面サイズ補正
    	; 画面の左,右,下に隙間が空くので補正する。
    	; ウインドスタイル「WS_SYSMENU」が設定されていない画面は補正なし。(例:VSCode)
    	edge := 0
    	if (getWinOSVersion() == 11) {
    		style := WinGetStyle("A")
    		if (style & 0x00080000) { ; WS_SYSMENU
    			edge := 7 ; px
    		}
    	}
    
    	; 画面位置計算
    	if (windowPosition == "1min") {
    		x := x - edge
    		y := y
    		width := width * ROTATION_WIDTH_MINI + edge * 2
    		height := height + edge
    	}
    	if (windowPosition == 1) {
    		x := x - edge
    		y := y
    		width := width / 2 + edge * 2
    		height := height + edge
    	}
    	if (windowPosition == "1max") {
    		x := x - edge
    		y := y
    		width := width * ROTATION_WIDTH_MAX + edge * 2
    		height := height + edge
    	}
    	if (windowPosition == 2) {
    		x := width * CENTER_WIDTH_START
    		y := y
    		width := width * CENTER_WIDTH_SIZE + edge * 2
    		height := height + edge
    	}
    	if (windowPosition == "3min") {
    		x := width * ROTATION_WIDTH_MINI - edge
    		y := y
    		width := width * ROTATION_WIDTH_MAX + edge * 2
    		height := height + edge
    	}
    	if (windowPosition == 3) {
    		x := width / 2 - edge
    		y := y
    		width := width / 2 + edge * 2
    		height := height + edge
    	}
    	if (windowPosition == "3max") {
    		x := width * ROTATION_WIDTH_MAX - edge
    		y := y
    		width := width * ROTATION_WIDTH_MINI + edge * 2
    		height := height + edge
    	}
    	if (windowPosition == "q") {
    		x := x - edge
    		y := y
    		width := width / 2 + edge * 2
    		height := height / 2 + edge
    	}
    	if (windowPosition == "a") {
    		x := x - edge
    		y := height / 2 + y
    		width := width / 2 + edge * 2
    		height := height / 2 + edge
    	}
    	if (windowPosition == "w") {
    		x := width / 2 - edge
    		y := y
    		width := width / 2 + edge * 2
    		height := height / 2 + edge
    	}
    	if (windowPosition == "s") {
    		x := width / 2 - edge
    		y := height / 2 + y
    		width := width / 2 + edge * 2
    		height := height / 2 + edge
    	}
    	OutputDebug("x=" x " y=" y " width=" width " height=" height " windowPosition=" windowPosition)
    }
    
    ; 画面位置設定
    setWindowPosition(windowPosition, monitorNum*) {
    	global previousKey
    	try {
    		; デスクトップのアイコンが移動してしまうのでガード
    		activeHwnd := WinGetID("A")
    		GroupAdd("Desktop", DESKTOP_CLASS " " DESKTOP_EXE)
    		GroupAdd("Desktop", DESKTOP_CLASS2 " " DESKTOP_EXE)
    		desktopHwnd := WinGetID("ahk_group Desktop")
    		if (activeHwnd == desktopHwnd)
    			return
    
    		; 画面の最大化を解除
    		if (WinGetMinMax(activeHwnd) == 1)
    			WinRestore(activeHwnd)
    
    		; 「1」再押下で画面幅を変更
    		if (windowPosition == 1) {
    			if (previousKey == 1) {
    				windowPosition := "1max"
    			} else if (previousKey == "1max") {
    				windowPosition := "1min"
    			} else if (previousKey == "1min") {
    				windowPosition := 1
    			}
    		}
    		; 「3」再押下で画面幅を変更
    		if (windowPosition == 3) {
    			if (previousKey == 3) {
    				windowPosition := "3max"
    			} else if (previousKey == "3max") {
    				windowPosition := "3min"
    			} else if (previousKey == "3min") {
    				windowPosition := 3
    			}
    		}
    
    		; 移動位置取得
    		getWindowPosition(monitorNum, windowPosition, &x, &y, &width, &height)
    
    		; 画面移動
    		WinMove(x, y, width, height, activeHwnd)
    
    		; 前回の移動先保存
    		previousKey := windowPosition
    	}
    }
    
    ; ----------------------------------------
    ; main
    ; ----------------------------------------
    
    ; 矢印キー × 5
    ^Up:: Send "{UP 5}"
    ^Down:: Send "{Down 5}"
    ^Left:: Send "{Left 5}"
    ^Right:: Send "{Right 5}"
    
    ; 上下左右
    ^*i:: Send "{UP}"
    ^*k:: Send "{Down}"
    ^*j:: Send "{Left}"
    ^*l:: Send "{Right}"
    ^*u:: Send "{Home}"
    ^*o:: Send "{End}"
    
    ; 削除
    ^*h:: Send "{BS}"
    
    ; 画面移動(左/中央/右)
    !1:: setWindowPosition("1")
    !2:: setWindowPosition("2")
    !3:: setWindowPosition("3")
    
    ; 画面移動(左上/左下/右上/右下)
    !q:: setWindowPosition("q")
    !a:: setWindowPosition("a")
    !w:: setWindowPosition("w")
    !s:: setWindowPosition("s")
    
    ; 音量調整
    ^F10:: Send "{VOLUME_MUTE}"
    ^F11:: Send "{VOLUME_DOWN}"
    ^F12:: Send "{VOLUME_UP}"
    
    ; 仮想デスクトップ
    #Include "*i C:\tool\taskview\taskview_ext.ahk"

    Ctrl + 矢印キー:矢印キー5回連打
    Ctrl + iキー :上キー
    Ctrl + kキー :下キー
    Ctrl + jキー :左キー
    Ctrl + lキー :右キー
    Ctrl + uキー :Homeキー
    Ctrl + oキー :Endキー
    Ctrl + hキー :BackSpace
    Alt + 1キー :アクティブ画面左寄せ*
    Alt + 2キー :アクティブ画面中央寄せ
    Alt + 3キー :アクティブ画面右寄せ*
    Alt + qキー :アクティブ画面左上寄せ
    Alt + aキー :アクティブ画面左下寄せ
    Alt + wキー :アクティブ画面右上寄せ
    Alt + sキー :アクティブ画面右下寄せ
    Ctrl + F10 :音量ミュート
    Ctrl + F11 :音量Down
    Ctrl + F12 :音量UP

    *:機能追加

    アクティブ画面の移動先モニターの指定

    setWindowPosition関数の第2引数にモニター番号を指定します。

    例:

    !1:: setWindowPosition("1", 1)
    !2:: setWindowPosition("2", 1)
    !3:: setWindowPosition("3", 1)
    !4:: setWindowPosition("1", 2)
    !5:: setWindowPosition("2", 2)
    !6:: setWindowPosition("3", 2)

    上記の例では、「Alt」+「1~3」キーでプライマリモニタに、「Alt」+「4~6」キーでセカンダリモニターに、画面移動します。(動作未確認)

    例:

    !1:: setWindowPosition("1")
    !2:: setWindowPosition("2")
    !3:: setWindowPosition("3")

    省略時は、アクティブ画面が存在しているモニターで画面移動します。

    ! = Alt
    ^ = Ctrl
    + = Shift
    # = Win

    …φ(. . )メモメモ

  • マウスジェスチャー/タスクビュー

    ひと工夫したので貼っておこー

    やりたいこと

    マウスジェスチャーで仮想デスクトップを切り替えたい。

    やったこと

    1. 以下のサイトからMouseGestureL.ahkをダウンロードします。

    MouseGestureL.ahk
    https://hp.vector.co.jp/authors/VA018351/mglahk.html

    「MouseGestureL.ahk Ver. 1.40 (2022/06/22)」リンクから「MGLahk140.zip」をダウンロードする。

    2. ダウンロードした「MGLahk140.zip」を展開し、以下に格納します。

    C:\tool\MGLahk140
    └─Setup.vbs
    └─ ・・・

    ※格納場所任意。

    3. 「Setup.vbs」を実行し、「MouseGestureL.exe」を生成します。

    C:\tool\MGLahk140
    └─Setup.vbs
    └─ ・・・
    └─ MouseGestureL.exe

    4. 生成した「MouseGestureL.exe」を実行します。
    →タスクトレイに「MouseGestureL.ahk」が常駐します。

    5. 「MouseGestureL.ahk」を右クリックし、「設定」を選択します。

    6. マウスジェスチャーに「タスクビュー」のキーボード操作を割り当てます。

    例:RB←

    アクションスクリプト

    ;左デスクトップに移動
    SendLevel 1
    ctrl := GetKeyState("Ctrl")
    shift := GetKeyState("Shift")
    win := GetKeyState("LWin")
    if (ctrl and shift and win) {
        Send,^+#{Left}
    } else if (ctrl and shift) {
        Send,^+{Left}
    } else if (ctrl and win) {
        Send,^#{Left}
    } else {
        Send,^#{Right}
    }

    RB← + Ctrl + Shift + Win:アクティブ画面を左デスクトップに移動して、左デスクトップに移動
    RB← + Ctrl + Shift:アクティブ画面を左デスクトップに移動
    RB← + Ctrl + Win:左デスクトップに移動

    RB←:右デスクトップに移動

    例:RB→

    アクションスクリプト

    ;右デスクトップに移動
    SendLevel 1
    ctrl := GetKeyState("Ctrl")
    shift := GetKeyState("Shift")
    win := GetKeyState("LWin")
    if (ctrl and shift and win) {
        Send,^+#{Right}
    } else if (ctrl and shift) {
        Send,^+{Right}
    } else if (ctrl and win) {
        Send,^#{Right}
    } else {
        Send,^#{Left}
    }

    RB→ + Ctrl + Shift + Win:アクティブ画面を右デスクトップに移動して、右デスクトップに移動
    RB→ + Ctrl + Shift:アクティブ画面を右デスクトップに移動
    RB→ + Ctrl + Win:右デスクトップに移動

    RB→:左デスクトップに移動

    注意事項

    上記のアクションスクリプトをそのままコピペする場合は読み飛ばしてください。

    MouseGestureL.ahk も AutoHotkey で作成されています。

    AutoHotkey 1.0:ASCII版
    AutoHotkey 1.1:Unicode版
    AutoHotkey 2.0:下位互換なし、レガシーシンタックス廃止版。

    MouseGestureL.ahk は、AutoHotkey 1.1 で、「タスクビュー」は、AutoHotkey 2.0 で実行されています。

    タスクビュー
    https://kozawa.tokyo/?p=1262

    通常、AutoHotkeyで生成したキーストロークは、AutoHotkeyでは処理されません。AutoHotkeyでAutoHotkeyのホットキーをトリガーするために、アクションスクリプトでSendする前にSendLevelの指定が必要となります。

    SendLevel 1

    SendLevel
    https://ahkscript.github.io/ja/docs/v2/lib/SendLevel.htm

    下位互換はないですが、SendLevel、InputLevelまわりは互換ありです。

    7. 「軌跡・ログ」タブで「ジェスチャーの軌跡を表示する」にチェックする。(任意)

    8. 「その他」タブで「スタートアップに登録」する。管理者権限は不要です。(任意)

    9. 「OK」ボタンをクリックする。

  • タスクビュー

    書き直したやつも貼っておこー

    https://kozawa.tokyo/?p=1259

    機能追加

    Ctrl + Win + F1~F6キー:デスクトップ切り替え
    Ctrl + Shift + F1~F6キー:アクティブ画面を指定のデスクトップに移動*
    Ctrl + Shift + Win + F1~F6キー:アクティブ画面を指定のデスクトップに移動してデスクトップも移動*
    Ctrl + Win + 左右キー:デスクトップ1と6を左右キーで移動*
    Ctrl + Shift + 左右キー:アクティブ画面を隣のデスクトップに移動*
    Ctrl + Shift + Win + 左右キー:アクティブ画面を隣のデスクトップに移動してデスクトップも移動*

    *:機能追加

    もうぐちゃぐちゃ。こんなの覚えてられん。これを覚えて使おうとする人おる?環境によっては、Ctrl + Shift + 左右キーあたりは他のソフトのホットキーと被るかもしれないので人によっては使えないのだろうなぁとは分かりつつも致し方なし。

    作ったもの

    taskview_ext_20240615.zip

    「タスクビュー」のソースファイル

    #Requires AutoHotkey v2.0+
    #SingleInstance Force
    
    ; ----------------------------------------
    ; define
    ; ----------------------------------------
    
    PREV := "Prev"
    NEXT := "Next"
    OK := True
    NG := False
    VDA_PATH := "C:\tool\taskview\VirtualDesktopAccessor.dll"
    hVirtualDesktopAccessor := DllCall("LoadLibrary", "Str", VDA_PATH, "Ptr")
    GetDesktopCountProc := DllCall("GetProcAddress", "Ptr", hVirtualDesktopAccessor, "AStr", "GetDesktopCount", "Ptr")
    GoToDesktopNumberProc := DllCall("GetProcAddress", "Ptr", hVirtualDesktopAccessor, "AStr", "GoToDesktopNumber", "Ptr")
    GetCurrentDesktopNumberProc := DllCall("GetProcAddress", "Ptr", hVirtualDesktopAccessor, "AStr", "GetCurrentDesktopNumber", "Ptr")
    MoveWindowToDesktopNumberProc := DllCall("GetProcAddress", "Ptr", hVirtualDesktopAccessor, "AStr", "MoveWindowToDesktopNumber", "Ptr")
    
    ; ----------------------------------------
    ; helper function
    ; ----------------------------------------
    
    GetDesktopCount() {
        count := DllCall(GetDesktopCountProc, "Int")
        return count
    }
    
    GoToDesktopNumber(number) {
        if (number > GetDesktopCount())
            return
        ; Win + 左右キーのアニメーションに操作感を合わせるため、
        ; 移動前後に0.5秒の待ち時間を設定している(機能的には不要)
        Sleep 500
        DllCall(GoToDesktopNumberProc, "Int", number - 1)
        Sleep 500
    }
    
    GetCurrentDesktopNumber() {
        number := DllCall(GetCurrentDesktopNumberProc, "Int")
        number++ ; デスクトップ番号を1オリジンで指定するため + 1
        return number
    }
    
    MoveWindowToDesktopNumber(number) {
        WinWaitActive WinExist("A")
        retry := 0
        Loop
            try {
                activeHwnd := WinGetID("A")
                number-- ; dllには0オリジンで渡すため - 1
                DllCall(MoveWindowToDesktopNumberProc, "Ptr", activeHwnd, "Int", number, "Int")
                result := OK
                break
            } catch {
                Sleep 250
                result := NG
                retry++
            }
        until retry == 10
    
        return result
    }
    
    moveWindow(desktop) {
        current := GetCurrentDesktopNumber()
        max := GetDesktopCount()
        if (desktop == PREV) {
            if (current == 1) {
                result := MoveWindowToDesktopNumber(max)
            } else {
                result := MoveWindowToDesktopNumber(current - 1)
            }
        } else if (desktop == NEXT) {
            if (current == max) {
                result := MoveWindowToDesktopNumber(1)
            } else {
                result := MoveWindowToDesktopNumber(current + 1)
            }
        } else {
            result := MoveWindowToDesktopNumber(desktop)
        }
        return result
    }
    
    moveDesktop(desktop) {
        current := GetCurrentDesktopNumber()
        max := GetDesktopCount()
        if (desktop == PREV) {
            if (current == 1) {
                GoToDesktopNumber(max)
            } else {
                Send "^#{Left}"
            }
            KeyWait "Left"
        } else if (desktop == NEXT) {
            if (current == max) {
                GoToDesktopNumber(1)
            } else {
                Send "^#{Right}"
            }
            KeyWait "Right"
        } else {
            GoToDesktopNumber(desktop)
        }
    }
    
    moveWindowMoveDesktop(desktop) {
        result := moveWindow(desktop)
        if (result == OK)
            moveDesktop(desktop)
    }
    
    ; ----------------------------------------
    ; main
    ; ----------------------------------------
    
    ; アクティブ画面移動
    ^+Left:: moveWindow(PREV)
    ^+Right:: moveWindow(NEXT)
    ^+F1:: moveWindow(1)
    ^+F2:: moveWindow(2)
    ^+F3:: moveWindow(3)
    ^+F4:: moveWindow(4)
    ^+F5:: moveWindow(5)
    ^+F6:: moveWindow(6)
    
    ; デスクトップ移動
    ^#Left:: moveDesktop(PREV)
    ^#Right:: moveDesktop(NEXT)
    ^#F1:: moveDesktop(1)
    ^#F2:: moveDesktop(2)
    ^#F3:: moveDesktop(3)
    ^#F4:: moveDesktop(4)
    ^#F5:: moveDesktop(5)
    ^#F6:: moveDesktop(6)
    
    ; アクティブ画面/デスクトップ移動
    ^#+Left:: moveWindowMoveDesktop(PREV)
    ^#+Right:: moveWindowMoveDesktop(NEXT)
    ^#+F1:: moveWindowMoveDesktop(1)
    ^#+F2:: moveWindowMoveDesktop(2)
    ^#+F3:: moveWindowMoveDesktop(3)
    ^#+F4:: moveWindowMoveDesktop(4)
    ^#+F5:: moveWindowMoveDesktop(5)
    ^#+F6:: moveWindowMoveDesktop(6)

    インストール手順

    1.「taskview_ext_20240615.zip」ファイルを展開し、C:ドライブの直下に格納します。

    C:\tool\taskview
    └─taskview_ext.ahk

    ※格納場所固定。変更する場合は、ソース内のパス「VDA_PATH := “C:\tool\taskview\VirtualDesktopAccessor.dll”」を変更する必要がある。

    2. 以下のサイトからDLLファイルをダウンロードします。

    VirtualDesktopAccessor.dll
    https://github.com/Ciantic/VirtualDesktopAccessor

    リリースページの「VirtualDesktopAccessor.dll」をダウンロードする。
    https://github.com/Ciantic/VirtualDesktopAccessor/releases

    3. ダウンロードしたDLLファイルを同じフォルダに格納します。

    C:\tool\taskview
    ├─taskview_ext.ahk
    └─VirtualDesktopAccessor.dll

    4. 「taskview_ext.ahk」を実行します。

    アンインストール

    フォルダごと削除するだけ。

    動作確認環境

    • Windows 11
    • Autohotkey V2
    • ディスプレイ:1枚だけ

    既知の問題点

    デスクトップ1と6を左右キーで移動するときにアニメーションがない。

    その他

    IVirtualDesktopManager インターフェイス (shobjidl_core.h)
    https://learn.microsoft.com/ja-jp/windows/win32/api/shobjidl_core/nn-shobjidl_core-ivirtualdesktopmanager

    • IVirtualDesktopManager::GetWindowDesktopId
      指定された最上位ウィンドウをホストしている仮想デスクトップの識別子を取得します。
    • IVirtualDesktopManager::IsWindowOnCurrentVirtualDesktop
      指定されたウィンドウが現在アクティブな仮想デスクトップ上にあるかどうかを示します。
    • IVirtualDesktopManager::MoveWindowToDesktop
      指定した仮想デスクトップにウィンドウを移動します。

    「VirtualDesktopAccessor.dll」には、このインターフェイスでは実現できない機能が含まれているのなんで?どうやって作ってるんだろう?仮想デスクトップ周りって他にも公開情報あるのか?ググったけど見つからなかったので継続調査中・・・

    ソースファイル、助かるーけど、COM周り、シェル周り、相変わらず難しい。Rustで書かれているので、これを機にRustも触ってみようかとインストールしてドキュメントをパラパラした。

    ヒープメモリを使用する変数に所有権あるらしいな。所有権ムーブしたり変数の変更に制限をかけることで二重開放などなどが起こりえない言語仕様になってるとか、なっていないとか?メモリの管理というか、状態の管理で良くバグるのあるある。おかしな動作がパソコン再起動したら直るってそういうことですよねえ。

    所有権を理解する
    https://doc.rust-jp.rs/book-ja/ch04-00-understanding-ownership.html

    25年、29年?何も変わらないWindows のデスクトップアプリの内部、一度公開されたインターフェイスは変わらないですねえ。

    Win32 API のプログラミング リファレンス
    https://learn.microsoft.com/ja-jp/windows/win32/api

    いにしえのソースやドキュメントを見ながら酒飲んでるw 🥴

    時には昔の話を

    https://www.youtube.com/results?search_query=時には昔の話を

  • タスクビュー

    おもちゃツールを作ったので貼っておこー

    Windows標準機能

    • 「Win」+「Tab」キーで表示
    • 「Ctrl」+「Win」+「左右」キーで隣のデスクトップに移動

    やりたいこと

    「Ctrl」+「Win」+「F1~F6」キーで離れたデスクトップに直接移動

    作ったもの

    taskview_ext_20240608.zip

    「タスクビュー」のソースファイル

    ; ----------------------------------------
    ;  prerequisites
    ;  display: 1 monitor only
    ;  os: Windows 11
    ;  virtual desktop: 1 - 6
    ; ----------------------------------------
    WINCOUNT := 4
    switchDesktop(desktopId) {
        winIds := WinGetList()
        Send "#{Tab}"
        WinWaitActive ("ahk_class XamlExplorerHostIslandWindow")
        Sleep 500
        count := 0
        Loop  {
            if count == 0 {
                if winIds.Length > WINCOUNT
                    Send "{Tab}"
            } else {
                Send "{Right}"
            }
            count++
        } Until count == desktopId
        Send "{Enter}"
    }   
    ^#F1::switchDesktop(1)
    ^#F2::switchDesktop(2)
    ^#F3::switchDesktop(3)
    ^#F4::switchDesktop(4)
    ^#F5::switchDesktop(5)
    ^#F6::switchDesktop(6)

    「Ctrl」+「Win」+「F1~F6」キーでデスクトップ切り替え

    前提

    事前に仮想デスクトップが6つ作成されていることを想定している。

    動作確認環境

    • Windows 11
    • Autohotkey V2
    • ディスプレイ:1枚だけ

    機能追加予定

    ディスプレイが2枚以上あると正しく動かないことが分かっている。「Win」+「Tab」キーを押下して、単純にTabキーを送り付けて最後にEnterキーを叩いているだけなのでディスプレイの枚数が増えると必ずバグる。

    Send “{Tab}” を Send “{Tab x}” にしてTabキーの回数を修正すれば動くのだろうけど、そもそもマルチディスプレイ環境であれば、タスクビューでデスクトップを切り替えるような使い方はしないか。

    あとは、実行時にタスクビューの画面が表示されてしまい宜しくない。

    余談

    Linuxの仮想コンソールは、「Ctrl」+「Alt」+「F1~F6」キーで切り替えていた。昔のLinuxのGUIは、すぐに固まってしまい仮想コンソールからプロセスを落とすことがよくあった。

    Linuxの仮想コンソールに倣い6つの仮想デスクトップを想定している。

  • キーのリマッピング for macOS

    Karabiner-Elementsの定義ファイルをバックアップしたので貼っておこー 

    Ctrl + 矢印キー:矢印キー5回連打*
    Ctrl + iキー :上キー*
    Ctrl + kキー :下キー*
    Ctrl + jキー :左キー*
    Ctrl + lキー :右キー*
    Ctrl + uキー :Homeキー*
    Ctrl + oキー :Endキー*
    Ctrl + hキー :BackSpace*
    Alt + 1キー :アクティブ画面左寄せ
    Alt + 2キー :アクティブ画面中央寄せ
    Alt + 3キー :アクティブ画面右寄せ
    Alt + qキー :アクティブ画面左上寄せ
    Alt + aキー :アクティブ画面左下寄せ
    Alt + wキー :アクティブ画面右上寄せ
    Alt + sキー :アクティブ画面右下寄せ
    Ctrl + F10 :音量ミュート
    Ctrl + F11 :音量Down
    Ctrl + F12 :音量UP

    *:Karabinerで定義

    Karabiner-Elements

    https://karabiner-elements.pqrs.org

    Karabiner-Elements Settings画面

    Exchange control + arrow key to 5 arrow keys
    {
        "description": "Exchange control + arrow key to 5 arrow keys",
        "manipulators": [
            {
                "from": {
                    "key_code": "right_arrow",
                    "modifiers": {
                        "mandatory": [
                            "control"
                        ],
                        "optional": [
                            "any"
                        ]
                    }
                },
                "to": [
                    {
                        "key_code": "right_arrow",
                        "modifiers": []
                    },
                    {
                        "key_code": "right_arrow",
                        "modifiers": []
                    },
                    {
                        "key_code": "right_arrow",
                        "modifiers": []
                    },
                    {
                        "key_code": "right_arrow",
                        "modifiers": []
                    },
                    {
                        "key_code": "right_arrow",
                        "modifiers": []
                    }
                ],
                "type": "basic"
            },
            {
                "from": {
                    "key_code": "left_arrow",
                    "modifiers": {
                        "mandatory": [
                            "control"
                        ],
                        "optional": [
                            "any"
                        ]
                    }
                },
                "to": [
                    {
                        "key_code": "left_arrow",
                        "modifiers": []
                    },
                    {
                        "key_code": "left_arrow",
                        "modifiers": []
                    },
                    {
                        "key_code": "left_arrow",
                        "modifiers": []
                    },
                    {
                        "key_code": "left_arrow",
                        "modifiers": []
                    },
                    {
                        "key_code": "left_arrow",
                        "modifiers": []
                    }
                ],
                "type": "basic"
            },
            {
                "from": {
                    "key_code": "up_arrow",
                    "modifiers": {
                        "mandatory": [
                            "control"
                        ],
                        "optional": [
                            "any"
                        ]
                    }
                },
                "to": [
                    {
                        "key_code": "up_arrow",
                        "modifiers": []
                    },
                    {
                        "key_code": "up_arrow",
                        "modifiers": []
                    },
                    {
                        "key_code": "up_arrow",
                        "modifiers": []
                    },
                    {
                        "key_code": "up_arrow",
                        "modifiers": []
                    },
                    {
                        "key_code": "up_arrow",
                        "modifiers": []
                    }
                ],
                "type": "basic"
            },
            {
                "from": {
                    "key_code": "down_arrow",
                    "modifiers": {
                        "mandatory": [
                            "control"
                        ],
                        "optional": [
                            "any"
                        ]
                    }
                },
                "to": [
                    {
                        "key_code": "down_arrow",
                        "modifiers": []
                    },
                    {
                        "key_code": "down_arrow",
                        "modifiers": []
                    },
                    {
                        "key_code": "down_arrow",
                        "modifiers": []
                    },
                    {
                        "key_code": "down_arrow",
                        "modifiers": []
                    },
                    {
                        "key_code": "down_arrow",
                        "modifiers": []
                    }
                ],
                "type": "basic"
            }
        ]
    }
    Exchange control + h key to backspace key
    {
        "description": "Exchange control + h key to backspace key",
        "manipulators": [
            {
                "from": {
                    "key_code": "h",
                    "modifiers": {
                        "mandatory": [
                            "control"
                        ],
                        "optional": [
                            "any"
                        ]
                    }
                },
                "to": [
                    {
                        "key_code": "delete_or_backspace",
                        "modifiers": []
                    }
                ],
                "type": "basic"
            }
        ]
    }
    Exchange control + ikjl key to arrow key
    {
        "description": "Exchange control + ikjl key to arrow key",
        "manipulators": [
            {
                "from": {
                    "key_code": "i",
                    "modifiers": {
                        "mandatory": [
                            "control"
                        ],
                        "optional": [
                            "any"
                        ]
                    }
                },
                "to": [
                    {
                        "key_code": "up_arrow",
                        "modifiers": []
                    }
                ],
                "type": "basic"
            },
            {
                "from": {
                    "key_code": "k",
                    "modifiers": {
                        "mandatory": [
                            "control"
                        ],
                        "optional": [
                            "any"
                        ]
                    }
                },
                "to": [
                    {
                        "key_code": "down_arrow",
                        "modifiers": []
                    }
                ],
                "type": "basic"
            },
            {
                "from": {
                    "key_code": "j",
                    "modifiers": {
                        "mandatory": [
                            "control"
                        ],
                        "optional": [
                            "any"
                        ]
                    }
                },
                "to": [
                    {
                        "key_code": "left_arrow",
                        "modifiers": []
                    }
                ],
                "type": "basic"
            },
            {
                "from": {
                    "key_code": "l",
                    "modifiers": {
                        "mandatory": [
                            "control"
                        ],
                        "optional": [
                            "any"
                        ]
                    }
                },
                "to": [
                    {
                        "key_code": "right_arrow",
                        "modifiers": []
                    }
                ],
                "type": "basic"
            }
        ]
    }
    Exchange control + uo key to home end key
    {
        "description": "Exchange control + uo key to home end key",
        "manipulators": [
            {
                "from": {
                    "key_code": "u",
                    "modifiers": {
                        "mandatory": [
                            "control"
                        ],
                        "optional": [
                            "any"
                        ]
                    }
                },
                "to": [
                    {
                        "key_code": "home",
                        "modifiers": []
                    }
                ],
                "type": "basic"
            },
            {
                "from": {
                    "key_code": "o",
                    "modifiers": {
                        "mandatory": [
                            "control"
                        ],
                        "optional": [
                            "any"
                        ]
                    }
                },
                "to": [
                    {
                        "key_code": "end",
                        "modifiers": []
                    }
                ],
                "type": "basic"
            }
        ]
    }

    Rectangle

    https://rectangleapp.com

    アクティブ画面の移動は、Rectangleを使っていた。

    Hammerspoon

    https://www.hammerspoon.org

    Hammerspoonでスクリプトを書くとAutoHotkeyと同じようなことができる。知らんけど。

  • キーのリマッピング

    少し修正したので貼っておこー

    バグ修正

    • アクティブ画面を移動したときに画面サイズが数ピクセル分小さく表示されるバグを修正。
      Windows11の場合のみ、固定値(7px)分だけ画面サイズを拡大した。画面サイズをマウスで変更できるように1pxだけ余白を残している。
      なお、デスクトップのテーマ等によっては意図した通り補正できない可能性がある。
    • Ctrl + 矢印キーのモディファイア「*」を削除。
      Ctrl + Win + 左右キーが無効化されていたので「*」を削除した。
    • アクティブ画面の移動/リサイズに失敗した場合の動作を修正。
      スクリプトが異常終了しないように修正した。

    機能追加

    • Ctrl + iキー :上キー
    • Ctrl + kキー :下キー
    • Ctrl + jキー :左キー
    • Ctrl + lキー :右キー
    • Ctrl + uキー :Homeキー
    • Ctrl + oキー :Endキー
    • Alt + qキー :アクティブ画面左上寄せ
    • Alt + aキー :アクティブ画面左下寄せ
    • Alt + wキー :アクティブ画面右上寄せ
    • Alt + sキー :アクティブ画面右下寄せ

    作ったもの

    keyremap_20240610.zip

    「キーのリマッピング」のソースファイル

    https://ahkscript.github.io/ja/docs/v2/misc/Remap.htm

    #SingleInstance Force
    
    ; ----------------------------------------
    ; helper function
    ; ----------------------------------------
    
    ; OS情報取得
    GetWinOSVersion()
    {
    	osVersion := StrSplit(A_OSVersion, ".")
    	major := osVersion[1]
    	minor := osVersion[2]
    	build := osVersion[3]
    	If (major == "10")
    		If (minor == "0")
    			If (build >= "20000")
    				Return 11
    	Return 10
    }
    
    ; ディスプレイ情報取得
    getDisplayInfo(&x, &y, &width, &height)
    {
    	MonitorGetWorkArea(1, &Left, &Top, &Right, &Bottom)
    	x := Left
    	y := Top
    	width := Right - Left
    	height := Bottom - Top
    }
    
    ; 画面位置取得
    getWindowPosition(windowPosition, &x, &y, &width, &height)
    {
    	; ディスプレイ情報取得
    	getDisplayInfo(&x, &y, &width, &height)
    
    	; 画面サイズ補正
    	; 画面の左,右,下に隙間が空くので補正する。
    	; ウインドスタイル「WS_SYSMENU」が設定されていない画面は補正なし。(例:VSCode)
    	edge := 0
    	if (GetWinOSVersion() == 11) {
    		style := WinGetStyle("A")
    		if (style & 0x00080000) { ; WS_SYSMENU
    			edge := 7 ; px
    		}
    	}
    
    	; 画面位置計算
    	if (windowPosition == 1) {
    		x := x - edge
    		y := y
    		width := width / 2 + edge * 2
    		height := height + edge
    	}
    	if (windowPosition == 2) {
    		x := width * 0.1
    		y := y
    		width := width * 0.8 + edge * 2
    		height := height + edge
    	}
    	if (windowPosition == 3) {
    		x := width / 2 - edge
    		y := y
    		width := width / 2 + edge * 2
    		height := height + edge
    	}
    	if (windowPosition == "q") {
    		x := x - edge
    		y := y
    		width := width / 2 + edge * 2
    		height := height / 2 + edge
    	}
    	if (windowPosition == "a") {
    		x := x - edge
    		y := height / 2 + y
    		width := width / 2 + edge * 2
    		height := height / 2 + edge
    	}
    	if (windowPosition == "w") {
    		x := width / 2 - edge
    		y := y
    		width := width / 2 + edge * 2
    		height := height / 2 + edge
    	}
    	if (windowPosition == "s") {
    		x := width / 2 - edge
    		y := height / 2 + y
    		width := width / 2 + edge * 2
    		height := height / 2 + edge
    	}
    	OutputDebug("x=" x " y=" y " width=" width " height=" height)
    }
    
    ; 画面位置設定
    setWindowPosition(windowPosition) {
    	getWindowPosition(windowPosition, &x, &y, &width, &height)
    	try {
    		hwnd := WinGetID("A")
    		WinMove(x, y, width, height, hwnd)
    	}
    }
    
    ; ----------------------------------------
    ; main
    ; ----------------------------------------
    
    ; 矢印キー × 5
    ^Up::Send "{UP 5}"
    ^Down::Send "{Down 5}"
    ^Left::Send "{Left 5}"
    ^Right::Send "{Right 5}"
    
    ; 上下左右
    ^*i::Send "{UP}"
    ^*k::Send "{Down}"
    ^*j::Send "{Left}"
    ^*l::Send "{Right}"
    ^*u::Send "{Home}"
    ^*o::Send "{End}"
    
    ; 削除
    ^*h::Send "{BS}"
    
    ; 画面移動(左/中央/右)
    !1::setWindowPosition("1")
    !2::setWindowPosition("2")
    !3::setWindowPosition("3")
    
    ; 画面移動(左上/左下/右上/右下)
    !q::setWindowPosition("q")
    !a::setWindowPosition("a")
    !w::setWindowPosition("w")
    !s::setWindowPosition("s")
    
    ; 音量調整
    ^F10::Send "{VOLUME_MUTE}"
    ^F11::Send "{VOLUME_DOWN}"
    ^F12::Send "{VOLUME_UP}"
    

    Ctrl + 矢印キー:矢印キー5回連打
    Ctrl + iキー :上キー*
    Ctrl + kキー :下キー*
    Ctrl + jキー :左キー*
    Ctrl + lキー :右キー*
    Ctrl + uキー :Homeキー*
    Ctrl + oキー :Endキー*
    Ctrl + hキー :BackSpace
    Alt + 1キー :アクティブ画面左寄せ
    Alt + 2キー :アクティブ画面中央寄せ
    Alt + 3キー :アクティブ画面右寄せ
    Alt + qキー :アクティブ画面左上寄せ*
    Alt + aキー :アクティブ画面左下寄せ*
    Alt + wキー :アクティブ画面右上寄せ*
    Alt + sキー :アクティブ画面右下寄せ*
    Ctrl + F10 :音量ミュート
    Ctrl + F11 :音量Down
    Ctrl + F12 :音量UP

    *:機能追加

    既知の問題点

    モニター1台の環境を前提としているため、別途修正するかもしれない。

  • キーのリマッピング

    AutoHotkey V1→V2

    https://kozawa.tokyo/?p=886

    作ったもの

    keyremap_20240501.zip

    ファイルとして公開してなかったので今更ながら置いておく。