TrackWheel

TrackPointのは便利なんだけど、中ボタンが使えないのはもったいない! でも、いちいちタスクトレイから切り替えるのも面倒だ。

AHKでトレイアイコンを操作するスクリプトを使ってもいいが、 一瞬メニューがでるし、何しろ1ステップ多いのが嫌だ!

と言う人向け。普通のマウスだとあまり便利でないかもしれない。 (マウスを普段使っていないので試してない)

機能概要

主機能 副機能

必要要件

まぁ、一応ってことで。以下が必要

簡単な利用方法

単品利用のばあいを記載する。
トラックポイントの場合
  1. トラックポイント等を利用して独自のスクロール機能を利用しているなら停止する
  2. アーカイブをフォルダ構成を維持して展開する
  3. 出来たフォルダの中にある TW.ahk をそのまま実行する
  4. 動作が気にくわないなら、同フォルダにある TW.ini を編集して、 もう一度 TW.ahk を実行する。(特に停止したりしなくても良い)
  5. やめたいときはトレイアイコンをクリックして終了を選ぶ

設定の変更方法

はじめに

テキストエディタ(メモ帳なのかっ!)で設定ファイル(デフォルトでは TW.ini) を開く。 そこに説明が書いてあるのでよく読んで編集すること。

編集が終わったらスクリプトを再起動する。よく分かんないときは、Appendix でも読んでくれ。

フォントは MSゴシック とかの等幅フォントを使わないと大変なことに。

デバッグモード

画面は開発中のものです。
実際のものと確実に異なっています

デバッグモードをOnにして機能を利用するとスクロール対象のクラス以外に以下の情報が取得できる。 これをみて色々把握しないと設定が出来ないので頑張って理解してくれ。

①各方向へのスクロール方法

Wheel, Scroll, VKey のいずれかを選択したかと、 方向逆転(~)が表示される。(まぁ、設定ファイルの文字列がそのまま出るわけだが...)

②スクロール量の算出に必要な数字群

動作感度、動作閾値、ページモード閾値のそれぞれX軸、Y軸のが表示される。未設定の場合はデフォルト値が出る。

③移動量とスクロール行数

X軸・Y軸のそれぞれの単位時間あたりの原点(ボタン押下座標)からの 移動量(dx/dt, dy/dt)とそれが行数に変換されたものが表示される。

上段の移動量は、②の数値群を用いて下段のスクロール行数に変換される。


スクロール方法の変更

デバッグモードにすると、縦横各方向のスクロール方法が表示される。 スクロール方法は以下の3つから選択する。

動作内容(要は速度)の調整

これを理解する上で以下の数値が必要となる。よく読んで、適当に設定するように。

動作閾値 (TX, TY)

いわゆる「遊び」である。

小さな移動量でスクロールしていたらちょっと触れただけでもすぐに移動してしまい都合が悪い。 デフォルトでは X軸は10、Y軸は 1 を設定してある。 これにより縦スクロール中にあまり横スクロールをしなくて済む。

動作閾値は X,Y軸それぞれに値がある。更に、操作対象毎の設定も可能である。

この図では、X軸方向へは閾値を超えていないので、行数は0行と算出されれている。

動作感度(SX, SY)

移動量をどうスクロール量に反映させるかを計算する時に用いる数値である。 計算式は以下の通り。

つまり小さいほどピンキーで、大きいほど鈍い。(1 や 2 、逆に 100 や 200 だと実用にならないはず。)

※ 動作閾値を補正するのは、動作閾値を超えた瞬間に大きくスクロールしないようにするため

行数 = Round((移動量-動作閾値分の補正) / 動作感度)

「ま、なんて単純!」と思ったアナタ。まーこんなもんですよ。 あと、見ても分かるとおり、0 を設定したらゼロ除算でこけますので注意。

ページモード閾値 (PX, PY)

これは "Scroll" を利用したときのみに利用される数値である。 "Scroll" を利用した場合どのような動作をしているかというと、 スクロールバーの[▲]を上で算出した行数分だけ押すのをエミューレートしている。

これが結構チマチマとしかスクロールしないし、多くの行をスクロールさせようとした場合には たくさんの命令をループで回して送らなければならないので重くなる。

で、なにを言いたいかというと、スクロールバーの「ボタン([▲][▼)」]や 「つまみ」(移動する棒状のやつ)以外の部分をクリックすると一気にページ毎の スクロールに変わるわけだが、それに切り替えるための閾値である。

デフォルトでは縦・横ともに8となっている。 8回以上[▲]押すくらいなら一気に1ページスクロールしてしまえ!ってことである。

バイパスコントロール設定

