【GPD P2 MAX】長音符(ハイフン)含むキーボード問題をAutoHotkeyで解決する

GPD P2 MAXの最も厄介な問題はキーボードの使い辛さだと思う。特に長音符(ハイフン)を1キーで入力できないのは致命的で、これを解決しないことには常用は難しい。

というわけで、今回は私がこの問題にどう対処しているか紹介する。

記事の要約

最後まで読んだ後に「求めているものではなかった」とならないように、先に概要を書いておく。

  • キーマップ変更ツール「AutoHotkey」を使用する
  • バックスラッシュキー(注:英語配列)を『かな入力』時のみ長音符(ハイフン)に変える
  • CtrlキーとAltキーを、単独押下時のみ『英数入力』または『かな入力』に変える

文章だと分かりづらいので、キーボードの図で示すとこんな感じ。

他のサイトでは類似ソフトの「Change Key」を使ったアプローチをよく見るけど、Change Keyでできるのはキーの入れ替えや無効化のみで、複雑な条件設定(今回行うようなIME状態による分岐やアプリケーション毎のキー設定など)ができない。

また、GPD P2 MAXはキー自体が少なく限られているため、入れ替えするにも対象キーの選別が難しい。加えて、入れ替えによって他のキー入力も犠牲になるため、結果として利便性を損なう恐れもある。

そこで、元のキーは極力変えずに、IME 状態の条件を組み合わせることで「新しい入力方法」を増やすことにした。

AutoHotkeyのインストール

AutoHotkeyのダウンロードは以下から。2019年9月現在、V2系はアルファ版なので、V1系の最新版(Current Version)を使用する。

AutoHotkey
Free keyboard macro program. Supports hotkeys for keyboard, mouse, and joystick. Can expand abbreviations as you type them (AutoText).

インストールは簡単なので割愛。設定項目はデフォルトのままでOK。

Autohotkeyファイルの作成

Windowsのどの領域でも良いので「右クリック>新規作成>AutoHotkey Script」でahkファイルを作成する。それをテキストエディタで開いて、以下のコードを入力する。

IME_GET(WinTitle="A")  {
    ControlGet,hwnd,HWND,,,%WinTitle%
    if  (WinActive(WinTitle))   {
        ptrSize := !A_PtrSize ? 4 : A_PtrSize
        VarSetCapacity(stGTI, cbSize:=4+4+(PtrSize*6)+16, 0)
        NumPut(cbSize, stGTI,  0, "UInt")  ;   DWORD   cbSize;
        hwnd := DllCall("GetGUIThreadInfo", Uint,0, Uint,&stGTI)
                 ? NumGet(stGTI,8+PtrSize,"UInt") : hwnd
    }

    return DllCall("SendMessage"
          , UInt, DllCall("imm32\ImmGetDefaultIMEWnd", Uint,hwnd)
          , UInt, 0x0283 ;Message : WM_IME_CONTROL
          ,  Int, 0x0005 ;wParam  : IMC_GETOPENSTATUS
          ,  Int, 0)     ;lParam  : 0
}

IME_SET(SetSts, WinTitle="A")    {
    ControlGet,hwnd,HWND,,,%WinTitle%
    if  (WinActive(WinTitle))   {
        ptrSize := !A_PtrSize ? 4 : A_PtrSize
        VarSetCapacity(stGTI, cbSize:=4+4+(PtrSize*6)+16, 0)
        NumPut(cbSize, stGTI,  0, "UInt")  ;   DWORD   cbSize;
        hwnd := DllCall("GetGUIThreadInfo", Uint,0, Uint,&stGTI)
                 ? NumGet(stGTI,8+PtrSize,"UInt") : hwnd
    }

    return DllCall("SendMessage"
          , UInt, DllCall("imm32\ImmGetDefaultIMEWnd", Uint,hwnd)
          , UInt, 0x0283 ;Message : WM_IME_CONTROL
          ,  Int, 0x006  ;wParam  : IMC_SETOPENSTATUS
          ,  Int, SetSts) ;lParam  : 0 or 1
}

