torazaemon2016’s blog

手書き文字認識メモ開発

AutohotkeyでGUIメニューを表示し、ペン1本で PCを操作する Ver.2

Autohotkeyを使ってGUIメニューを出すことでキーボードがなくてもPCを操作する環境を作る。(Ver.2)

前にこの話を書いて、そろそろちょうど1年なので、現在の状況にUpdateします。

今はこんなふうになっています。

カテゴリごとに色分け

前回の記事: torazaemon2016.hatenablog.jp

2025/11/21:3回目のUpdateも行っています。 torazaemon2016.hatenablog.jp

Autohotkey Ver.2 で、ボタンに色を付ける

GUI要素のButtonにColorを付けようとしてみて、 いろいろとググってみましたが、標準ではボタンの色の変更ができないようでした。

いろんな人が拡張ライブラとして作成していて、Githubなどに出ているものなどをやってみましたが、 Win32をガリガリたたいて大変そうなのと、ahkファイルとしても、1つ1つのボタンに色を付ける設定が結構面倒だったりと、 なかなか良さそうなものがありませんでした。

Autohotkey Ver.2 で、標準で色が使えるGUI要素

そんななか、標準で色を付けることができるものとして「タブ」機能があるのに気が付いたので、 Tab3 (AddTab3)を使って書いてできたのが、上記のメニューの画面です。

ahkスクリプト

 MyGui.AddTab3("X16 +BackgroundYellow",["System"])

がTab3で、色とタイトルを付けています。

本来のTab3の機能である「Tabのページが複数」という使い方をしているのではなく、 単なる1ページだけのTab3を、たくさん上下に並べているというのが、ミソです。

タブの名前が、それぞれのカテゴリの名前のようになって、わかりやすい感じになっているかと思います。

以下 全ahkスクリプト(GUI_menu.ahk)

