GUIウィンドウに特定のメッセージが送られたときに実行される関数を割り当てる
OnMessage(MsgNumber [, "FunctionName", MaxThreads])
引数名 | 説明 |
---|---|
MsgNumber | 監視・応答させたいメッセージの番号 |
FunctionName |
メッセージを受け取ったときに実行させたい関数の関数名を文字列として指定する 空の文字列を指定すると、MsgNumberに対する関数の割り当てを解除する。 第2引数以降を省略すると、割り当ての変更は行われない。 |
MaxThreads |
メッセージを受け取って関数を実行中に同じメッセージが送られたとき、スレッド割り込みによって実行できる数の上限を指定する。 省略時は「1」。 割り込まれなかった場合は、後述の条件によって後回しにされるか無視される。 割り込みを許すと、メッセージイベントが時系列順に処理されなくなるため、通常は変更しない。 |
FunctionName([wParam,lParam,msg,hwnd]) { }
引数 | 説明 |
---|---|
wParam | メッセージとともに送られるWPARAMパラメータの値が0...4294967296の整数値で与えられる |
lParam | メッセージとともに送られるLPARAMパラメータの値が-2147483648...2147483647.の整数値で与えられる |
msg | 送られたメッセージの番号が与えられる |
hwnd | メッセージが送られたウィンドウやコントロールのウィンドウハンドルが与えられる |
割り当てる関数は、4つの引数を受け取ることができる。
引数名は自由につけてかまわない。
その引数で与えられる情報が必要ない場合、引数の設定を省略してもかまわない。
関数が呼び出される際には、以下の組み込み変数にもメッセージを受け取った状況に応じた値が設定される。
また、LastFoundWindowはメッセージを受け取ったウィンドウ(メッセージがコントロールに送られた場合は、その親ウィンドウ)になる。
関数はReturn文で-2147483648から4294967295までの値を返せる。
値を返した場合、メッセージへの応答はそこで完了する。
関数が返すべき値は、メッセージの種類によって異なる。
何も値を返さなかった場合、AutoHotkeyの通常の処理が行われる。
問題なく割り当てが行われると、それまでMsgNumberに割り当てられていた関数の関数名が返される。
ただし、それまで何も割り当てられていなかった場合、新たに割り当てた関数名自体が返される。
指定された関数が存在しなかったり、設定された引数が間違っている場合など、正常に割り当てが行えなかった場合は、空文字列が返される。
FunctionNameを与えなかった場合、現在割り当てられている関数名が返される。この場合、関数が割り当てられていなければ、空文字列が返される。
メッセージイベントによる関数の実行は、現在実行中のスレッドに割り込んで、新規スレッドとして実行される。
AutoHotkeyのスクリプトがメニューを表示中や、KeyDelayやMouseDelayの途中などで停止している間に送られた場合、
0x312番未満のメッセージに割り当てられたイベントは無視される。
0x312番以上のメッセージの場合は、後回しにされる。
イベントが無視された場合、割り当てられた関数は実行されず、通常のメッセージ応答が行われる。
イベントが後回しにされた場合、スクリプトが実行可能になった時点で実行される。
MsgBoxコマンドなどでダイアログが表示されている間は、ウィンドウ上のコントロールに対するメッセージは無視される。
同じ番号のメッセージイベントが実行中だった場合、MaxThreadsの上限を超えていなければ、実行中のスレッドに割り込んでメッセージイベントが実行される。
メッセージが0x312番以上で、実行中のスレッドがCritical状態だった場合、メッセージイベントは後回しにされる
それ以外の場合、メッセージイベントは無視される。
別のメッセージイベントか、メッセージイベント以外のスレッドが実行中で、スレッドがCritical状態だったり、Thread,Interruptの設定による割り込み禁止期間だった場合、
0x0〜0x311番のメッセージは例外的に割り込まれる。
0x312番以上のメッセージは後回しにされる。
メッセージ応答イベントの優先度は常に0であるため、実行中のスレッドの優先度が0より大きい場合、すべてのメッセージは無視される。
0x0〜0x311番のメッセージイベントが無視されずに実行されるようにするためには、次にメッセージがチェックされる前にメッセージイベントが終了するようにすればよい。
短い処理の場合は、「Critical,30」のようにしてメッセージチェック間隔を十分に広くすれば、スレッドが終了するまでメッセージがチェックされず、無視されることもなくなる。
処理が長い場合は、以下のようにして、別の0x312番以上のメッセージイベントを呼び出し、元のスレッドは即座に終了すればよい。
MSG=0x000 ;処理を割り当てたいメッセージ OnMessage(MSG,"OnMSG") OnMSG(w,l,m,h){ PostMessage,0x4000,%w%,%l%,,ahk_id %h% } OnMessage(0x4000,"OnMSGMain") OnMSGMain(w,l,m,h){ Critical ;同じメッセージが来たら後回しにされるようにする /* ここで時間がかかる処理を実行 処理中にMSG番のメッセージが来たら、割り込みでイベントが発生し、 0x4000番のメッセージが再送信され、そのイベントが後回しで実行される */ }
MsgNumberで関数を割り当てられるメッセージの数は、最大で500までである。
それ以上のメッセージに応答しようとすると、この関数は失敗する。
OnMessageを使用しているスクリプトは、自動的に常駐状態かつ#SingleInstance(複数実行不可)になる。
自作プログラム同士で独自のメッセージをやり取りしたい場合は、Windowsにあらかじめ定義されたメッセージやAutoHotkeyが使用するメッセージと重ならないように0x1000(4096)番以降のメッセージ番号を使用するのがよい。
GUIを持たないAutoHotkeyのスクリプトにメッセージを送りたい場合は、AutoHotkeyのメインウィンドウ(ahk_class AutoHotkey)に送るとよい。
一般的なメッセージの一覧については、WinAPI Database for VB Programmerのアルファベット順表示「W」の項などが詳しい。
RegisterCallback(), OnExit, OnClipboardChange, Post/SendMessage, Functions, List of Windows Messages, DllCall(), Threads
; Example: Have a script receive a custom message from some other script or program. OnMessage(0x5555, "MsgMonitor") OnMessage(0x5556, "MsgMonitor") MsgMonitor(wParam, lParam, msg) { ; Since returning quickly is often important, it is better to use a ToolTip than ; something like MsgBox that would prevent the function from finishing: ToolTip Message %msg% arrived:`nWPARAM: %wParam%`nLPARAM: %lParam% } ; The following could be used inside some other script to run the function inside the above script: SetTitleMatchMode 2 DetectHiddenWindows On ReceivingScript := WinExist("Name of Receiving Script.ahk ahk_class AutoHotkey") if ReceivingScript PostMessage, 0x5555, 11, 22 ; Sends to the "last found window" due to WinExist() above. DetectHiddenWindows Off ; Must not be turned off until after PostMessage.
; Example: The following is a working script that monitors mouse clicks in a GUI window. ; See also: GuiContextMenu Gui, Add, Text,, Click anywhere in this window. Gui, Add, Edit, w200 vMyEdit Gui, Show OnMessage(0x201, "WM_LBUTTONDOWN") return WM_LBUTTONDOWN(wParam, lParam) { X := lParam & 0xFFFF Y := lParam >> 16 if A_GuiControl Control := "`n(in control " . A_GuiControl . ")" ToolTip You left-clicked in Gui window #%A_Gui% at client coordinates %X%x%Y%.%Control% } GuiClose: ExitApp