バイパスコントロールの罠にはまったヤツら

通常、ボタン (Button) とかテキストトラベル (Static) なんつークラスは、 どうせスクロールなんてしない。でもマウス直下にあると無視できない。

と言うわけで、これらの上位の(見た目上は下側に隠れた)コントロールに制御を渡したい。そんなときに使うのがバイパス。

設定ファイル内では Bypass に設定をするが、正規表現 での設定なので分からない場合はいじらぬが吉である。

この図ではうまいことにスクロールできるコントロールまでたどり着いている。 というか、クラス名が長すぎて TrayTip が切れている。今気づいたが見なかったことにしよう...

全くの余談だが、この後このプロセスが 1.5GB メモリを消費していたので速攻殺してやった。悪名高い Catalyst である...


既知の不具合とか、作者の能力の限界とか

スクロールしないところがある!

動かしかたが分かりません。 設定を Wheel とか VKey にしてやってください。 それでも無理なら諦めて...

Word2002とかエクスプローラに左ペインなんて全く分からない...

別のスクロールバーに誤爆してる!

多分Office系だと思う...。座標だけで割り出すのは限界が...

なんか、動きがもっさりしてる...

仕様です。一応、グローバル変数の TW_PRIORITY_HIGH の値を真にすると 機能実行中だけプロセスの優先度を「高」にしたりする機能があったり無かったり...

スクロール実施中は他のマウスボタンのホットキーは効かない。

仕様です。マウスフックですから...

他のAHK等のフックプロセスがある場合、本スクリプトのフックが効かない事がある

仕様です。アプリケーションレベルのフックはフックは後勝ちなのかな?スクリプトを再起動するといいかも。

マウスポインタが消えないときがあるんだけど・・・

多分他のユーザのプロセス(スレッド)のはず。

ファイル名を指定して実行とかのダイアログのインクリメンタルサーチの部分はシステムプロセスだったり・・・

ボタン押しても例のアイコンが出ないしスクロールが出来ないんだけど...

フック処理に失敗していると思われる

デバッグを On にするとマイドキュメントにエラーログを吐くはず

ボタン離しても例のアイコンが消えないんだけど...

大変危険な状態です。 対象ウィンドウに色々メッセージを送っている最中にハングしているものと見られるので利用を止めましょう。

パワーポイントのノート欄(下ペイン)とは激しく相性が悪いです...

対処法なんてわかりません。素人が作ったものなんで。

組み込み方法

基本手順

高度な(?)組み込み方法

Appendix(蛇足)

動作機序

フックに関してはこんな感じ

スクロール方法の決定はこんな感じ

コントロールとスクロールバーの抽出方法について

結構苦労した。コード量は大したことがないけど大変な作業だった...。そのときの考察したメモ。 もし、読む気があるなら、、、添付の "窓調査.ahk" を利用するとわかりやすいはず。

Type1 - Self

Parent Control
Target Control
 
   
縦横スクロールがOKなヤツ

一番よく見るタイプ。スクロールする必要が生じたら、自分の中にスクロールバーを作るタイプ。 各種設定画面とかでよく見る、入力欄(Edit, RichEdit)、 リスト(ComboBox, ListBox)、表(ListView)、 ツリー(TreeView)など。 これらは、ホイール命令(WM_MOUSEWHELL)や、スクロール命令(WM_VSCROLL/WM_HSCROLL) によく反応してくれる。

厳密さを求めるなら、user32.dllGetScrollInfo または GetScrollPos 関数で スクロールの情報が取得できるもの。


Type2 - Bypass

Parent Control
Target Control
 
   
上で説明したバイパスに
ハマったヤツの構造

これもよく見かけるタイプ。 入力も出来るしリストから選択も出来るドロップダウンリスト等(ComboBoxの上に Editが乗っている)とか、ボタン(Button)とか ラベル(Static)の上でスクロールするのも同じ。 要は、Type1に該当する汎用コントロールの上に他の汎用コントロールが乗ってるやつ。

対象コントロール自体はスクロールバーを持たないが、ホイール・スクロール命令を透過するものが多いので そのまま命令を送信すればスクロールしてくれる。

透過しない場合は、Bypassにクラス名を追加し、 明示的に1段階上のコントロールに処理を委譲するような設定をする。 なお、上位コントロールもBypass対象ならば更に上位へとバイパス対象でないところまでいく(トップレベルウィンドウで止まる)。


Type3 - ChildScrollBar

Parent Control
Target Control
 
 
 
エクセルは分かりやすい

自分自身はスクロール命令(WM_VSCROLL/WM_HSCROLL)に反応しないけど、 自分の配下にスクロールバーがあってそいつらを操作すれば良いタイプ。