#If IME_GET()
  \::-
#If

*~a::
*~b::
*~c::
*~d::
*~e::
*~f::
*~g::
*~h::
*~i::
*~j::
*~k::
*~l::
*~m::
*~n::
*~o::
*~p::
*~q::
*~r::
*~s::
*~t::
*~u::
*~v::
*~w::
*~x::
*~y::
*~z::
*~1::
*~2::
*~3::
*~4::
*~5::
*~6::
*~7::
*~8::
*~9::
*~0::
*~F1::
*~F2::
*~F3::
*~F4::
*~F5::
*~F6::
*~F7::
*~F8::
*~F9::
*~F10::
*~F11::
*~F12::
*~`::
*~~::
*~!::
*[email protected]::
*~#::
*~$::
*~%::
*~^::
*~&::
*~*::
*~(::
*~)::
*~-::
*~_::
*~=::
*~+::
*~[::
*~{::
*~]::
*~}::
*~\::
*~|::
*~;::
*~'::
*~"::
*~,::
*~<::
*~.::
*~>::
*~/::
*~?::
*~Esc::
*~Tab::
*~Space::
*~Left::
*~Right::
*~Up::
*~Down::
*~Enter::
*~PrintScreen::
*~Delete::
*~Home::
*~End::
*~PgUp::
*~PgDn::
    Return

*~RAlt::Send {Blind}{vk07}
RAlt up::
    if (A_PriorHotkey == "*~RAlt")
    {
        IME_SET(0)
    }
    Return

*~LCtrl::Send {Blind}{vk07}
LCtrl up::
    if (A_PriorHotkey == "*~LCtrl")
    {
        IME_SET(1)
    }
    Return

やたら長いし初見だと何をしているのか全くわからないと思うので、次章で簡単に解説する。興味ない人やとりあえず動けばよい人は読み飛ばして構わない。

Autohotkeyファイルの詳細

コードが長いので区分けにして説明する。

IME_GET(WinTitle="A")  {
    ControlGet,hwnd,HWND,,,%WinTitle%
    if  (WinActive(WinTitle))   {
        ptrSize := !A_PtrSize ? 4 : A_PtrSize
        VarSetCapacity(stGTI, cbSize:=4+4+(PtrSize*6)+16, 0)
        NumPut(cbSize, stGTI,  0, "UInt")  ;   DWORD   cbSize;
        hwnd := DllCall("GetGUIThreadInfo", Uint,0, Uint,&stGTI)
                 ? NumGet(stGTI,8+PtrSize,"UInt") : hwnd
    }

    return DllCall("SendMessage"
          , UInt, DllCall("imm32\ImmGetDefaultIMEWnd", Uint,hwnd)
          , UInt, 0x0283 ;Message : WM_IME_CONTROL
          ,  Int, 0x0005 ;wParam  : IMC_GETOPENSTATUS
          ,  Int, 0)     ;lParam  : 0
}

IMEの状態を取得する関数。IME制御用関数をまとめたIME.ahkを配布しているeamat @Cabinetから引用させていただいた。この関数なしでは生きていけない。

IME_SET(SetSts, WinTitle="A")    {
    ControlGet,hwnd,HWND,,,%WinTitle%
    if  (WinActive(WinTitle))   {
        ptrSize := !A_PtrSize ? 4 : A_PtrSize
        VarSetCapacity(stGTI, cbSize:=4+4+(PtrSize*6)+16, 0)
        NumPut(cbSize, stGTI,  0, "UInt")  ;   DWORD   cbSize;
        hwnd := DllCall("GetGUIThreadInfo", Uint,0, Uint,&stGTI)
                 ? NumGet(stGTI,8+PtrSize,"UInt") : hwnd
    }

    return DllCall("SendMessage"
          , UInt, DllCall("imm32\ImmGetDefaultIMEWnd", Uint,hwnd)
          , UInt, 0x0283 ;Message : WM_IME_CONTROL
          ,  Int, 0x006  ;wParam  : IMC_SETOPENSTATUS
          ,  Int, SetSts) ;lParam  : 0 or 1
}

IMEの状態をセットする関数。出典は先程のIME_GET()と同じ。この関数なしでは生きていけない。

#If IME_GET()
  \::-
#If

IMEがON(かな入力)の場合に、バックスラッシュキーを長音符(ハイフン)にする定義。IMEがOFF(英数入力)の場合は元のキー(バックスラッシュキー)となる。

この定義をすると、かな入力時に1タッチ(同時押し不要)で長音符を打てる代わりに、全角のバックスラッシュ(¥マーク含む)が打てなくなるのだけど、全角のバックスラッシュなんて常識的に考えていらないだろっていうのと、普段のキーボード的にもあまり違和感ない配置なので、今のところこれがベストだと考えている。

*~a::
*~b::
(~中略~)
*~PgDn::
    Return

めちゃめちゃ長いこの記述は次の定義の布石で、これ単独では意味を成さない。ちなみにこれ以降の記述は全てこの記事で公開しているahkファイルのコードを参考にしている。

*~RAlt::Send {Blind}{vk07}
RAlt up::
    if (A_PriorHotkey == "*~RAlt")
    {
        IME_SET(1)
    }
    Return

*~LCtrl::Send {Blind}{vk07}
LCtrl up::
    if (A_PriorHotkey == "*~LCtrl")
    {
        IME_SET(0)
    }
    Return

色々難しいので説明を大幅に割愛するけど、要するに「Altキー単独で打ったときは『かな入力』」、「Ctrlキー単独で打ったときは『英数入力』」になる。

単純に『かな』と『英数』を1つのキーで切り替えるほうが仕組みは簡単だけど、どうせならMacのようにIMEの状態に関係なく『かな』or『英数』を固定で切り替えられるほうが便利と考えた。

もちろん、組み合わせ時(例えばCtrl+CやAlt+Tabなど)の場合は切り替えが発生しない。あくまで単独で打ったときのみ発動する。

Autohotkeyファイルの実行

ファイル保存後、ahkファイルを右クリックして「Run Script」を実行するとスクリプトを実行(定義を反映)できる。

もし今後OS起動時に毎回実行したい場合は、Windowsスタートアップのフォルダにファイルの実体またはショートカットを配置すれば勝手に動作してくれるだろう。

余談

実はGPD P2 MAX購入後からAutoHotkeyの魅力にハマってしまい、自分用には今回紹介した以外にも様々な設定を加えている。結果、現時点でコードが500行以上になってしまった。それでも全く問題なく動作しているからすごいツールだと思う。

参考リンク

あわせてどうぞ

8.9インチUMPC「GPD P2 MAX」を購入した
9月に国内で販売開始されたGPDの新モデル「GPD P2 MAX」。実は7月に先行予約していて、先週ようやく自分の手元にも届いた。まずは軽く外観などについて紹介する。 外箱 シンプルな箱。どうでも良いけどGPDって「GamePa...
【GPD P2 MAX】ファン音を抑えるためにファームウェアをバージョンアップしてみた
GPD P2 MAXはとにかくファンがよく回る。そしてうるさい。それだけ本体が熱くなっているんだろうけど、先日ファンの回転を抑えるファームウェアが公開されたので適用してみた。 ファームウェアのダウンロードと適用 ファームウェアは以下のG...
【GPD P2 MAX】高精度タッチパッド化してジェスチャー設定を変更する
GPD P2 MAXのハック欲が止まらないので連日連投。 GPD P2 MAXはデフォルトだと高精度タッチパッドではない。そのため、3本指のジェスチャー操作は標準設定を使用せざるを得ないのだけど、これを変更できるドライバが公開されてた...
タイトルとURLをコピーしました