見出し画像

【AutoHotKey】Shiftを長押しせずに範囲選択するコード【ahk】

0. 追記 ※必読

 この記事で紹介するのは改良する前のコードです。改良版のコードはこちらをご覧ください。2022/09/07追記。


1. はじめに ※必読

 【Shift】を長押しすることなく範囲選択するコードをオートホットキーで書いたので公開します。
 本稿には必読部分(前半)とそうではない部分(後半)があります(後半部は随時書き足していくつもりです)。お忙しい方も、必読部分は必ずすべて読んでからご使用・ご利用ください。


2. 何をするためのコードなのか & 使い方 ※必読

2-1. 何をするためのコードなのか

 【Shift】を長押ししなくてもキーボードで範囲選択できるようにするためのコードです(英数字入力の際に使えば疑似的なCaps Lockとしても機能します)。

2-2. 使い方

  • 【無変換 + スペース】で範囲選択モード(私が勝手に命名した)を開始します。

  • 範囲選択モード中は、【Shift】を長押しすることなく、矢印キーやマウスカーソルだけで選択領域(青い部分)を変更できます。

  • もう一度、【無変換 + スペース】を押すと範囲選択モードを終了します。


3. コードを使用・利用するための条件 ※必読

 このコードを使用または利用した結果に関して、私(投稿主)は一切の責任を負わないことに同意したうえで、ご使用・ご利用ください。同意は使用・利用の必要条件とします。


4. 投稿主の環境 ※必読

 私の環境をごく簡単に紹介します。

  • Windows 11

  • AutoHotkey Unicode 64-bit (ver. 1.1.34.03)

 上記以外の環境での動作や影響は一切検証していませんので、ご注意ください。


5. 実際のコード ※必読

 下のコードをコピペして、スクリプトをリロードすれば、使えるようになります。ただし、「rs := 0」はスクリプトの上の方に置いてください。そうしないと、機能しない可能性があります。

#MaxThreadsPerHotkey 2



rs := 0



sc07B & Space::
if GetKeyState("Shift")
{
	rs := 0
	Return
}
Else
{
	rs := 1
	Gosub, Range_Selection01
	Return
}
Return