特に設定は必要ない。Type1の亜種と言っていい。

ぶっちゃけあんまり見ない。エクセルとか。


Type4 - Parent ScrollBar

Parent Control
Target Control
 
 
 
パワーポイントは変態!!
親子構造がひどい

上のものと構成がにてるけど、厄介というか個別対応が必要なもの。 汎用コントロールでは実現できない各種アプリのコントロールが該当。 Word, PowerPoint 等オフィス系アプリでよく見る。

スクロールバーは自分と同位に並べられた、別コントロールってパターン。

ホイール命令(WM_MOUSEWHELL)は対象コントロールに送ればスクロールしてくれるが、 スクロール命令(WM_VSCROLL/WM_HSCROLL)はそれぞれのスクロールバーを探して、 それらに送信しないとスクロールしない事が多いヤツら。

スクロールバーの識別子(クラス)が "ScrollBar" ってやつなら探すのもそう大変ではないけど、 対象コントロールと同じ名前だったりするヤツがあって面倒なものも多い。 あとはペイン分割だったりとか、MDI子ウィンドウだったりとか・・・


Type5 - Unknown

OpenOfficeの構造と画面の見た目
コマンドプロンプト

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_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_SBH
TW_TARGET_SBV
Int 操作対象スクロールバーのウィンドウハンドル
TW_TARGET_SCROLLH
TW_TARGET_SCROLLV
Int 操作対象スクロールバーの親ウィンドウハンドル
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 ホットキータイムアウト時間

Components 調査結果

  • コモンコントロールは IE6 相当での調査なので、Vista 等 IE7 以降導入の場合は結果が異なるかもしれない

凡例: 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 VKey Wheel Scroll VKey
Gecko * MozillaWindowClass × × ~Wheel, Wheel HWheelの向きに逆に反応する感じなので。 VKeyの場合は要フォーカス変更(フレームクリック)
Trident(IE6) * Internet Explorer_Server × Scrlll, Scroll Scrollの方がレンダリングの関係上スムーズ。 Scroll,VKeyの場合は要フォーカス変更(フレームクリック)
ListView * SysListView32 × - - *Auto Detect*
ListView * TListView × - - *Auto Detect*
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の設定画面とか)は無理。

Applications 調査結果

凡例: 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 VKey Wheel Scrool 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 × - - *Auto Detect*
PowerPoint 2002 PP10FrameClass paneClassDC × - - *Auto Detect* ペインが多いのでまだ誤爆があるかも...
Access 2002 OMain OGrid × - - *Auto Detect* ピンキー過ぎるきらいがある。sX,sYを大きくすればいいかも
Visio 2003 VISIOA VISIOG × - - *Auto Detect* ピンキー過ぎるきらいがある。sX,sYを大きくすればいいかも
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 × - - *Auto Detect* 横スクロールバーが出ないがスクロールする
DF Afx:400000:8:10011:0:c00841 AfxFrameOrView42s × - - *Auto Detect* レンダリング遅すぎ

その他

著作権とか...

  • どうでも良い、その代わりに何も保証しない。
  • 敢えて言えば、誰でもいじっていいし、制限なんて要らない。(添付文書を含む)
  • 用語を使えば、 Public Domain なのかなぁ

サポート?とか

  • 基本的にしない。趣味で作っているので。
  • でも致命的なのがあった教えて欲しい。むしろ、直したのをクレ。

更新履歴

面倒なのでプレーンテキストで
2008/12/28
 機能修正/追加
  トグル関数を整備
 内部仕様の変更
  Scroll/Wheel のメッセージ投げを SendMessagePostMessageに変えた
  (分かっていたが追従性が激減した。が、バグる可能性は減った。またWordでScrollが効く)
  開始処理が終了する前にボタン押上イベントが発生したときの後処理が行われない不具合を対処したつもり
2008/12/27
 機能修正/追加
  外部ファイルで個別設定の取り込みを可能に
  スクロール方法の自動選択をかなり強化
  Scroll選択でもCtrl,Shift押下中はWheelを送るようにした(拡大/縮小,履歴など)
  怪しい挙動(!)がかなり減った
 内部仕様の変更
  開始・終了時の致命的なバグをFix
  自ユーザ以外のプロセスに attach しようとして初期化落ちしていたのを fix
  スクロールバーの検出方法の強化(クラス名に非依存)
 ※ 個人的にはトラックポイント機能の代替が出来たレベルになったと思う
