AutoHotkeyでキー入力したときや Gui上のオブジェクトの上にマウスを持っていったときとかに ToolTipを出す方法について。
ToolTip
1
|
|
な感じでToolTipを出現させられます。
Text
に出現させたい文字列を入れればその文字列が出ます。
(`n
で改行もいれられる。)
Text
に何も入れないで実行すると表示されているToolTipを消しせます。
X
、Y
は出現位置で
CoordMode
のToolTip
の値によってスタート地点が変わりますが、
初期値ではWindow
になっていて、
0, 0
とすれば現在のウィンドウの左上にひっつくような表示になります。
1 2 |
|
とかすればウィンドウの右下から外側にくっつく様なToolTipに。
X, Y
が省略されるとマウスの所に出現します。
WhichToolTip
はToolTipに振られる番号で、1から20を指定できます。
省略すると1番になります。複数のToolTipを表示させたい場合には
違う番号を指定します。(そうしないと前のものを上書きしてしまいます。)
キー入力イベントで表示させる簡単な例
簡単に、Aを押すと1秒だけToolTipを出すやり方としては
1 2 3 4 5 |
|
こんな方法。ToolTipを出して、
Sleep
で一秒待ってからText
無しのToolTip
コマンドで削除します。
Sleepに与える引数はミリ秒なので1000で一秒です。
次に複数のToolTipを出してみます。
1 2 3 4 5 6 7 8 9 |
|
これを実行してAを押すと、
tool tip 2
とtool tip 3
が出ますが、
ToolTip番号1はtool tip 2
に上書きされるので
tool tip 1
は出ません。
その後、1秒たってtool tip 2
が消え、さらに1秒経ってからtool tip 3
が消えます。
ただし、このSleep
を使った方法はちょっと問題があって、
1秒経つ前にAを押した場合、
再びtool tip 2
が表示される命令が出てこれはそのまま表示され続けるままですが、
以前のSleep
後のToolTip
が生きているので前にAを押したときから
1秒のタイミングで消えてしまいます。
この様な事を避けるため、通常は次のSetTimer
を使った方法を使います。
SetTimerを使った例
SetTimer を使うと指定時間の途中で消したりすることが可能になります。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|
AでToolTipを出した後、SetTimer
を使っています。
SetTimer
では最初の引数でラベルを指定し、2つめに数字があると
その時間(ミリ秒)のタイマーを作動し、その時間分待った後にラベルで指定された動作を実行します。
実行後はタイマーをリセットし、またカウントダウンを初めて指定時間後に動作を実行する、を繰り返します。
RemoveToolTip
というラベルの中では
Text
無しのToolTip
で削除しています。
最初のタイマーが10000ミリ秒(10秒)で作動するのでここではツールチップが10秒間表示されることになります。
また、表示中にAをもう一度押すと
ToolTip
がもう一度実行されますがこの際は同じメッセージなのでそのまま。
その後SetTimer
によってタイマーがリセットされるので
Sleep
を使ったときと違い、最後に押したときから10秒経ってから消えることになります。
RemoveToolTip
ではさらにToolTip
の直前でSetTimer
でOff
をしています。
2つ目にOff
があるとそのタイマーは停止されるので
ここへ来るとタイマーは止まり、その後繰り返しません。
最初のSetTimer
からラベルを伝って必ず来るようになっているので
このタイマーは一回しか作動しません。
この設定をこの様に別のラベルで作っておくとBでこのラベルを呼出し、 途中で消すことが出来ます。
Gosub
はラベルにジャンプしてReturn
で戻ってくる機能です。
Goto
という似たような機能がありますが、こちらは行ったまま戻ってきません。
ここでは直後にReturn
してるのでどちらでも同じですが、
Goto
的なものは混乱の元なのでGosub
で関数的に呼び出して戻ってくる、
と言った感じにした方が分かりやすくなります。
ここで、Bに対して単に
1 2 3 |
|
の様にToolTipを直接消す様に定義しても全く同じことが出来ます。
ただこの場合は裏でタイマーは動き続けていて3秒後にToolTip
を実行します。
実行してもText
が無いので結局何も起こりませんが。
これだけの例だとそこまで気にする必要はありませんが、 与えたラベルの中で色々やる場合に、複数回起動されると困ることもあるでしょうし、 単に裏で無駄なプロセスが残っているのも気持ち悪いので きちんと消すようにした方が良いです。
同様に、Sleep
を使ってる場合でもBにToolTip
を実行させて
無理やり消すことも出来ますが、
この場合もSleep
後の実行命令は残りますし、
上にも書いたようにSleep
での実行には問題があるので
SetTimer
を使った方が良いです。
GuiのオブジェクトにマウスオーバーでToolTipを表示させる
Tooltipを直接表示させることは出来ましたが、 Webや他のアプリで良くあるのは何らかのものの上にマウスを持っていった時に 表示されるToolTipです。
これを実現するためには以下の様な事をやります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
|
以下のページで出てる解答にちょっと手を加えたものになっています。
(SOLVED) gui control tooltip on hover? - Page 2 - Ask for Help - AutoHotkey Community
Guiに関しては以下参照。
まず、いくつかのGuiのコンテンツをいれたウィンドウを表示させています。
Show
した後に、
OnMessage
という関数がありますが、
これは特定のメッセージ番号を受け取った時に実行する関数を指定できる
関数です。
最初の引数がメッセージ番号で2つめに関数名を文字列で書きます。
メッセージはSendMessage, 0x200
の様にスクリプト内で送ることも出来ますが、
それ以外にもGui上の操作などでも特定の番号でAutoHotkeyに送られてきます。
ここに
...
WM_MOUSEFIRST = 0x200
WM_MOUSEMOVE = 0x200
WM_LBUTTONDOWN = 0x201
WM_LBUTTONUP = 0x202
WM_LBUTTONDBLCLK = 0x203
...
とありますが、0x200
はWM_MOUSEFIRST
及びWM_MOUSEMOVE
にあてられています。
これはGuiウィンドウの上でマウスが動いた時にメッセージを送ることになります。
その後のWM_LBUTTONDOWNCLK
(0x203
)なら左クリックした時にメッセージを送ることになります。
これを使うことでGuiウィンドウ上でマウスが動いた時に常に
MyMouseMove
が実行される事になります。
MyMouseMove
では、
CurrControl
とPrevControl
という2つのグローバル変数を使っています。
上の参考URLの中ではstatic
を使って関数内で次回も使える変数にして
いますが、これによって
DisplayToolTip
も関数内に書く様な形になっています。
2つの値を他の余計な所で書き換えられない、という点はstatic
の方が便利ですが、
ラベルは外に出したほうがすっきりするかな、ということで
上の様な書き方をしてみました。
その上でまずA_GuiControl
という値を取ってきています。
A_GuiControl
は命令を実行させたGui Controlが入っていますが、
v-labelが指定されてる時はv-labelが、
されてない時はテキストが入ります。
この場合はマウスの下にあるオブジェクトのものが入ることになります。
Gui, Add, Edit, vMyEdit
ならMyEdit
、
Gui, Add, Edit, , MyEditText
ならMyEditText
の部分がA_Control
に入ります。
両方ない場合は空。
ただし、Text
はちょっと注意が必要で
そのままv-labelを与えてもテキストを与えてもGui Controlではないので
A_GuiControl
に何も入りません。
(上の参考URLの最後の質問にこれに関すると思われるものもありますが。)
コントロールオブジェクトにするためにはg-labelを付けます。
これで押した時にする動作を付けられるわけですが、
今回はこれに何もしない動作をDummyラベルを割り当てています、
これにより、押しても何もしないテキストですが
Gui Controlとなり、A_GuiControl
で値が取得できる様になります。
値を取得したら、前回と変わってなければ何もせずに終了。
上のURLの例だと!=
の代わりに< >
を使っていますが同じ意味です。
また、InStr(...)
で" "
と比べ、空白を含まないチェックをしていますが、
これは空白を含むと、あとで
1
|
|
の所で、%CurrControl%
の値と_TT
をくっつけた名前の変数の中身を取り出す時に
変数名に空白があるとエラーが出てしまうからです。
ただ、その様な別の要素に移った際にもTooltipを消してリセットするのが正しいので
変更後はまずA_GuiControl
が変わったかどうかだけ見てPrevControl
をセットし
ToolTip
で一度ToolTipを削除しています。
その次に、A_GuiControl
が空白(何も無いスペースやText
などでGui Controlオブジェクトじゃないもの、v-labelもテキストも無いもの)だったり、
スペースを含むような値(大概はText
でg-labelを設定してないもの)
の場合には何もせずに終了します。
この部分に関してもう少し。参考URLの方では
…and not InStr(CurrControl, " ")
みたいなことをしていますがこれは上手く動きませんでした。
InStr
は2つ目の引数が最初に現れる位置を返しますが、なければ0を返します。
0がfalseなのでnot
にしてand
でつなげれば同じことなはずなのですが。
これの&&
だけ変更したり...==0
だけ変更したりしても上手く行きませんでした。
エラーになるわけではなく、CurrControl != ""
の真偽だけで全て決まってしまうような形になっていました。
何か勘違いしてる気がしますが、とりあえず上に書いた形だと期待通りに動いてくれました。
いずれにせよ、もし使えるA_GuiControl
だった場合、
DisplayToolTip
を1秒のタイマーでセットします。
これによっていきなり出すのではなく、1秒以上マウスが同じオブジェクトの上に居た場合にToolTip を出すことが出来ます。
DisplayToolTip
では上でも説明したとおり%CurrControl%_TT
を
ToolTipに出していますが、
この値は
Prepare tooltip messages
のところで作っています。
この様にGui Control名+_TT (_TTでなくてもいいけど適当な共通のもの)
をToolTipの内容として作っておくことで
こんな感じの動作を実現することが出来ます。
これとは別の方法で実現しようとする以下のような解答もありました。
ここでは
MouseGetPos
を使ってGui Controlの情報を取ってきていますが、
ここで取れるものはButton1
とかButton2
とかで、
ClassNN
と呼ばれるコントロール群の名前+番号となっています。
従って配置した順序によって取れる値が変わるためちょっと使いづらいものになっています。