Range_Selection01:
	CoordMode, ToolTip, Screen
	ToolTip, --RS_IN_EFFECT---RS_IN_EFFECT--`n--RS_IN_EFFECT---RS_IN_EFFECT--, 1670, 980
	Loop
	{
	    Send {Shift down}
	    Sleep 30
	}Until rs = 0
	Send, {Shift up}
	ToolTip
Return


6. 既知の問題と対処法 ※必読

 このコードの問題と対処法をいくつかお伝えします。

6-1. 万が一の暴走とその際の対処法

 万が一、範囲選択モードが暴走した時は、タスクバー上にある、このコードを含むスクリプトのオートホットキーアイコンを【右クリック】し、【Exit】を押してください。そのあと、2~3回ゆっくりと【Shift】を押せば、暴走も終わります。

6-2. Chromeとの相性

 残念ながらこのコードはChrome(バージョン: 104.0.5112.81(Official Build) (64 ビット))とあまり相性が良くないようで、Chrome上での使用にいくつか問題があります。それらの問題を回避するために、Chrome上で範囲選択モードを使用するときには次の鉄則に従ってください;「選択範囲をキーボードショートカットでコピーまたは切り取りしたいときは、範囲選択モードを終了させてから、ショートカットを入力せよ!」。言い換えると、範囲選択モードの状態のままでショートカットを使用するな、ということです。この鉄則さえ守れば、Chrome上でも問題なく範囲選択モードを使用できるはずです。

6-3. 範囲選択モードONとOFFの瞬間的な切り替え

 範囲選択モードを何度も瞬間的に切り替えると(【無変換 + スペース】を何度も連打すると)、たまに、切り替えが正常に行われず選択範囲がスペース一個分と置換されてしまうときがあります(加えて、入力方式が全角英数字に切り替わっています)。おそらく、本当なら【無変換 + スペース】が送信されなければならないのに、【無変換】が零れ落ちて【スペース】だけが送信されてしまっているのでしょう。
 原因が不明なので根本的な対処法は今のところ分かりません。が、強いて言うなら、範囲選択モードのON/OFFの切り替えを瞬間的には行わないようにする(【無変換 + スペース】を連打しないようにする)という対策があるでしょうか。

6-4. 無変換キーの機能が失われる

 これは何かの不具合ではなく、オートホットキーの仕様です。「sc07B & Space::」の部分を「~sc07B & Space::」に置き換えることにより、無変換キーの機能は保持されますが、より厄介な問題が生じるのでお薦めできません。


7. 記事の折り返し地点 ※必読

 この節が最後の必読部分です。お伝えしておきたいことをいくつか個別的に記します。

7-1. コード公開の動機について

 私はITやプログラミングの門外漢です。そんな私がこのコードを公開したのには三つの動機があります。

  1.  第一に、「この記事を見たプログラミングに詳しい方が、私のコードの不完全な箇所を指摘してくれたらいいな」と思ったからです。もし私のコードに改善の余地があれば、この記事のコメント欄で指摘していただけたら幸いです。

  2.  第二に、「プログラミングに詳しい方が私のコードを叩き台にして、範囲選択のための、より良いコードを作ってくれたらいいな」と思ったからです。もしそのような方がいらっしゃたら、出来上がったコードをネットで公開し、その旨をこの記事のコメント欄でお知らせいただけたら、これまた幸いです。

  3.  最後に、「せっかく書いたのだから、他の人の役にも立ってくれたら嬉しいな」というシンプルなものです。

7-2. この記事のリンクの掲載について

 もしこの記事のリンクを、ご自身のブログやサイト等に掲載されたいという方がいらっしゃいましたら、私への連絡はせずに、ご自由に掲載してください。

7-3. 上記コードの、商売への利用について

 もし万が一、この記事のコードを何らか商売のためにご使用・ご利用したい方がいらっしゃったら、ご自由にどうぞ。その際も私への連絡はしないでください。

7-4. 記事の後半部分について

 この記事の後半部分では、コードの概説、Chromeで起こる問題の紹介、プロトタイプ(試作版)の紹介などをします。前半の必読部分では省略した情報を含んでいるので、このコードへの理解を深めたい方は読まれることをお薦めします。

 ※ここで必読部分は終わりです。読んでくださり、ありがとうございました。
 では後半に続きます。


8. コードの解説

 上記のコードは大きく分けて次の四つの部分から構成されています。

  1. #MaxThreadsPerHotkey 2

  2. rs := 0

  3. 「sc07B & Space::」で始まる部分

  4. 「Range_Selection01:」で始まる部分

この節では、これらを一つずつ解説します。

8-1. #MaxThreadsPerHotkey 2

 これは#MaxThreadsPerHotkeyコマンドで、上記のコードでは、一つのホットキーを同時に2重まで起動できるように設定しています。これを設定しておかないと、一度範囲選択モードを発動すると、二度と解除できなくなります。
 ちなみに、似た名前の#MaxThreadsコマンドがありますが別物です。

8-2. rs := 0

 ここでは、「rs」という変数を導入し、その変数に値0を代入しています。
 また、「5. 実際のコード ※必読」で書いたように、この部分はスクリプトの上のほうに書かないといけません。理由は、Auto-executeセクションで調べてみてください。
 ちなみに、「rs」という変数の名前は Range Select (範囲選択)から名付けました(範囲選択モード中の画面右下の表示の「RS」も同じ由来です)。

8-3. 「sc07B & Space::」で始まる部分

 この部分はさらに、一行目と、二行目以降に分解できます。
 一行目は「【無変換 + スペース】で二行目以降の内容を実行する」という意味です。
 二行目以降は、GetKeyState()コマンドを利用することで、【無変換 + スペース】と一緒に、【Shift】が押されるか否かで分岐しています。
 もし【Shift】が【無変換 + スペース】と共に押されていたら、 rs に値0を代入します。
 もし【無変換 + スペース】だけが押されたら、 rs に値1を代入し「Range_Selection01」(四つ目の部分)を実行します。

8-4. 「Range_Selection01:」で始まる部分

 まずスクリーン右下に「--RS_IN_EFFECT---RS_IN_EFFECT--」の表示を出して(CoordModeコマンドToolTipコマンド)、【Shift】を30ミリ秒ごとに連続入力します(LoopコマンドSendコマンド)。この連続入力は rs に0が代入されるまでずっと続きます(Untilコマンド)(同様の挙動はBreakコマンドでも実現可能です)。 rs に0が代入されたら、【Shift】の押し上げを一度入力し、画面右下の表示を消します。

 以上でコード解説を終わります。


9. Chromeで起こる問題

 6-2で既に述べた通り、このコードはChromeと相性が良くありません。この節では具体的にどのような問題が起こるかを説明します。

9-1. 範囲選択モード中に【Ctrl + c】を使うとデベロッパーツールが起動してしまう

 小見出しどおりの不具合です。原因はChrome独自のキーボードショートカットです。Chromeでは【Ctrl + Shift + c】でデベロッパーツールが起動するというショートカットがあるので、そちらに判定が吸われてしまうようです。

9-2. 範囲選択モード中に【Ctrl + x】を押しても切り取りが行われない

 こちらも小見出しどおりですが原因不明です。

 今のところChromeで確認できている問題はこの二つであり、6-2に書いた鉄則(Chromeでは範囲選択モード中に【Ctrl + c】【Ctrl + x】を使用しない)に基づけばどちらも回避できます。
 9節は以上です。


10. プロトタイプの紹介


いいなと思ったら応援しよう!