2008/12/23
 そもそも根本が違うと思い全部書き直し(まぁ、切り貼りだけど)
  GUIは面倒だから作らない
  Win32APIを用いて、LowLevelMouseHookを使うようにした。
  システムカーソル変更を取りやめ、操作対象のスレッドに忍び込みカーソルを消すことにした。
  本質的でない ScrollLock 関連とかはやめにした。
  WM_MOUSEHWHEELを採用
  個別設定はまだ無い。
  あとはあまり変わりない。
--------
2008/12/22
 機能修正/追加
  上下キーエミュレートを追加 → スピンコントロールとか
  Shift+Wheel(横スクロール)を追加。→ OpenOffice.org向け
  ChildCtrlを追加。子コントロールにスクロール命令が送れるようにした。
  設定GUIを追加(GUIが2つに)。起動中にパラメタを変更し動作に反映できるようにした。
  上記GUIでの変更をINIファイルに反映出来るようにした。(トレイメニューでの設定変更を廃止)
  操作対象別のパラメタ持てるようにした。(上記GUIで動的に変更可)
  ScrollMode=1の場合のスクロール量算出式の変更。
  TrayTipを利用しない場合のバグを修正。
  透明カーソルのパスを示す設定項目 "cursor" を削除。
  この文書の誤字・誤りを訂正。
 内部仕様の変更
  コア部分がかなり変わった。
  スクロールバー検出をちょっとだけ強化
  設定項目 "GuiNo"を廃止。GUI番号は空き番号を探して設定するようにしたため。
  TrackWheel 関数を廃止。
  データストア(TrackWheel_DataStrage)関数を廃止。
  Iniファイルのセクション名の変更 [TrackWheel] → [config]
  各種関数の統廃合などリファクタリング多数。
  カーソルのpush/popで二重push出来ないようにした。(潜在的なバグのfix)
  SendMessage等の最中のマウス移動抑止を無くした。
  プロセス内部で透明カーソルを生成するようにした。
2008/12/06
 機能修正/追加
  INIファイルでの初期化を追加。デフォルトとした。このため初期化がAutoexecブロック1行で済む。
  INIファイルで初期化を行ったときのみ、トレイメニューからINIファイルの編集が出来るようにした。
  コントロールだけでなく、ウィンドウクラス名、実行ファイル名でのマッチングも可能にした。(オプション)
  正規表現でのマッチングを可能にした。(オプション)
  トレイチップが出ないとき、自動で消えるツールチップを出すようにした。
  トレイアイコンを変更するようにした。(既に変更してあるときは変えない)
  「ホイールポストアクション」の追加。未タイムアウト時のキー送信以外のカスタマイズをしやすくした。
  スクリプト終了時のOnExitで飛ぶラベルをIniファイルで設定できるようにした。
 内部仕様の変更
  Ini初期化関数で、多重初期化抑制と初期化失敗を検知しユーザ通知するようにした。
  動作に関わる全てのグローバル変数を無くした。
  上記の内容に伴い、デバッグモードのの時のみデータストアクラスの内容表示が出来るようにした。
  コメント追加/修正、未使用コードの削除など
2008/12/05
 機能修正/追加
  WheelScroll.ahkの機能を大幅に取り入れ以下を実現した
   Excel等のMDI小窓の横スクロール
   各種設定をほぼそのまま取り込んで各アプリで動作するようにした
  感度・動作閾値の設定が出来るようにした
  縦スクロール量算出方法を2種類(移動量に比例、移動量の2乗に比例)にし選択出来るようにした。
  横スクロールに左右キーエミューレートモード(ほぼMozilla専用)を追加
  横スクロール加速実装 (WM_VSCROLLと同じ方式)
  Ctrl or Shift or RButton が押されているときは一時的に固定移動モードになるようにした
   IE や Firefox 等の履歴・拡大率の変更時には固定の方が都合がよい
   特定のツールのタブ移動のマウスジェスチャがあったりするため
  ScrollLock On 時に挙動が変化するようにした(以下から選択可能)
   VScroll 制限 : 縦スクロールしない(横だけ移動)
   HScroll 制限 : 横スクロールしない(縦だけ移動)
   FixMove      : 常に一定値でスクロールする(縦横とも)
 内部仕様の変更
  Start/Stop 関数を整備、InitHotkey 関数を利用しなくても組み込みやすくした
  フル関数化 (ホットキー、メニュー用ラベルは除く)
  変数保持関数を追加し、グローバル変数を一部を除き利用しなくした
  以前の初期化関数はそのまま使えるはず

2008/12/03  それなりに動くようになった。
2008/12/02  WinAPIなんて初めて触るw
2008/12/01  基本部分完成。マウスカーソルがうざい。
2008/11/30  作ろうと思った。