TrackPointのは便利なんだけど、中ボタンが使えないのはもったいない! でも、いちいちタスクトレイから切り替えるのも面倒だ。
AHKでトレイアイコンを操作するスクリプトを使ってもいいが、 一瞬メニューがでるし、何しろ1ステップ多いのが嫌だ!と言う人向け。普通のマウスだとあまり便利でないかもしれない。 (マウスを普段使っていないので試してない)
まぁ、一応ってことで。以下が必要
TW.ahk
をそのまま実行するTW.ini
を編集して、
もう一度 TW.ahk
を実行する。(特に停止したりしなくても良い)
テキストエディタ(メモ帳なのかっ!)で設定ファイル(デフォルトでは TW.ini
) を開く。
そこに説明が書いてあるのでよく読んで編集すること。
編集が終わったらスクリプトを再起動する。よく分かんないときは、Appendix でも読んでくれ。
フォントは MSゴシック とかの等幅フォントを使わないと大変なことに。
ここは 設定ファイル(デフォルトでは "TW.ini" ) の [connfig
セクションをについて説明をする。
Button
LButton
, RButton
, MButton
, XButton1
, XButton2
からいずれかを選んで記載する。
Timeout
Icon
debug
Bypass
デバッグモードをOnにして機能を利用するとスクロール対象のクラス以外に以下の情報が取得できる。 これをみて色々把握しないと設定が出来ないので頑張って理解してくれ。
Wheel
, Scroll
, VKey
のいずれかを選択したかと、
方向逆転(~)が表示される。(基本的に設定ファイルの文字列がそのまま出る)
動作感度、動作閾値、ページモード閾値のそれぞれX軸、Y軸のものが表示される。未設定の場合はデフォルト値が出る。
X軸・Y軸のそれぞれの単位時間あたりの原点(ボタン押下座標)からの 移動量(dx/dt, dy/dt)とそれが行数に変換されたものが表示される。
上段の移動量は、②の数値群を用いて下段のスクロール行数に変換される。
デバッグモードにすると、縦横各方向のスクロール方法が表示される。 スクロール方法は以下から選択する。
Scroll2
よりレスポンスが良い。none
とかにしてスクロールさせないのも手。(Dynamic Function を利用してる)これを理解する上で以下の数値が必要となる。よく読んで、適当に設定するように。
いわゆる「遊び」である。
小さな移動量でスクロールしていたらちょっと触れただけでもすぐに移動してしまい都合が悪い。 デフォルトでは X軸は10、Y軸は 1 を設定してある。 これにより縦スクロール中にあまり横スクロールをしなくて済む。
動作閾値は X,Y軸それぞれに値がある。更に、操作対象毎の設定も可能である。
この図では、X軸方向へは閾値を超えていないので、行数は0行と算出されれている。
移動量をどうスクロール量に反映させるかを計算する時に用いる数値である。 計算式は以下の通り。
つまり小さいほどピンキーで、大きいほど鈍い。(1 や 2 、逆に 100 や 200 だと実用にならないはず。)
※ 動作閾値を補正するのは、動作閾値を超えた瞬間に大きくスクロールしないようにするため
行数 = Round((移動量-動作閾値分の補正) / 動作感度)
「ま、なんて単純!」と思ったアナタ。まーこんなもんですよ。 あと、見ても分かるとおり、0 を設定したらゼロ除算でこけますので注意。
これは "Scroll2" を利用したときのみに利用される数値である。 "Scroll2" を利用した場合どのような動作をしているかというと、 スクロールバーの[▲]を上で算出した行数分だけ押すのをエミューレートしている。
これが結構チマチマとしかスクロールしないし、多くの行をスクロールさせようとした場合には たくさんの命令をループで回して送らなければならないので重くなる。
で、なにを言いたいかというと、スクロールバーの「ボタン([▲][▼)」]や 「つまみ」(移動する棒状のやつ)以外の部分をクリックすると一気にページ毎の スクロールに変わるわけだが、それに切り替えるための閾値である。
デフォルトでは縦・横ともに8となっている。 8回以上[▲]押すくらいなら一気に1ページスクロールしてしまえ!ってことである。
通常、ボタン (Button
) とかテキストトラベル (Static
) なんつークラスは、
どうせスクロールなんてしない。でもマウス直下にあると無視できない。
と言うわけで、これらの上位の(見た目上は下側に隠れた)コントロールに制御を渡したい。そんなときに使うのがバイパス。
設定ファイル内では Bypass
に設定をするが、正規表現 での設定なので分からない場合はいじらぬが吉である。
この図ではうまいことにスクロールできるコントロールまでたどり着いている。 というか、クラス名が長すぎて TrayTip が切れている。今気づいたが見なかったことにしよう...
全くの余談だが、この後このプロセスが 1.5GB メモリを消費していたので速攻殺してやった。悪名高い Catalyst である...
動かしかたが分かりません。
設定を Wheel
とか VKey
にしてやってください。
それでも無理なら諦めて...
Word2002とかエクスプローラに左ペインなんて全く分からない...
多分Office系だと思う...。座標だけで割り出すのは限界が...
仕様です。一応、グローバル変数の TW_PRIORITY_HIGH
の値を真にすると
機能実行中だけプロセスの優先度を「高」にしたりする機能があったり無かったり...
仕様です。マウスフックですから...
仕様です。アプリケーションレベルのフックはフックは後勝ちなのかな?スクリプトを再起動するといいかも。
多分他のユーザのプロセス(スレッド)のはず。
ファイル名を指定して実行とかのダイアログのインクリメンタルサーチの部分はシステムプロセスだったり・・・
フック処理に失敗していると思われる
デバッグを On にするとマイドキュメントにエラーログを吐くはず
大変危険な状態です。 対象ウィンドウに色々メッセージを送っている最中にハングしているものと見られるので利用を止めましょう。
パワーポイントのノート欄(下ペイン)とは激しく相性が悪いです...
対処法なんてわかりません。素人が作ったものなんで。
TW.ahk
をインクルードする。なるべくAutoexecブロック内には書かないように。
(関数ライブラリスクリプトとして利用する場合はこの宣言は必要ない。)
#Include, hoge\TW.ahk
初期化関数を呼び出す。普通は Autoexec ブロックに記載する。
TW_Initialize()
設定ファイルを明示的に指定したい場合は、引数で指定する。
なお、設定ファイルはデフォルトで 初期化関数が呼ばれた時点のカレントディレクトリ
内にある "TW.ini
" を見に行くので、色々やっている人は注意。
TW_Initialize("hoge.ini")
設定ファイルの Button
の定義を外して(空にする)、
自スクリプト内で、ホットキー登録をする。
; 例1) 発動条件をIf文で指定する場合 ; AutoExecブロックで初期化する TW_Initialize() ; ホットキー設定をする $*MButton:: if (a condition) TW_HotkeyStart() ; ホットキーでの開始用関数を叩く else if (another conditon) ~~~ else Send, {Blind}{MButton} return
; 例2) IfWinActive 等を利用する場合 #IfWinActive, HogeApp *MButton::TW_HotkeyStart() ; ホットキーでの開始用関数を叩く
終了後に呼ばれるサブルーチンを設定すれば良い。
グローバル変数 TW_POSTACTION
にサブルーチンラベルを設定すれば、
TrackWheel側からコールを行う。
※ このグローバル変数は初期値なしである。
; Autoexecブロックでサブルーチンラベルの設定をする。 TW_POSTACTION = SomeLabel TW_Initialize() ; 任意の場所にサブルーチンラベルをかく SomeLabel: タイムアウトしなかった時の処理 return
なお、以下のコードは意図した(?)とおりに動かない。 おそらく常に If 文は真となる。 スクロール開始処理と、スクロール実体処理、およびスクロール終了処理は別スレッドで動くため、 開始処理自体はフラグを立てる様なもので、あまり時間はかからないからである。
*MButton:: TW_HotkeyStart() if (A_TimeSinceThisHotkey < 300) タイムアウトしなかった時の処理 else タイムアウトしたときの処理 return
マウスボタン押下で機能のON/OFFをトグルする場合は、以下のようにする。この方式はマウスボタン専用である。
MButton::TW_HotkeyToggle() ; トグル用の開始関数を叩く
需要はないと思うが、キーボードの場合は上を使わないで以下のようにする。 この方式はキーボード専用である。
#Space::TW_HotkeyToggleByKey() ; キーボード用のトグル関数を叩く
こんな感じ
A_ThisHotkey
から然るべきマウス押上メッセージ(=終了メッセージ)にするSetWindowsHookEx
) して上記メッセージを拾うようにするこんな感じ
GetScrollInfo
を該当コントロールに投げてコントロール自体がスクロール出来るかを見る最初は常時 Mouse Hook On で考えて作ってたんだけど、AHKのマウスフックが全く効かなくなるのが痛かった。 じゃあ、別の単体スクリプトにしてメインスクリプトからメッセージ送るって方法をやったけど、
結構苦労した。コード量は大したことがないけど大変な作業だった...。そのときの考察したメモ。 もし、読む気があるなら、、、添付の "窓調査.ahk" を利用するとわかりやすいはず。
Target Control | ∧ | ||
∨ | |||
< | > |
一番よく見るタイプ。スクロールする必要が生じたら、自分の中にスクロールバーを作るタイプ。
各種設定画面とかでよく見る、入力欄(Edit, RichEdit)、
リスト(ComboBox, ListBox)、表(ListView)、
ツリー(TreeView)など。
これらは、ホイール命令(WM_MOUSEWHELL
)や、スクロール命令(WM_VSCROLL
/WM_HSCROLL
)
によく反応してくれる。
厳密さを求めるなら、user32.dll
の GetScrollInfo
または GetScrollPos
関数で
スクロールの情報が取得できるもの。
Target Control | ∧ | ||
∨ | |||
< | > |
これもよく見かけるタイプ。 入力も出来るしリストから選択も出来るドロップダウンリスト等(ComboBoxの上に Editが乗っている)とか、ボタン(Button)とか ラベル(Static)の上でスクロールするのも同じ。 要は、Type1に該当する汎用コントロールの上に他の汎用コントロールが乗ってるやつ。
対象コントロール自体はスクロールバーを持たないが、ホイール・スクロール命令を透過するものが多いので そのまま命令を送信すればスクロールしてくれる。
透過しない場合は、Bypass
にクラス名を追加し、
明示的に1段階上のコントロールに処理を委譲するような設定をする。
なお、上位コントロールもBypass対象ならば更に上位へとバイパス対象でないところまでいく(トップレベルウィンドウで止まる)。
Target Control |
|
|||
|
上のものと構成がにてるけど、厄介というか個別対応が必要なもの。 汎用コントロールでは実現できない各種アプリのコントロールが該当。 Word, PowerPoint 等オフィス系アプリでよく見る。
スクロールバーは自分と同位に並べられた、別コントロールってパターン。
ホイール命令(WM_MOUSEWHELL
)は対象コントロールに送ればスクロールしてくれるが、
スクロール命令(WM_VSCROLL
/WM_HSCROLL
)はそれぞれのスクロールバーを探して、
それらに送信しないとスクロールしない事が多いヤツら。
スクロールバーの識別子(クラス)が "ScrollBar" ってやつなら探すのもそう大変ではないけど、 対象コントロールと同じ名前だったりするヤツがあって面倒なものも多い。 あとはペイン分割だったりとか、MDI子ウィンドウだったりとか・・・
OpenOffice.org などの Java 系のアプリは中身が Windows の汎用コンポーネントを使っていないので、 内部構造が全く取得できない。調査ツールの画面を見れば一目瞭然である。
コマンドプロンプトも同じ。
まぁ、でも今の判定ルーチンだと Unknown は Wheel + Wheel になるのでコイツらは無問題。
むやみに変えないでね。ただでさえ不安定なので。
TW_TARGET_XXX
は大抵デバッグに出しているはず。
変数名 | 型(?) | 説明 |
---|---|---|
TW_ASSIGNED | Str | アサインされたホットキー名 |
TW_BYPASS | Str | バイパス対象クラス設定 |
TW_BYPASS_CLASSES | Str | バイパスされたクラスリスト(改行区切り) |
TW_CALLBACK_HWND | Handle | コールバック対象のウィンドウハンドル(GUIのウィンドウハンドル) |
TW_CONFIG_FILE | Str | 設定ファイルパス |
TW_DEBUG | Bool | デバッグフラグ |
TW_DEFAULT_OPTION | Str | デフォルトオプション |
TW_DEFAULT_PX TW_DEFAULT_PY |
Int | デフォルトのページモード閾値 |
TW_DEFAULT_RULE_H TW_DEFAULT_RULE_V |
Str | デフォルトのスクロールルール |
TW_DEFAULT_SX TW_DEFAULT_SY |
Int | デフォルトの動作感度 |
TW_DEFAULT_TX TW_DEFAULT_TY |
Int | デフォルトの動作閾値 |
TW_DIFF_ACCUM_COUNT | Int | 差分蓄積回数。マウスフックプロシージャで利用。マウスが動く度にスクロールにしていたら埒があかないのでこの回数分ためてからスクロールに変換する |
TW_GUINO | Int | GUI番号 |
TW_HIDE_MOUSE | Bool | マウスカーソルを消すかどうかのフラグ。動きが怪しいならこれを常時OFFにすべき。 |
TW_HOTKEY_NAME | Str | 機能を発動したホットキー名。TW_ASSIGNED とどう違うのと聞かれると痛い。でもやっぱり違う。 |
TW_HOTKEY_START | Int | ホットキーで機能を開始したOS経過時間(A_TickCount)。 |
TW_ICON | File | アイコンパス |
TW_MOUSE_PROC | Handle | マウスフックプロシージャのハンドル。消すとマズい。 |
TW_MOUSEHOOK | Handle | マウスフックのハンドル。動作中だけ値が入っている(はず)。Unhookに失敗したら残る。 |
TW_MSG_CALLBACK | Msg | コールバックに利用するメッセージ番号。消すとマズい。 |
TW_MSG_STOP | Msg | マウスフックを停止させる、ウィンドウメッセージ(マウス系に限る)。ボタン押下時に決定する |
TW_MY_THREAD | ThreadId | 自分自身のスレッドId |
TW_POSTACTION | Str |
後処理用サブルーチンラベル名。デフォルトは空。 IsLabel()でチェックして、後処理関数内で参照して呼び出す。 |
TW_PRIORITY_HIGH | Bool |
動作時に優先度を上げる場合に true にする。 デフォルトは未設定(偽) |
TW_REVERSE_H TW_REVERSE_V |
Bool | 方向反転フラグ。要はルールに "~" が付いたやつ |
TW_SCROLL_FUNCH TW_SCROLL_FUNCV |
Str | スクロール関数名(の接尾辞) |
TW_SCROLLINFO_H TW_SCROLLINFO_V |
Struct | WM_HSCROLL, WM_VSCROLL を行う時に必要なの情報を格納した構造体 |
TW_TABLE | Str |
個別設定情報格納テーブル(CSVをそのままメモリに)。MsgBox, %TR_TABLE% とかで確認できる。ボタン押下後にこいつを展開して、 TW_TARGET_XXX にする。
|
TW_TARGET_CLASS_CTRL TW_TARGET_CLASS_WIN |
Str | 操作対象ウィンドウ/コントロールのクラス名 |
TW_TARGET_HANDLE_CTRL TW_TARGET_HANDLE_WIN |
Handle | 操作対象ウィンドウ/コントロールのウィンドウハンドル |
TW_TARGET_PX TW_TARGET_PY |
Int | 操作対象のページモード閾値 |
TW_TARGET_SBV |
Int |
廃止→ 構造体 TW_SCROLLINFO_H , TW_SCROLLINFO_V で吸収
|
TW_TARGET_SCROLLV |
Int |
廃止→ 構造体 TW_SCROLLINFO_H , TW_SCROLLINFO_V で吸収
|
TW_TARGET_SX TW_TARGET_SY |
Int | 操作対象の動作感度 |
TW_TARGET_THREAD | ThreadId | 操作対象のスレッドID。動作中だけ値が入っている(はず)。デタッチに失敗したら残る。 |
TW_TARGET_TX TW_TARGET_TY |
Int | 操作対象の動作閾値 |
TW_TARGET_X TW_TARGET_Y |
Int | 開始時点のマウス座標 |
TW_TIMEOUT | Int | ホットキータイムアウト時間 |
スクロール(WM_HSCROLL/WM_VSCROLL)を行うときに必要な情報を格納する。
スクロールバー探索関数 TW_FindScrollBar
内でセットする。
内部の値を参照するときは、関数 TW_ScrollInfo_GetXxx()
を使用する。
Type SCROLLINFO { type UShort(2bytes) ; スクロールバーの種別 (SB_HORZ | SB_VERT | SB_CTL) hScrollBar UInt (4bytes) ; スクロールバーのウィンドウハンドル hTarget UInt (4bytes) ; スクロールメッセージを送るコントロールのウィンドウハンドル } ... 10 bytes
凡例: Wheel: WM_MOUSEHWHEEL/WM_MOUSEWHEEL, Scroll: WM_HSCROLL/WM_VSCROLL, VKey: VK_LEFT/VK_RIGHT; VK_UP/VK_DOWN
○:OK, ×:NG, ▲:備考欄参照, -:試す意義を感じず, ?:試す機会なし
Component Name | Window Class | Control Class | Horizontal | Vertical | Recommended Rule | Notes | ||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
Wheel | Scroll | Scroll2 | VKey | Wheel | Scroll | Scroll2 | VKey | |||||
Gecko | * | MozillaWindowClass | ○ | × | × | ○ | ○ | × | × | ○ | ~Wheel, Wheel | HWheelの向きに逆に反応する感じなので。 VKeyの場合は要フォーカス変更(フレームクリック) |
Trident(IE6) | * | Internet Explorer_Server | × | ○ | × | ○ | ○ | × | ○ | ○ | Scrolll, Wheel | Scrollの方がレンダリングの関係上スムーズ。 Scroll,VKeyの場合は要フォーカス変更(フレームクリック) |
ListView | * | SysListView32 | × | × | ○ | - | ○ | × | ○ | - | Scroll2,Scroll2 | |
ListView | * | TListView | × | × | ○ | - | ○ | × | ○ | - | Scroll2,Scroll2 | |
TreeView | * | SysTreeView32 | × | ○ | ○ | - | ○ | ○ | ○ | - | *Auto Detect* | |
TreeView | * | TTreeView | × | ○ | ○ | - | ○ | ○ | ○ | - | *Auto Detect* | |
ListBox | * | ListBox | - | - | - | - | ○ | ○ | ○ | - | *Auto Detect* | |
ListBox | * | TListBox | - | - | - | - | ○ | ○ | ○ | - | *Auto Detect* | |
ComboBox | * | ComboBox | - | - | - | - | ○ | ○ | ? | - | *Auto Detect* | |
ComboBox | * | TComboBox | - | - | - | - | ○ | ○ | ? | - | *Auto Detect* | |
Edit | * | Edit | × | ○ | ○ | - | ○ | ○ | ○ | - | *Auto Detect* | |
Edit | * | TMDITextView | ? | ? | ? | - | ○ | ○ | ○ | - | *Auto Detect* | |
Edit | * | TMemo | ? | ? | ? | - | ○ | ○ | ○ | - | *Auto Detect* | |
RichEdit | * | RichEdit* | × | ○ | ○ | - | ○ | ○ | ○ | - | *Auto Detect* | |
Java SWT | * | SWT_Window0 | × | ○ | ○ | - | ○ | ○ | ○ | - | *Auto Detect* | コントロールのレイヤーが異常なヤツ(Eclipseの設定画面とか)は無理。 |
凡例: Wheel: WM_MOUSEHWHEEL/WM_MOUSEWHEEL, Scroll: WM_HSCROLL/WM_VSCROLL, VKey: VK_LEFT/VK_RIGHT; VK_UP/VK_DOWN
○:OK, ×:NG, ▲:備考欄参照, -:試す意義を感じず, ?:試す機会なし
Application Name | Window Class | Control Class | Horizontal | Vertical | Recommended Rule | Notes | ||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
Wheel | Scroll | Scroll2 | VKey | Wheel | Scrool | Scrool2 | VKey | |||||
(XP)メモ帳 | Notepad | Edit | × | ○ | ○ | - | ○ | ○ | ○ | - | *Auto Detect* | |
(XP)ワードパッド | WordPadClass | RICHEDIT50W | × | ○ | ○ | - | ○ | ○ | ○ | - | *Auto Detect* | Wheelはレンダリングが追いつかない事がある |
(XP)ペイント | MSPaintApp | Afx:* | × | ○ | ○ | - | ○ | ○ | ○ | - | *Auto Detect* | |
(XP)プログラムのの追加と削除 | NativeHWNDHost | DirectUIHWND | ? | ? | ? | ? | ○ | × | × | × | *Auto Detect* | 横スクロールバーは出ない...はず |
(XP)コマンドプロンプト | ConsoleWindowClass | N/A | × | × | × | - | ○ | × | × | × | *Auto Detect* | コントロールクラスがとれない。 |
Excel 2002 | XLMain | EXCEL7 | × | ○ | ○ | - | ○ | ○ | ○ | - | *Auto Detect* | ScrollLock+VK_XXという手も有りか。 |
Word 2002 | OpusApp | _WwG | × | ○ | ○ | - | ○ | × | ○ | - | Scroll, Scroll2 | 縦スクロールバーはちょっと特殊な感じ... |
PowerPoint 2002 | PP10FrameClass | paneClassDC | × | ○ | ○ | - | ○ | ○ | ○ | - | *Auto Detect* | ペインが多いのでまだ誤爆があるかも... |
Access 2002 | OMain | OGrid | × | ○ | ○ | - | ○ | ○ | ○ | - | *Auto Detect* | ピンキー過ぎるきらいがある。sX,sYを大きくすればいいかも |
Visio 2003 | VISIOA | VISIOG | × | × | ○ | - | ○ | × | ○ | - | Scroll2,Scroll2 | これも今のところ Scroll で動かない。 |
Adobe Reader 9 | AcrobatSDIWindow | AVL_AVView | × | ○ | ○ | - | ○ | ○ | ○ | - | *Auto Detect* | |
TrueImage Personal2 | FXTopWindow | FXWindow | × | × | × | - | ○ | ○ | × | - | *Auto Detect* | スクロールバーのクラスも FXWindow。無理矢理サイズで判断して VKey 送れば何とか出来そうだけど、誤爆が多そうだし大して使わないから対応しない |
OpenOffice3 | SALFRAME | N/A | ○ | × | × | × | ○ | × | × | × | *Auto Detect* | コントロールクラスがとれない。 |
EmEditor8 | EmEditorMainFrame | EmEditorView | × | ○ | ○ | - | ○ | ○ | ○ | - | *Auto Detect* | |
Jane Style 3 | TMainWind | THogeListView | × | × | ○ | - | ○ | × | ○ | - | Scroll2,Scroll2 | やはりListView系なので... |
DF | Afx:400000:8:10011:0:* | AfxFrameOrView42s | × | ○ | ○ | - | ○ | ○ | ○ | - | Scroll2,Scroll | 横が非対応なので |
SendMessage
→PostMessage
に変えた※ 個人的にはトラックポイント機能の代替が出来たレベルになったと思う
そもそも根本が違うと思い全部書き直し(まぁ、切り貼りだけど)
それなりに動くようになった。
WinAPIなんて初めて触るw
基本部分完成。マウスカーソルがうざい。
作ろうと思った。