MouseGesture.ahk	by AutoHotkeyを流行らせるページ管理人

●概要
マウスボタン操作やカーソル移動などの組み合わせに様々な動作を割り当てる。
カーソル下ウィンドウの条件などに応じて別の動作を割り当てることも可能。

動作にはAutoHotkey(http://www.autohotkey.com/)が必要。


●ファイル説明
readme.txt
    この説明
MouseGesture.ahk
    マウスジェスチャスクリプト本体
MG_Edit.ahk
    設定編集とMG_Config.ahkの生成を行う。通常はメニューから呼び出す。
    引数に「/ini2ahk」を付けて実行すると、MG_Config.ahkの生成のみ行う

MouseGesture.ini
    設定を保存するiniファイル
MouseGesture.ini.sample
    デフォルトのiniファイル(アップデート時に上書きされないように別名とした)
MG_User.ahk
    アプリケーション定義のCustom条件や、ジェスチャに割り当てる動作から
    利用するためのサブルーチンや関数を定義しておくスクリプト。
MG_Config.ahk
    iniファイルから生成されるカスタム部分のスクリプト
MG_Buttons\
    ボタン定義モジュールを格納するフォルダ
MG_ScreenEdge\
	画面端認識機能のスクリプトモジュールとボタン定義モジュール
	使いたい場合は、中のreadme.txtを参照


●使用方法
単独で利用する場合は、MouseGesture.ahkをAutoHotkeyで実行すればよい。
トレイアイコンのメニューに追加されるサブメニューから、以下の操作が行える。

有効                ジェスチャの開始トリガーの有効/無効を切り替え
ナビ表示            入力中ジェスチャのツールチップ表示を有効/無効化
拡張スクリプト編集  「MG_User.ahk」をエディタで開く
再起動              定義スクリプトを再生成後、スクリプトを再起動する
設定編集            設定画面を開く

#Includeで他のスクリプトに組み込む場合は、組込先スクリプトと同じフォルダに
全てのファイル・フォルダを置く。
初期化処理内に#Includeを書くか、「Gosub,MG_Init」を実行すること。


○サブルーチン
ホットキーやメニューなどから利用するために、以下のサブルーチンが用意されている。

Gosub,MG_NaviToggleEnable:    ナビ表示のON/OFF
Gosub,MG_Enable:              開始トリガの有効化
Gosub,MG_Disable:             開始トリガ無効化
Gosub,MG_ToggleEnable:        開始トリガの有効/無効切り替え
Gosub,MG_Edit:                設定画面表示
Gosub,MG_EditUser:            MG_User.ahk編集
Gosub,MG_Reload:              定義スクリプトを再生成後、スクリプトを再起動



●設定画面
全体で共通のボタンの役割は以下の通り
 +          条件・ジェスチャ定義を新規作成
 -          選択項目を削除
 C          選択した定義のini形式テキストをクリップボードにコピー
 ↑         選択項目を上に移動
 ↓         選択項目を下に移動

 変更       編集中の定義名の変更
 追加       編集中のルール、ジェスチャパターン、動作割り当てを新規に登録
 更新       編集中のルール、ジェスチャパターン、動作割り当てを上書き

 OK         設定を保存し、スクリプトに反映させる
 キャンセル 設定を保存せずに終了する
 
 クリップボードからインポート
            クリップボード内のini形式テキストから定義を追加する

クリップボードへのコピー・インポートでは、掲示板などへ貼り付けることを考慮し、
Tab文字が【TAB】に置換される。


○「条件定義」タブ
ソフトごとや「タイトルバー上」などの条件に応じた動作割り当てをする場合、
あらかじめここで条件を定義しておく。
定義名には、半角英数字と「_」のみ使用でき、他の定義と同じ名前は付けられない。
「Disable」条件定義には、ジェスチャの認識処理自体を無効化したいソフトなどの
条件を列挙する。この条件定義は、削除・リネームできない。

条件種別と条件値を入力し、「追加」「更新」で登録する。
ひとつの定義に対して、複数のルールを登録できる。
通常は、ルールのどれかひとつに一致すれば条件に一致とみなされるが、
「すべてに一致」が選択されていると、列挙されたすべてのルールに一致したときのみ
その条件定義に一致したものとみなされるようになる。

各条件種別の意味は以下の通り
  WClass     ターゲットウィンドウのクラス名が値に指定した文字列と一致するか
  CClass     ターゲットコントロールのクラス名が値に指定した文字列と一致するか
  Exe        ターゲットウィンドウを所有するプロセスの名前が値と一致するか
  Title      ターゲットウィンドウのタイトルが値に指定した文字列と一致するか
  Custom     値に指定したAutoHotkeyの条件式が真になるか
  Include    値に指定した条件定義に一致しているか

ターゲットウィンドウ、ターゲットコントロールとは、ジェスチャが開始されたときに
マウスカーソル下にあったウィンドウやコントロールのことである。
クラス名は、ウィンドウの種類を識別するために付けられる名前のこと。

種別選択欄の右の「入力」ボタンを押すと、値の入力補助機能が実行される。
Customでは条件式テンプレートの選択メニュー、Includeでは条件定義選択メニュー
が表示され、それ以外では指定ウィンドウから値を取得する機能が実行される。


○「ジェスチャ定義」タブ
認識させたいジェスチャのパターンを登録する。
ひとつのジェスチャ定義に対して複数のジェスチャパターンを登録できる。
同じ内容のジェスチャは、全体で一つだけしか登録できない。

ジェスチャパターンは、カーソル移動やボタンの押し下げ・押し上げに対応した文字列
を繋げたもので表される。詳しい仕様は後述。
入力欄にパターン文字列を入力し、「追加」「更新」で、リストに登録する。
下部の入力パネルでストロークを表すボタンをクリックしたり、ボタン名リスト
をダブルクリックすることで、入力欄にパターン文字列を追加できる。
「-」ボタンで、末尾の動作を一つ削除できる。
入力欄を直接編集することも可能。


○「動作割り当て」タブ
ジェスチャ定義で登録したジェスチャが認識されたときに実行される動作を設定する

「条件」で、条件定義で登録した条件を選択し、「動作」でその条件に一致するときに
実行される動作を設定し、「追加」「更新」ボタンで登録する。
条件で「Default」を選択すると、他の割り当て済み条件に一致しなかったときの
動作を設定できる。
同時に複数の条件を満たす場合には、一番上の割り当てのみが実行されるようになる。

「動作」はAutoHotkeyのスクリプトで指定する。
下のドロップダウンリストでテンプレートを選択して「入力」ボタンを押すことで、
よく使われる動作の入力が可能である。
ただし、パラメータをを追加で記述しなければならないものもある。
特によく使われるキー操作送信コマンド「Send」の使い方については、下記URLを参照。
http://lukewarm.s101.xrea.com/commands/Send.html
Win〜系コマンドでウィンドウ指定の引数を省略したときは、ターゲットウィンドウ
が対象となる。ただし、Sendコマンドなど、ターゲットウィンドウに関係なく
Windows全体に対して作用するコマンドもある。
その他高度な機能については後述。


○「設定」タブ
各種の設定を変更する

・「ストローク認識に必要なピクセル数」
ジェスチャ認識中にこの距離以上カーソルが移動するとストロークとして認識される。
長距離ストロークについては後述。

・「タイムアウト」
「移動開始とみなされないピクセル数」以上カーソルが動いた後で、
「停止とみなす時間」以上カーソルを停止させると、ジェスチャの認識が打ち切られる。

・「ストローク認識のインターバル」
大きくすると認識処理の負荷が減るが、認識精度は低下する。

・「アクティブウィンドウをターゲットにする」
ジェスチャ開始時のカーソル下のウィンドウ・コントロールではなく、
アクティブウィンドウとフォーカスのあったコントロールをターゲットとみなす。

・「起動時からナビを有効」
入力中のジェスチャ文字列をツールチップ表示する機能を起動時からONにする。

・「矢印ナビ」
ジェスチャ文字列の代りに、入力されたストロークを矢印で表示する

・「八方向モード」
ストロークを4方向ではなく8方向で認識する

・「斜めの広さ」
真斜め(45,135,225,315度)を中心に何度の範囲を斜めとみなすか。
0にすると縦横のみに、90にすると斜めのみになる。45度で、縦横も45度の8等分となる。
斜めを認識しやすくしたい場合は60、認識されにくくしたい場合は30とするといい。
第1ストロークのみ斜めを使用する場合、「縦横の後」「斜めの後」を0にする。
縦横で開始したときは縦横のみ、斜めで開始したときは斜めのみにする場合は、
「縦横の後」を0に、「斜めの後」を90にする。

・「新規ボタン定義」
「キー」で指定したキーが「名前」で指定したボタンとして認識されるようになる。
例えば、多ボタンマウスのドライバユーティリティで第6ボタンにF13キーを割り当てて
「名前」にX3B、「キー」に「F13」と入力して「実行」を押せば、
第6ボタンが「X3B」として「ジェスチャ定義」タブのボタン一覧に追加される。
「キー」に記述するキー名については、下記URLを参照。
http://lukewarm.s101.xrea.com/KeyList.html

左右チルトや第6〜12ボタンをジェスチャ定義欄のボタン名一覧に正しく表示させたい
場合は、ボタン名をそれぞれ「LT」「RT」「X3B」〜「X9B」として定義すること。
これ以外の名前で登録されたボタンは、単にボタン名のみが表示される。


○設定画面にない設定項目
下記の設定は、MG_User.ahkの初期化処理に記述する
指定がなければデフォルト値が使われる

;;;;;矢印ナビの設定
MG_ExNaviFG=000000		;文字色(各桁がRRGGBBを表す6桁の16進数)
MG_ExNaviBG=			;背景色(〃。空白時は透明)
MG_ExNaviSize=24		;文字サイズ
MG_ExNaviSpacing=2		;文字の間隔
MG_ExNaviPadding=4		;文字と縁の間隔
MG_ExNaviMargin=8		;カーソルからの距離(-1にすると、開始位置に固定表示)

MG_ExNaviFG_RB=			;RB/X1B/X2Bなどボタンごとに色を変える場合に指定

;;;;;;ジェスチャが特定の状態になったとき、覚え書きなどのテキストを表示
MG_Tooltip_(ジェスチャ定義文字列)=
(
ジェスチャの割り当て表など
)

●ジェスチャの仕様

○ボタン操作
ボタンの押し下げは、ボタン名に続いて「_」を付けた文字列(例:LB_)で表す。
初期状態で用意されているボタン名は、「LB(左)」「RB(右)」「MB(ホイール)」
「X1B(第4)」「X2B(第5)」「WU(ホイール↑回転)」「WD(ホイール↓回転)」である。
「新規ボタン定義」機能や後述のボタン定義モジュールで追加可能。

ボタンを放す操作は、ボタンの種類は区別せず「_」で表す。
クリック(ボタンを押して離す)は、「LB__」「RB__」のように表すことになる。
ホイール回転には、ボタンを放す操作は存在しない。


○ストローク
ボタンを押したままカーソルを同じ方向に一定量動かすと、ストロークとみなされる。
4方向モードでは、上下左右へのストロークをそれぞれ「U」「D」「L」「R」で表す。
8方向モードでは、下記のようにテンキー上の位置に対応した数字で表す。

7  8  9
 ＼|／ 
4− −6
 ／|＼ 
1  2  3

8方向モードでは、「斜めの広さ」の設定が可能。
初期設定では、各方向45度である。この場合の縦横の広さは45度となる。
斜めを60度に設定した場合縦横は30度、30度に設定すれば60度になる。
これにより、縦横もしくは斜めストロークのどちらかを認識され易くできる。

第1ストロークと、縦横ストロークの後、斜めストロークの後で異なる設定も可能で、
それぞれ広さを0度や90度にすることもできる。
これにより、縦横で始めた場合は縦横ストロークのみとか、第1ストロークのみ8方向
といった設定も可能である。


○長距離ストローク
「設定」タブの「通常ストローク」で指定した以上の移動であれば、
何ピクセルでも1ストロークとみなされるが、他3つの設定で指定した距離を超えると
「LL」「RR」「UU」「DD」のような長距離ストロークとして認識される。

デフォルト設定はかなり大きめなので、一般的なディスプレイでは2段階までであるが、
設定値を小さくすれば「LLL」のような3段階以上のストロークも可能である。


○画面端への接触の認識
カーソルが画面端に達することをボタン操作として認識する機能が用意されている。
詳細は「MG_ScreenEdge」フォルダを参照。


○ジェスチャの連続発動
「RB_MB__」や「RB_L」のようなジェスチャが発動すると、押し下げ中のボタン以外の
内容がリセットされ、「RB_」まで入力された状態から認識処理が再開される。
その為、これらのジェスチャは、ボタンを押したまま何度でも連続発動できる。

なお、「RB_MB_」に動作が割り当てられている場合、ホイールボタンが押された時点で
ジェスチャが発動し、その後「RB_MB_」の状態から認識が続行される。
その後ホイールボタンを放すと「RB_MB__」の状態になる。


○「押しっぱなしで連続発動」を実現するには
「RB_LB_」など、ボタンを押し下げた時点で発動するジェスチャに、
下記のような動作を割り当てる。
MG_While()関数の詳細については後述。

if(MG_While()){
	;押している間の動作
}else{
	;放したときの動作
}


○ダブルジェスチャ
通常、「RB_LR_」や「RB__」のような操作が実行され、全てのボタンが放された
状態になると、入力中のジェスチャ内容は完全に破棄される。
その為、「RB__RB__」のような、途中で全ボタンが放されるジェスチャは認識できない。

しかし、「設定」タブのダブルジェスチャの間隔上限を設定していた場合や、
「RB__」の割り当て動作で「MG_Wait(500)」のような処理を実行した場合は、
指定された時間(ミリ秒)だけジェスチャの追加入力が可能となる。

これにより「WU_」や「WD_」などの押しっぱなしにならないボタンから開始する
ジェスチャも定義できるが、直後にはジェスチャの開始ボタンとして使われている
ボタンしか組み込めない。
例えば、「X1B_」で始まるジェスチャが存在しない場合、「WU_X1B__」のような
ジェスチャを定義しても認識されない。


○タイムアウト
認識処理中に、少しカーソルを移動してからしばらく停止すると、タイムアウトになる。
その時点で押し下げ中のボタンの押し下げ動作とカーソル移動が再現されされ、
以降は普通のマウス操作が可能になる。右D&Dをしたいときなどに利用する。

「MG_Abort()」を割り当てれば、即座にタイムアウト状態にすることも可能。


○自動リセット
認識中のジェスチャ文字列が定義されているジェスチャ文字列の最大長を超えると、
自動的に押し下げ中のボタン以外の内容がクリアされた状態になる。



●動作定義
スクリプトで使用できる機能の詳細は、下記URLのリファレンスを参照。
キー操作を発生させるSendコマンドや、ウィンドウ関連コマンドがよく使われる。
http://lukewarm.s101.xrea.com/
http://lukewarm.s101.xrea.com/commands/Send.html
http://lukewarm.s101.xrea.com/commands/index.html#window
ウィンドウ関連コマンドでは、デフォルトの対象ウィンドウがターゲットウィンドウに
なっているので、対象ウィンドウを指定する引数は省略可能である。

何も書かなければ、単に入力済みジェスチャのリセットのみが行われる。

割り当てた動作自体は、なるべく即座に終了するようにすること。
ダイアログの表示などを行いたい場合は、後述のMG_Timer()を利用する。



●ユーティリティ変数・関数
条件定義の「Custom」条件や、ジェスチャに割り当てる動作では、
以下の変数や関数を利用できる。
なお、条件定義で定義した条件判定は、「MG_Is設定名」という名前の関数として
定義される。

MG_Gesture      入力中のジェスチャ文字列
MG_TickCount    ジェスチャ開始時のA_TickCountの値(特定の時点からの経過ミリ秒)
MG_X            ジェスチャ開始座標(横)
MG_Y            ジェスチャ開始座標(縦)
MG_HWND         ジェスチャ開始座標でのマウス下ウィンドウのハンドル
MG_HCTL         ジェスチャ開始座標でのマウス下コントロールのハンドル
MG_PID          ターゲットウィンドウを所有するプロセスのPID
MG_Exe          ターゲットウィンドウを所有するプロセスの名前
MG_WClass       ターゲットウィンドウのクラス名
MG_CClass       ターゲットコントロールのクラス名
MG_Title        ターゲットウィンドウのタイトル
MG_Executed     今回のジェスチャ認識中に発動したジェスチャの数

MG_GetFocus()
	フォーカスのあるコントロールのハンドルを得る
MG_Win(cmd)
	ターゲットウィンドウからWinGet(詳細は下記URL参照)で情報を取得。
	cmdには"PID"、"Transparent"、"TransColor"、"Style"、"ExStyle"など
    http://lukewarm.s101.xrea.com/commands/WinGet.html
MG_WinX()
	ターゲットウィンドウの横座標を返す
MG_WinY()
	ターゲットウィンドウの縦座標を返す
MG_WinW()
	ターゲットウィンドウの幅を返す
MG_WinH()
	ターゲットウィンドウの高さを返す
MG_CIndex()
	ターゲットウィンドウ上にある同クラスコントロール中での
	ターゲットコントロールの順位を1からの整数で返す。
	この値は通常、コントロールが生成された順番になる。
	同じウィンドウでも、順位付けが変動する場合があるので、あまり当てにならない。
MG_ControlX()
	ターゲットコントロールのウィンドウ内での横座標を返す
MG_ControlY()
	ターゲットコントロールのウィンドウ内での縦座標を返す
MG_ControlW()
	ターゲットコントロールの幅を返す
MG_ControlH()
	ターゲットコントロールの高さを返す
MG_ExePath(pid)
	ターゲットウィンドウ(PID指定時はそのプロセス)の実行ファイルパスを取得
MG_CommandLine()
	ターゲットウィンドウの所有プロセスのコマンドラインを取得する。
	スクリプトホストなどで実行されているプログラムで、引数となったスクリプトの
	ファイル名を手がかりに判別を行いたいときに使用する。
	引数の一致判定には「InStr()」や「RegExMatch()」を使う。
MG_HitTest(c)
	ターゲットウィンドウ(c=1ならコントロール)上の場所の種類を返す
    主な返り値は"Client","Menu","HScroll","VScroll","Border","SizeBorder",
    "Caption","SysMenu","MinButton","MaxButton","CloseButton","HelpButton"。
    SysMenuというのは、タイトルバー左端のアイコンのこと。
MG_LvHitTest()
	ターゲットコントロールがリストビューの時、カーソル下にあるものの種類を返す
	返り値は、リストビュー以外では""、何もないところでは0、その他は下記文字列。
	"ItemIcon","ItemLabel","ItemState"(行選択型詳細表示の時の2列目以降など)
MG_TvHitTest()
	ターゲットコントロールがツリービューの時、カーソル下にあるものの種類を返す
	返り値は、ツリービュー以外では""、何もないところでは0、その他は下記文字列。
	"ItemIcon","ItemLabel","ItemState"(行選択型詳細表示の時の2列目以降など)
	"Indent"(項目の左),"Button"(サブアイテムの開閉ボタン),"Right"(項目の右)
MG_TreeListHitTest()
	カーソルがツリービュー、リストビューのアイテム上にあるかどうかを返す
MG_GetCursor()
	ターゲットウィンドウにおける、現在のマウスカーソルのハンドルを得る。
	Windows標準のカーソルを判別する式は、カスタム条件式の入力補助メニューから
	選択して入力できる。
MG_DumpWinInfo()
	ターゲットウィンドウ、コントロールのクラス、位置などの情報を列挙した
	文字列を返す。「MsgBox,% MG_DumWinInfo()」などとして使う。


MG_Send(btn,DorU)
    ボタン操作をエミュレートする。btnはボタン名(「"RB"」など)
    DorUが"D"なら押し下げ、"U"なら押し上げ、未指定時はクリック。
MG_Move(x,y)
    マウスカーソルを指定座標に移動する
    x,yを省略した場合、ジェスチャの開始座標に移動する
MG_Scroll(x=0,y=0,hctl=MG_HCTL)
	hctlで指定したコントロールを横にxカウント、縦にyカウントスクロールさせる
	1カウント辺りの移動量は、コントロールごとに違う
MG_InstantScroll(stay=1,ppc_x=8,ppc_y=12,hctl=MG_HCTL)
	ジェスチャ開始位置からの相対距離に応じてスクロールさせる
	ppc_x,ppc_yは、1カウントスクロールさせるのに必要な移動量
	MG_While()と組み合わせて使う。
	stay=1では、スクロールさせた分カーソル位置が戻る
	stay=0にするとカーソル位置が戻らず、IEのホイールボタンのような動作になる
MG_DragScroll(ppc_x=8,ppc_y=12,hctl=MG_HCTL)
	コントロールをドラッグして移動するような感じにスクロールさせる
MG_DropFiles(filenames=Clipboard,target=ahk_id %MG_HWND%)
	ファイルをウィンドウにドロップする。WM_DROPFILESを使用。
	第一引数は、ドロップするファイル名。改行区切りで複数指定可能。
	第一引数を省略した場合は、クリップボード内のファイル/ファイル名。
	第二引数は、PostMessageのウィンドウ指定で使われるタイトル等。
	第二引数未指定時はターゲットウィンドウが指定される。
MG_FilesToClipboard(flilenames,isMove=0)
	指定ファイルをエクスプローラなどに貼り付ける形式でクリップボードにコピー
	第一引数は、ドロップするファイル名。改行区切りで複数指定可能。
	第二引数を1にすると、貼り付けたときにコピーではなく移動されるようになる。


MG_Abort()
    ジェスチャ中に強制的にタイムアウトさせる
MG_Counter(name=MG_Gesture,count=2)
	同じnameでこの関数が呼ばれた回数をカウントする。
	name未指定時は、入力中のジェスチャ文字列が使われる。
	実行するごとに一定の順番で別の動作を発生させたい場合などに使用する。
	countが2以上の場合は、その数で割った余り(0〜count-1)を返す。
	countが1の場合は、値が0にリセットされる。
	countが0の場合は、カウントを増やした上で、現在のカウント数を返す。
	countが-1の場合は、カウント数を増やさずに、現在のカウント数を返す。
	例えば、countが2なら、実行するごとに0,1が交互に返される。
	countが負の場合は、現在の値の取得のみを行う。
MG_Wait(ms=0)
    割り当てた動作内で実行すると、ジェスチャ発動がキャンセル扱いとなり、
    入力済みジェスチャのリセットが行われず、続けて入力可能になる。
    msで待機ミリ秒数を指定すると、ダブルジェスチャの受付待ちを行う。
    これは、ダブルジェスチャの起点にしたいジェスチャが少ない場合に使う。
MG_Timer(ms)
    時間差実行のタイマーをセットする。msに待ち時間(ミリ秒)を指定。
    符号をマイナスにした値を指定した場合、MG_Wait()も実行される。
    この場合、待ち時間までの間に入力内容が変化すると、タイマーは実行されない。
    ダブルクリックと「1回のみ」のクリックで動作を分けるときなどに使う。
    msを省略すると、ジェスチャ認識処理の終了を待つ。
    これは、ダイアログ表示などの時間の掛かる処理を割り当てるときに使う。
    タイマーが実行されると、同じジェスチャサブルーチンが再度実行される。
    この関数は、タイマー登録をした場合は1、タイマーで呼ばれた場合は0を返す。
    割り当てたい動作の前に「if(MG_Timer())	return	」を書き足して使う。
MG_Defer()
	「!MG_Timer()」を返す。
	ジェスチャの認識終了を待って遅延実行するときに使う。
MG_While(ms=20)
	「RB_」や「RB_LB_」などのボタンが押されている間中繰り返し実行したり、
	ボタンを放したときに特定の動作を実行したりする。
	ジェスチャ内から呼び出すと登録され、ボタンが放されると解除される。
	ms引数が1以上の場合、msミリ秒ごとに同じジェスチャサブルーチンが実行される。
	ボタンが放されたときには、常に同じジェスチャサブルーチンが実行される。
	この関数は、登録時と繰り返し実行時は「1」を返し、解除時は「0」を返す。
	また、「MG_WhileState」変数が未登録時は0、登録時は1になっている。
	同時に実行できるのは一つのみ。
	「RB_」と「RB_LB_」など、2つ以上同時に実行することは出来ない。
MG_Hold(max=0)
	押されているボタンが放されたときに同じジェスチャサブルーチンが実行される。
	ジェスチャが発動したときには空の文字列が、ボタンが放されたときには
	ジェスチャ発動からの経過時間(ボタンを押していた長さ)が返される。
	一つのジェスチャサブルーチン中では、何度でも呼び出せる。
	「if(MG_Hold()>500){	;動作	}」のようにすることで、
	一定時間以上の長押しに動作を割り当てられる。
	「if(MG_Hold() && MG_Hold()<500){	;動作	}」で、短くクリックしたとき
	に発動させられる。
	「RB_」と「RB_LB_」など、2つ以上同時に実行することは出来ない。


●設定例
下記の設定は、設定画面の「クリップボードからインポート」で取り込み可能。
8方向モード用のストローク定義は割愛。

・標準的なジェスチャ定義
[右↑]
G=RB_U_
[右↓]
G=RB_D_
[右←]
G=RB_L_
[右→]
G=RB_R_
[右+←→]
G=RB_LR_
[右+左クリック]
G=RB_LB__
[右+中央クリック]
G=RB_MB__
[右ホイール↑]
G=RB_WU_
[右ホイール↓]
G=RB_WD_

・Ctrlキーを押しているときは無効化

[Disable]
Custom=GetKeyState("Ctrl")

・ジェスチャ認識開始時にターゲットをアクティブにする
;「Send」などで正しく操作が実行されるように
[Gesture_Start]
G=RB_
Default=WinActivate【TAB】ControlFocus,,ahk_id %MG_HCTL%


・右ボタンで下にドラッグした場合は、即座に通常のD&Dを開始する
[R_DragStart]
G=RB_D
Default=MG_Abort()


・ホイール操作をターゲットコントロールにリダイレクト

[WheelRedirectUp]
G=WU_
Default=PostMessage,0x020A,% 0x00780000|GetKeyState("LButton")|GetKeyState("RButton")<<1|GetKeyState("Shift")<<2|GetKeyState("Ctrl")<<3|GetKeyState("MButton")<<4|GetKeyState("XButton1")<<5|GetKeyState("XButton2")<<6,% MG_Y<<16|MG_X,,ahk_id %MG_HCTL%

[WheelRedirectDown]
G=WD_
Default=PostMessage,0x020A,% 0xFF880000|GetKeyState("LButton")|GetKeyState("RButton")<<1|GetKeyState("Shift")<<2|GetKeyState("Ctrl")<<3|GetKeyState("MButton")<<4|GetKeyState("XButton1")<<5|GetKeyState("XButton2")<<6,% MG_Y<<16|MG_X,,ahk_id %MG_HCTL%


・右ボタンを押しながら左移動して放すと「戻る」、右移動で「進む」

[R_Left]
G=RB_L_
Default=Send,!{Left}

[R_Right]
G=RB_R_
Default=Send,!{Right}


・右ボタンを押しながら左、右と動かしてから放すとウィンドウを閉じる

[R_LR]
G=RB_LR_
Default=WinClose

・右ボタンを押しながら左クリックで「F5」キーを送信
[R_LButton]
G=RB_LB__
Browser=Send,{F5}


・右ボタンを押しながらホイールの上下でPageUp/PageDown
[R_WheelUp]
G=RB_WU_
Default=Send,{PgUp}

[R_WheelDown]
G=RB_WD_
Default=Send,{PgDn}


・右ボタンを押しながら左ボタンを押して左、右と動かしてから一方を放すと強制終了

[R_L_LR]
G=RB_LB_LR_
Default=Process,Close,% MG_Win("pid")


・右ボタンを押しながら左から右に大きく移動してボタンを放すと全ウィンドウ最小化

[R_RightLong]
G=RB_RR_
Default=WinMinimizeAll


・その反対で復元

[R_LeftLong]
G=RB_LL_
Default=WinMinimizeAllUndo


・第5ボタンクリックで最大化/復元

[MaximizedWindow]
Custom=MG_Win("MinMax")=1

[X2B]
G=X2B__
MaximizedWindow=WinRestore
Default=WinMaximize


・第5ボタンを押しながら左右に移動すると、次々同じ種類のウィンドウを切り替え

[X2_Rights]
G=X2B_R
Default=WinSet,Bottom,,ahk_class %MG_WClass%	WinActivate,ahk_class %MG_WClass%

[X2_Lefts]
G=X2B_L
Default=WinActivateBottom,ahk_class %MG_WClass%

#第5ボタンクリックに動作を割り当てたい場合は、「if(MG_Executed=1)」をつけて
#切り替えジェスチャが発動していた場合は発動しないようにする
[X2B]
G=X2B__
Default=if(MG_Executed=1)	WinSet,Topmost,Toggle


・上記では少し動かすごとに切り替わってしまって使いづらい場合
[X2_Ignore]
G=X2B_L
G=X2B_LL
G=X2B_LLL
G=X2B_R
G=X2B_RR
G=X2B_RRR
Default=MG_Wait(1)
#MG_Wait()で続きを受け付ける場合、Thresholdピクセルの移動で次が認識される。

#途中で反対に向かった場合はリセット
[X2_Cancel]
G=X2B_LR
G=X2B_LLR
G=X2B_LLLR
G=X2B_RL
G=X2B_RRL
G=X2B_RRRL
Default=

#Thresholdで指定した距離の4倍動かすごとに発動
[X2_4Rights]
G=X2B_RRRR
Default=WinSet,Bottom,,ahk_class %MG_WClass%	WinActivate,ahk_class %MG_WClass%

[X2_Lefts]
G=X2B_LLLL
Default=WinActivateBottom,ahk_class %MG_WClass%

[X2B]
G=X2B__
Default=if(MG_Executed=1)	WinSet,Topmost,Toggle



・右ボタンを押しながら円を描くごとに実行
[R_CircleR]
#認識成功率が低すぎるので、8方向モードの定義は省略
G=RB_URDL
G=RB_RDLU
G=RB_DLUR
G=RB_LURD

IrfanView=Send,{+}

[R_CircleL]
G=RB_ULDR
G=RB_LDRU
G=RB_DRUL
G=RB_RULD

IrfanView=Send,{-}



・第5ボタンでタイトルバーをクリックすると最小化、他の部分では最前面表示ON/OFF

[TitleBar]
Custom=MG_HitTest()="Caption"

[X2B]
G=X2B__
TitleBar=WinMinimize
Default=WinSet,Topmost,Toggle


・第5ボタンのシングルクリックで行選択、ダブルクリックで全選択

[x2]
G=X2B__
Editor=MG_Send("LB")	Send,{End}+{Home}	MG_Wait(500)
#{End}+{Home}とは、[End]を押した後に[Shift]+[Home]を押すという意味
#MG_Wait(500)で続きの入力を待つ

[x2d]
G=X2B__X2B__
Editor=Send,^a


・第5ボタンのシングル・ダブル・トリプルクリックにそれぞれ別の動作を割り当て

[x2]
G=X2B__
Default=if(MG_Timer(-500))	return	Send,1

[x2d]
G=X2B__X2B__
Default=if(MG_Timer(-500))	return	Send,2

[x2t]
G=X2B__X2B__X2B__
Default=Send,3


・第5ボタンでD&Dすることにより、選択範囲の移動(カット&ペースト)を行う

#第5ボタンを押しながらマウスを動かしても無視する(「X2B_」の状態に戻す)
[X2_IgnoreStroke]
G=X2B_L
G=X2B_R
G=X2B_D
G=X2B_U
Default=

#Ctrl+Xでカット、移動先をクリック、Ctrl+Vで貼り付け
[X2_DnDMove]
G=X2B__
Default=Send,^x	MG_Send("LB")	Send,^v

#何かボタンを押せば、「X2B_LB___」のようになって発動を阻止できる



・左右チルトスクロール

[LT]
G=LT_
Default=if(MG_While()){【TAB】MG_Scroll(-3)【TAB】}

[RT]
G=RT_
Default=if(MG_While()){【TAB】MG_Scroll(3)【TAB】}



●「マウ筋」からの移行方法
適当に頑張ってください。


●「StrokeIt」からの移行方法
適当に頑張ってください。


●WindowsVistaでの制限
UACの一般権限では、管理者権限のプロセスをSendなどで操作できない。
逆にAutoHotkeyのプロセスをが管理者権限で実行されている場合、
MG_CommandLine()で一般プロセスのコマンドラインを取得できないなどの制限がある。

MG_User.ahkに「#SingleInstance,off」を記述し、Disableに「MG_CommandLine()=""」
を登録して、一般権限と管理者権限の両方でMouseGesture.ahkを実行すれば、
両方の権限のプロセスで完全に動作するような気がする。




●MouseGesture.iniの直接編集による設定
iniファイルの仕様は、テキストエディタなどでも編集しやすいように設計されている。
その代わり、エントリ・セクション名の重複が許される特殊仕様のため、
AutoHotkeyのIniWriteなどで読み書きすると壊れる可能性があることに注意。

Settingsセクションで下記の例のようにEditCommandを設定しておくと、
メニューの「設定編集」でそのコマンドが実行されるようになる。
この場合、編集後に「再起動」を実行してスクリプトに反映させる必要がある。

EditCommand="edit " . A_ScriptDir . "\MouseGesture.ini"


○ファイルフォーマット
「[セクション名]」のような行がセクションの始まり、
「名前=値」のような行がエントリして扱われる。
「#」で始まる行と空行、その他上記フォーマットに一致しない行は無視される。
半角スペースもしくはタブ文字に続く「#」から行末、
「/*」で始まる行から「*/」で終る行もコメントとして無視される。


○条件定義セクション
セクション名には、任意の英数字列で定義名を記述する。
下記のエントリ名と「G」「Default」という名前は使えない。

「WClass」「CClass」「Title」「Exe」「Custom」「Include」
という名前のエントリで、ルールを定義する。
「And=1」というエントリがあると、全てに一致した場合のみマッチとなる。


○ジェスチャセクション
ジェスチャと、それに対する動作を定義する。セクション名は何でもよい。
ジェスチャパターンを定義した「G」という名前のエントリを一つ以上含むこと。

条件別割り当ては、条件定義名や「Default」という名前をエントリ名とし、
値に動作のスクリプトを記述。
複数行のスクリプトは、Tab文字で区切って1行で記述する。


○「Settings」セクション
エントリ名は以下の物。値にはAutoHotkeyの式(通常は単なる数値)を指定。
文字列を指定する場合は、「"」で囲まなくてはならない。

Interval=           ジェスチャ認識のループ間隔(小さい方が感度が上がる)
TimeoutThreshold=   タイムアウト可能になるのに必要な移動ピクセル数
Timeout=            タイムアウト状態になるまでの静止ミリ秒
Threshold=          ストロークの認識に必要な移動ピクセル数
8Dir=               1にすると8方向モードになる
DGInterval          ダブルジェスチャの間隔の上限ミリ秒
LongThresholdX=     「LL」「RR」の認識に必要な移動ピクセル数
LongThresholdY=     「UU」「DD」の認識に必要な移動ピクセル数
LongThreshold=      8方向モードでの長距離ストローク認識に必要な移動ピクセル数
EditCommand=        「編集」メニューで実行されるコマンド


●ボタン定義モジュール仕様
マウスボタンなどの認識処理は、機能を追加し易いようにモジュール化されている。
新規モジュールは、設定画面の「設定」タブ「新規ボタン定義」で作成できる。
自分でスクリプトを作成すれば、特殊な認識処理を要するボタンも定義可能である。

モジュールは「MG_Buttons」フォルダに「名前.ahk」のような名前で保存する。
名前はD,L,R,U以外のアルファベットを最低一つ含む、なるべく簡潔な英数字列にする。
初期化処理以外のサブルーチンなどは、Gotoで飛び越すように記述すること。
また、実行時のA_ScriptDir変数は、MouseGesture.ahkのあるフォルダになるので注意。

マウスボタンのように押したままにすることが出来るものは、「トリガ」とみなされる。
トリガ定義モジュールには、以下のようなラベル名のサブルーチンを定義する。

MG_名前_Enable:         ;トリガを有効化するサブルーチン
MG_名前_Disable:        ;トリガを無効化するサブルーチン
MG_名前_Down:           ;トリガの押し下げをエミュレートするサブルーチン
MG_名前_Up:             ;トリガの押し上げをエミュレートするサブルーチン

これとは別に、トリガの認識処理を用意する。(ホットキー割り当てなど)
認識処理によって押し下げが認識されたら「MG_TriggerDown("名前")」、
押し上げが認識されたら「MG_TriggerUp("名前")」を実行し、本体に通知する。

ホイール回転のように、押し下げたままの状態が無い物は「ボタン」とみなされる。
ボタン定義モジュールの場合、以下のサブルーチンを定義する。

MG_名前_Enable:         ;ボタンを有効化するサブルーチン
MG_名前_Disable:        ;ボタンを無効化するサブルーチン
MG_名前_Press:          ;ボタン操作をエミュレートするサブルーチン

ボタンが押されたことを認識したら、「MG_ButtonPress("名前")」を実行する。



●内部用グローバル変数・関数・サブルーチン
前述のユーティリティ変数と、MouseGesture.iniのSettingsセクションの項目名に
「MG_」を付けた名前の変数(「MG_Interval」など)の他、以下の物がある。
詳細はスクリプト内容を参照。

MG_Triggers         ジェスチャの開始に使われるボタン(「_」区切り)
MG_SubTriggers      入力途中でのみ使用するボタン(「_」区切り)
MG_MaxLength        登録されているジェスチャ文字列の最大文字数

MG_Enabled          ジェスチャの開始ボタンが有効化されているか
MG_NaviEnabled      「ナビ表示」の状態

MG_Active           ジェスチャのストローク認識が実行中かどうか
MG_TimedOut         ジェスチャがタイムアウトしたかどうか
MG_Aborted          MG_Abort()で中断された場合「1」
MG_LastTime         最後にジェスチャ文字列が変化した時間(A_TickCount)

MG_CurTriggers      現在押し下げているボタンの一覧(「_」区切り)
MG_TriggerCount     現在押し下げているボタン数

MG_TimerGesture     MG_Timer()で予約したジェスチャ名
MG_TimerMode        タイマーの種類や状態を格納
MG_WaitNext         MG_Wait()で設定された待機ミリ秒

MG_ShowNavi:            ナビ表示用タイマーサブルーチン
MG_TimerExecute:        MG_Timer()のタイマーサブルーチン

MG_TriggerDown(name)    トリガボタン押し下げの報告を受け付け
MG_TriggerUp(name)      トリガボタン押し上げの報告を受け付け
MG_ButtonPress(name)    ボタン操作の報告を受け付け
MG_GetMousePosInfo()    マウスカーソル位置でMG_HWNDなどを取得
MG_Check(gesture)       入力されたジェスチャが定義済みの場合実行
                        何かが発動したら1が返る。
                        gesture引数指定時は、そのジェスチャの動作を実行。
MG_Gesture(trigger)     ジェスチャのストローク認識処理。triggerは開始ボタン
                        認識処理を行った場合は1が返る。



●更新履歴
○2008/10/07
・MG_DropFiles()、MG_FilesToClipboard()を追加

○2008/09/18
・新規ボタン定義で「~」つきのキーを定義したとき正しく動作するように変更

○2008/09/15
・MG_Hold()、MG_Defer()を追加

○2008/09/12
・MG_CommandLine()を追加

○2008/09/11
・MG_GetCursor()とそれに伴うカスタム条件式テンプレートを追加

○2008/09/08
・一部環境で「どれかに一致」の文字が表示しきれない不具合を修正
・デフォルトでトレイメニューをルートに表示するように変更
・その他

○2008/09/07
・ターゲットウィンドウ・コントロールの位置やサイズなどを取得する関数を追加
・サンプルとして登録されている設定を減らした
・その他

○2008/08/24
・MG_LvHitTest()、MG_TvHitTest()、MG_TreeListHitTest()、MG_PIDを追加

○2008/03/16
・MG_GetFocus()、MG_Counter()、MG_ExePath()追加
・不具合修正

○2008/03/13
・MG_Scroll()、MG_DragScroll()、MG_InstantScroll()追加
・「アクティブウィンドウをターゲットとする」設定を追加
・ジェスチャの開始ボタン割り当てた動作実行時ターゲットが不正になる問題修正

○2008/03/12
・画面端接触認識モジュールを作成
・設定画面に「LT」「RT」「X3B」〜「X9B」の表示名を定義した

○2008/03/01
・MG_While()追加
・引数無しMG_Timer()の後、認識処理中にジェスチャ内容が変化しても動作するように
・キーリピートがあるキーをトリガにしたときの不具合修正

○2008/02/24
・設定画面に新規ボタン定義機能を追加

○2007/12/07
・最初のトリガ押し下げにアクションを割り当てられるように変更
・ツールチップナビに指定のテキストを表示する機能を追加
・一部ファイルの改行コードがLFだけだったのをCRLFに変更

○2007/11/14
・矢印ナビの機能を追加
・起動時からナビを有効化する設定を追加

○2007/11/05
・8方向モードで、斜めとみなす角度の範囲を設定可能にした
・カーソルを移動するMG_Move()を追加
・オプション設定が保存されないバグ修正
・複数行の動作を保存すると2行目以降が消えるバグ修正
・初回起動時の処理を、同梱のMG_Config.ahkに移転

○2007/11/01
・動作割り当て画面でツールバーのボタンIDを調べる機能を追加
・スクリプトのテンプレートで、引数の入力ダイアログを出すようにした
・設定編集後にスクリプトが再起動されないのを修正

○2007/10/31
・条件定義名に使えない文字を含んだ名前の確定防止
・ジェスチャ定義の重複防止
・ジェスチャ定義のバックスペースボタン

○2007/10/30
・初期状態で起動が出来ない問題を修正

○2007/10/28
・設定画面を作成