GUI_menu()
{
    If WinExist("AHK Menu")
    {
        WinActivate
        return
    }
    
    MyGui := Gui("Resize","AHK Menu")
    MyGui.OnEvent("Escape", CloseWindow) ; [ESC] キーで閉じる
    MyGui.OnEvent("Close", CloseWindow) ; X で閉じる
    ;MyGui.BackColor := "00EE99"  ; RGB color
    ;MyGui.BackColor := 0x202020  ; 2024-09-24 ColorButton.ahk
    ;MyGui.BackColor := "Green"
    ;MyGui.BackColor := "Black"
    MyGui.BackColor := "White"
    MyGui.SetFont("s12")  ; フォントサイズ(ポイント)を設定
    
    MyGui.AddTab3("X16 +BackgroundYellow",["System"])
    MyGui.Add("Button", " X32 y+0", "Win+Tab").OnEvent("Click", Win_Tab) ;
    MyGui.Add("Button", " X+20", "1").OnEvent("Click", Win_1) ; 
    MyGui.Add("Button", " X+8 ", "2").OnEvent("Click", Win_2) ; 
    MyGui.Add("Button", " X+8 ", "3").OnEvent("Click", Win_3) ; 
    MyGui.Add("Button", " X+8 ", "4").OnEvent("Click", Win_4) ; 
    MyGui.Add("Button", " X+16 cRed", "Task Mgr").OnEvent("Click", TaskManager_click) ; 
    MyGui.Add("Button", " x+16 cRed", "Shutdown").OnEvent("Click", Shutdown_click) ; 

    MyGui.AddTab3("X16 +BackgroundFF8800",["autohotkey"])
    MyGui.Add("Button", " X32 y+1", "Edit ahk").OnEvent("Click", Edit_ahk_click) ; 
    MyGui.Add("Button", " x+8", "Edit GUI").OnEvent("Click", Edit_ahk_gui_click) ; 
    MyGui.Add("Button", " x+8", "Reload").OnEvent("Click", Reload_ahk_click) ; 

    MyGui.AddTab3("X16 +BackgroundRed",["kobo"])
    MyGui.Add("Button", " X32 y+1", "起動").OnEvent("Click", Kobo_Click) ;
    MyGui.Add("Button", " X+20", "FullScreen").OnEvent("Click", Kobo_FullScreen) ; 
    MyGui.Add("Button", " X+20", "index").OnEvent("Click", Kobo_Index) ; 
    MyGui.Add("Button", " X+20", "Esc").OnEvent("Click", Escape) ;

    MyGui.AddTab3("X16 +BackgroundFF00FF",["Launcher"])
    btn := MyGui.Add("Button", "X32 Y+0 default", "Obsidian") ;
    btn.OnEvent("Click",Obsidian_click) ;
    MyGui.Add("Button", " x+20", "Google").OnEvent("Click", Chrome_click) ; 
    MyGui.Add("Button", " x+20", "Gmail").OnEvent("Click", Gmail_click) ; 
    MyGui.Add("Button", " x+20", "Calendar").OnEvent("Click", Gcalendar_click) ; 
    
    MyGui.AddTab3("X16 +Background00FF00",["Explorer"])
    MyGui.Add("Button", " X32 y+1", "Home").OnEvent("Click", Exp_home) ;
    MyGui.Add("Button", " X+8", "Download").OnEvent("Click", Exp_download) ; 
    MyGui.Add("Button", " X+8 ", "MyDoc").OnEvent("Click", Exp_MyDoc) ; 
    MyGui.Add("Button", " X+8 ", "Desktop").OnEvent("Click", Exp_Desktop) ; 

    ;--------
    MyGui.AddTab3("X16 +BackgroundBlue",["音声、視覚"])
    MyGui.Add("Button", " X32  y+0 cRed", "音声入力").OnEvent("Click", Mic_click) ; 
    MyGui.Add("Button", " X+16 ", "拡大鏡").OnEvent("Click", Loope) ; 

    MyGui.AddTab3("X16 +Background00FFFF",["Capture"])
    MyGui.Add("Button", " x32 y+0", "Win+Shift+s").OnEvent("Click", Capture_click) ; 
    MyGui.Add("Button", " x+8", "Win+PrtScn(全画面)").OnEvent("Click", FullCapture_click) ; 
    MyGui.Add("Button", " x+16 ", "Chrome URL get").OnEvent("Click",Chrome_get_click) ; 

    MyGui.AddTab3("X16  cWhite +Background080808",["Cursor"])
    MyGui.Add("Button", " X32 y+0", "←").OnEvent("Click", Arrow_Left) ; 
    MyGui.Add("Button", " X+8 ", "↓").OnEvent("Click", Arrow_Down) ; 
    MyGui.Add("Button", " X+8 ", "↑").OnEvent("Click", Arrow_Up) ; 
    MyGui.Add("Button", " X+8 ", "→").OnEvent("Click", Arrow_Right) ; 
    MyGui.Add("Button", " X+20 ", "^{Home}").OnEvent("Click", Goto_Head) ; 
    MyGui.Add("Button", " X+8 ", "^{End}").OnEvent("Click", Goto_Tail) ; 
    ;MyGui.Add("Button", " X+8 ", "BS").OnEvent("Click", Back_space) ;

    MyGui.Add("Button", "X32 Y+20", "^入力").OnEvent("Click", Hat) ; 
    MyGui.Add("Button", "X+8 ", "全角空白 入力").OnEvent("Click", Zenkaku_space) ; 
    MyGui.Add("Button", "X+8 ", "SPC").OnEvent("Click", Hankaku_space) ; 
    MyGui.Add("Button", "X+8 ", "Tab").OnEvent("Click", Tab_space) ; 
    MyGui.Add("Button", "X+8 ", "Enter").OnEvent("Click", Enter) ; 
    ;MyGui.Add("Button", "X+8", "Date").OnEvent("Click", Date_click) ; 
    ;MyGui.Add("Button", "X+8", "Time").OnEvent("Click", Time_click) ; 
    ;MyGui.Add("Button", "X+8 ", "-").OnEvent("Click", Add_item_click) ; 
    ;MyGui.Add("Button", "X+8 ", "- [ ] ").OnEvent("Click", Add_checkitem_click) 

    Aaa := WinActive("A")
    if(Aaa != 0){
        Title := WinGetTitle("A")   ;アクティブ タイトル名を取得し Title へ格納
    } else {
        Title := "no active"
    }
    ;MyGui.Add("Text", " x16 y+20", Title)
    MyGui.Add("Text", " x16 y+20 cWhite", Title)    ; 2024-09-24 BackGroudをBlackに変更したため、文字の色をWhiteに

    ;SetTimer(UpdateMenu, 5000) ;5秒後にメニューを閉じる
    ;MyGui.Show("x100 y20")
    MyGui.Show("x1500 y20")

;--------------------
    UpdateMenu(*)
    {
        CloseWindow()
    }
;---MyGui を閉じる関数-----
    CloseWindow(*)
    {
        ;SetTimer(UpdateMenu, 0)
        ;Sleep(100)
        MyGui.Destroy()
    }
;--------------------
    Date_click(*)
    {
        MyGui.Destroy()
        ;IME_set(0)
        now := FormatTime(, "yyyy-MM-dd")
        Sleep(100)
        Send(now)
        Send(A_Space)
    }

    Time_click(*)
    {
        MyGui.Destroy()
        ;IME_set(0)
        now := FormatTime(, "HH:mm")
        Sleep(100)
        Send(now)
        Send(A_Space)
    }

    Edit_ahk_click(*)
    {
        MyGui.Destroy()
        Run("notepad++.exe `"" A_ScriptDir "\AutoHotkey_V2.ahk`"") ;このスクリプトを編集 
    }

    Edit_ahk_gui_click(*)
    {
        MyGui.Destroy()
        Run("notepad++.exe `"" A_ScriptDir "\GUI.ahk`"") ;このスクリプトを編集 
    }

    Reload_ahk_click(*)
    {
        msg := "`"Reload Autohotkey `"" 
        ToolTip(msg)
        Sleep(500)
        ToolTip()
        Reload()    ;このスクリプトをリロードして適用
        return
    }
    
    Chrome_click(*)
    {
        MyGui.Destroy()
        func_chrome_open()
    }

    Chrome_get_click(*)
    {
        MyGui.Destroy()
        func_chrome_capture()
    }

    Capture_click(*)
    {
        MyGui.Destroy()
        Send "#+s"  ; Win+Shift+s
    }

    FullCapture_click(*)
    {
        MyGui.Destroy()
        Sleep(1000)
        Send("#{PrintScreen}")
        Sleep(1000)
        Run("C:\Users\xxxxxxxx\Pictures\Screenshots")
        return
    }
    
    Gmail_click(*)
    {
        MyGui.Destroy()
        browser := "C:\Program Files\Google\Chrome\Application\chrome.exe --disk-cache-dir=R:\Temp"
        Run(browser " `"https://mail.google.com/mail/u/0/#inbox`"")
    }
    
    Gcalendar_click(*)
    {
        MyGui.Destroy()
        browser := "C:\Program Files\Google\Chrome\Application\chrome.exe --disk-cache-dir=R:\Temp"
        Run(browser " `"https://calendar.google.com/calendar/u/0/r?pli=1`"")
    }
    
    Exp_home(*)
    {
        Run("C:\Users\xxxxxxxx\")
    }
    Exp_Download(*)
    {
        Run("C:\Users\xxxxxxxx\Downloads")
    }
    Exp_MyDoc(*)
    {
        Run("C:\Users\xxxxxxxx\Documents")
    }
    Exp_Desktop(*)
    {
        Run("C:\Users\xxxxxxxx\Desktop")
    }
    
    
    Obsidian_Click(*)
    {
        MyGui.Destroy()
        func_obsidian()
    }

    Add_item_click(*)
    {
        MyGui.Destroy()
        Sleep(50)
        Send "- "           ; 行末へ移動
    }
    Add_checkitem_click(*)
    {
        MyGui.Destroy()
        Sleep(50)
        Send "- [ ] "           ; 行末へ移動
    }

;---画面リストアする(またメニューを表示する)-----
    Arrow_Left(*)
    {
        MyGui.Hide()    ; メニュー消す (アクティブがエディタ画面に)
        Sleep(50)       ; ちょっと待つ(速すぎるとアクティブが切り替わらない)
        Send "{Left}"   ; ←移動
        Sleep(50)       ; ちょっと待つ
        ;Title := WinGetTitle("A")  ;アクティブ タイトル名を取得し Title へ格納
        MyGui.Restore() ; Guiメニューを表示する
        ;SetTimer(UpdateMenu, 5000)
    }
    Arrow_Right(*)
    {   
        MyGui.Hide()
        Sleep(50)
        Send "{Right}"          ; →移動
        Sleep(50)
        ;Title := WinGetTitle("A")  ;アクティブ タイトル名を取得し Title へ格納
        MyGui.Restore() ; Gui を表示する
        ;SetTimer(UpdateMenu, 5000)
    }
    Arrow_Down(*)
    {
        MyGui.Hide()
        Sleep(50)
        Send "{Down}"           ; ↓移動
        Sleep(50)
        ;Title := WinGetTitle("A")  ;アクティブ タイトル名を取得し Title へ格納
        MyGui.Restore() ; Gui を表示する
        ;SetTimer(UpdateMenu, 5000)
    }
    Arrow_Up(*)
    {
        MyGui.Hide()
        Sleep(50)
        Send "{Up}"         ; ↑移動
        Sleep(50)
        ;Title := WinGetTitle("A")  ;アクティブ タイトル名を取得し Title へ格納
        MyGui.Restore() ; Gui を表示する
        ;SetTimer(UpdateMenu, 5000)
    }
    Goto_Head(*)
    {
        MyGui.Hide()
        Sleep(50)
        Send "^{Home}"  ; 先頭へ移動
        Sleep(100)
        ;Title := WinGetTitle("A")  ;アクティブ タイトル名を取得し Title へ格納
        MyGui.show() ; Gui を表示する
        ;SetTimer(UpdateMenu, 5000)
    }
    Goto_Tail(*)
    {
        MyGui.Hide()
        Sleep(50)
        Send "^{End}"           ; 末尾へ移動
        Sleep(100)
        ;Title := WinGetTitle("A")  ;アクティブ タイトル名を取得し Title へ格納
        MyGui.show() ; Gui を表示する
        ;SetTimer(UpdateMenu, 5000)
    }
    
    Hankaku_space(*)
    {
        MyGui.Hide()
        Sleep(50)
        Send " "
        Sleep(100)
        ;Title := WinGetTitle("A")  ;アクティブ タイトル名を取得し Title へ格納
        MyGui.show() ; Gui を表示する
        ;SetTimer(UpdateMenu, 5000)
    }

    Zenkaku_space(*)
    {
        MyGui.Hide()
        Sleep(50)
        Send " "
        Sleep(100)
        ;Title := WinGetTitle("A")  ;アクティブ タイトル名を取得し Title へ格納
        MyGui.show() ; Gui を表示する
        ;SetTimer(UpdateMenu, 5000)
    }
    
    Hat(*)
    {
        MyGui.Hide()
        Sleep(50)
        Send "{^}"
        Sleep(100)
        ;Title := WinGetTitle("A")  ;アクティブ タイトル名を取得し Title へ格納
        MyGui.show() ; Gui を表示する
        ;SetTimer(UpdateMenu, 5000)
    }

    Enter(*)
    {
        MyGui.Hide()
        Sleep(30)
        Send("{Enter}")
        Sleep(30)
        ;Title := WinGetTitle("A")  ;アクティブ タイトル名を取得し Title へ格納
        MyGui.show() ; Gui を表示する
        ;SetTimer(UpdateMenu, 5000)
    }

    Tab_space(*)
    {
        MyGui.Hide()
        Sleep(50)
        Send("{Tab}")
        Sleep(100)
        ;Title := WinGetTitle("A")  ;アクティブ タイトル名を取得し Title へ格納
        MyGui.show() ; Gui を表示する
        ;SetTimer(UpdateMenu, 5000)
    }

    Back_space(*)
    {
        MyGui.Hide()
        Sleep(50)
        Send("{BS}")
        Sleep(100)
        ;Title := WinGetTitle("A")  ;アクティブ タイトル名を取得し Title へ格納
        MyGui.show() ; Gui を表示する
        ;SetTimer(UpdateMenu, 5000)
    }

    Escape(*)
    {
        MyGui.Hide()
        Sleep(50)
        Send("{Esc}")
        Sleep(100)
        ;Title := WinGetTitle("A")  ;アクティブ タイトル名を取得し Title へ格納
        ;MyGui.show() ; Gui を表示する
        ;SetTimer(UpdateMenu, 5000)
    }

    ;-------------
    Kobo_Click(*)
    {
        MyGui.Destroy()
        Run("C:\Program Files (x86)\Kobo\Kobo.exe") ;
    }
    Kobo_FullScreen(*)
    {
        MyGui.Hide()
        Sleep(50)
        if WinActive("ahk_exe kobo.exe")
        { 
            Send("#{Up}")
            Sleep(500)
            ;MsgBox "kobo.exe"  ;
            Click 2851, 60  ; Surface Pro8
            Sleep(300)
            Click 1350. 1   ; これでフォーカスを ページ送りにする(拡大じゃなくて)
        }
    }
    Kobo_Index(*)
    {
        MyGui.Hide()
        Sleep(50)
        if WinActive("ahk_exe kobo.exe")
        { 
            ;MsgBox "kobo.exe"  ;
            Click 10,10 
        }
    }

;---画面リストアする(またメニューを表示する)-----
; もっといい方法(フリーソフト(VirtualDesktop, WindowsVirtualDesktopHelperなど))もあるので、各自改良どうぞ
; WindowsVirtualDesktopHelperを常駐させ、タスクバーの< 1 >の<>場所を押すあたりがahkっぽいかと
;4画面使っているので、その間での移動
    Win_1(*)
    {
        MyGui.Hide()    ; メニュー消す (アクティブがエディタ画面に)
        Sleep(100)      ; ちょっと待つ(速すぎるとアクティブが切り替わらない)
        Send("#^{Left}#^{Left}#^{Left}")    
    }
    Win_2(*)
    {
        MyGui.Hide()    ; メニュー消す (アクティブがエディタ画面に)
        Sleep(100)      ; ちょっと待つ(速すぎるとアクティブが切り替わらない)
        Send("#^{Left}#^{Left}#^{Left}")
        Sleep(100)      ; ちょっと待つ(速すぎるとアクティブが切り替わらない)
        Send("#^{Right}")
    }
    Win_3(*)
    {
        MyGui.Hide()    ; メニュー消す (アクティブがエディタ画面に)
        Sleep(50)       ; ちょっと待つ(速すぎるとアクティブが切り替わらない)
        Send("#^{Right}#^{Right}#^{Right}#^{Left}")
    }
    Win_4(*)
    {
        MyGui.Hide()    ; メニュー消す (アクティブがエディタ画面に)
        Sleep(50)       ; ちょっと待つ(速すぎるとアクティブが切り替わらない)
        Send("#^{Right}#^{Right}#^{Right}")
    }
    
    Win_Tab(*)
    {
        MyGui.Hide()    ; メニュー消す (アクティブがエディタ画面に)
        Sleep(50)       ; ちょっと待つ(速すぎるとアクティブが切り替わらない)
        Send("#{Tab}")
;       Sleep(50)       ; ちょっと待つ
;       Title := WinGetTitle("A")   ;アクティブ タイトル名を取得し Title へ格納
;       MyGui.Restore() ; Guiメニューを表示する
;       SetTimer(UpdateMenu, 5000)
    }

    Mic_click(*)
    {
        MyGui.Hide()    ; メニュー消す (アクティブがエディタ画面に)
        Sleep(100)      ; ちょっと待つ(速すぎるとアクティブが切り替わらない)
        Send("#h")
        Sleep(50)       ; ちょっと待つ
        Title := WinGetTitle("A")   ;アクティブ タイトル名を取得し Title へ格納
        ;MyGui.Restore() ; Guiメニューを表示する
        MyGui.Show("NA") ; GuiメニューをNotActiveに
        ;SetTimer(UpdateMenu, 5000)
    }
    
    ; 拡大鏡
    Loope(*)    
    {
        MyGui.Hide()    ; メニュー消す (アクティブがエディタ画面に)
        msg := "1秒以内に拡大したいところをクリックしてください"
        ToolTip(msg)
        Sleep(1000)
        ToolTip()
        Sleep(1000)     ; ちょっと待つ(速すぎるとアクティブが切り替わらない)
        Send("#;")
        Sleep(50)       ; ちょっと待つ
        ;Title := WinGetTitle("A")  ;アクティブ タイトル名を取得し Title へ格納
        ;MyGui.Restore() ; Guiメニューを表示する
        ;MyGui.Show("NA") ; Guiメニューを表示する
        ;SetTimer(UpdateMenu, 5000)
    }
 
    TaskManager_Click(*)
    {
        MyGui.Destroy()
        Run("C:\ProgramData\Microsoft\Windows\Start Menu\Programs\System Tools\Task Manager.lnk")
    }
    
    Shutdown_click(*)
    {
        MyGui.Destroy()
        func_shutdown()
    }

}

func_shutdown()
{
    MyGui := Gui(,"Shutdown")
    MyGui.BackColor := "FF0000"  ; 赤
    MyGui.SetFont("s32")  ; 大きなフォント
    MyGui.Add("Text",, "Shutdown")
    MyGui.Add("Button", " default", "OK").OnEvent("Click", OK_click) ; ;
    MyGui.OnEvent("Escape", CloseWindow) ; [ESC]でダイアログを閉じる
    MyGui.show() ; Gui を表示する

    OK_Click(*)
    {
        Run("C:\Windows\system32\shutdown.exe /s /f /t 0")
        return
    }
    CloseWindow(*)
    {
        MyGui.Destroy()
    }
}

1つ1つのボタンに色を付けたいわけではなく、 たくさん増えたボタンが、それぞれどんな役割かが一目わかればいいので、 ちょうどいい感じになっています。

色は、以下で適当に付けていますので、もっと上手にやってみてください。

色の指定 - AutoHotkey Wiki

あと、HWRシリーズも、更新しています。 torazaemon2016.hatenablog.jp

音声認識もできるので、どんどん文章ができていきます。 キーボードなしでも、タブレットWindows PCで文章を作ることが捗るようになりました。

最大の問題だった、漢字を忘れていて書けないので、手書き入力は効率が悪い、は、 最近のWindowsUpdateによる、かな漢字変換可能なTextBoxによって解決しました!

torazaemon2016.hatenablog.jp

AutohotkeyやTouch Panel Gesturesで、キーボードがなくても快適です。

torazaemon2016.hatenablog.jp