今回はメッセージ取得のサンプルスクリプトを書いてみましょう。
とはいったものの、メッセージ取得というものは、メニューやツールバー、あるいはコモンコントロールなどと組み合わせることでその本領を発揮するのであって、メッセージ単体の機能となると、マウス入力やキー入力といった、HSP標準機能でも充分対応できるものばっかりなんですよね……。
まあ、とにかく、何か書いてみるとしましょう。前回も述べましたが、スクリプトの全体構造は以下の通り。
とりあえず、ウィンドウがアクティブ化/非アクティブ化されたときに送られるメッセージを取得してみましょう。のメッセージコードは0x0006です。
fActive(wParamの下位ワード値)はアクティブ化フラグで、ウィンドウが非アクティブ化される場合は0 (WA_INACTIVE) が、ウィンドウがアクティブ化される場合は1 (WA_ACTIVE) または 2 (WA_CLICKACTIVE) になります。fMinimized(wParamの上位ワード値)は、ウィンドウが最小化されている場合は0以外の値に、最小化されていない場合は0になります。hwndPre(lParamの値)は、このウィンドウに代わってアクティブ(または非アクティブ)になったウィンドウのハンドルになります。
#include "llmod.as"
#include "hsgetmsg.as"
; メッセージコードの定義
#define WM_ACTIVATE 0x0006
; ウィンドウのサブクラス化
set_subclass
hwnd = stat ; ウィンドウハンドル
; 取得メッセージ設定
set_message WM_ACTIVATE
dup msg, msgval.1
dup wprm, msgval.2
dup lprm, msgval.3
*mainloop
; メッセージを取得
get_message msgval
if msgval {
if msg == WM_ACTIVATE : gosub *OnActivate
} else {
wait 10 ; wait または await を実行
}
goto *mainloop
*OnActivate
fActive = wprm & 0xFFFF ; アクティブ化されたかどうかのフラグ
if fActive {
mes "アクティブ化されました"
} else {
mes "非アクティブ化されました"
}
return
上のスクリプトを実行させてみましょう。ウィンドウをいったん非アクティブにしてからもう一度アクティブにすると、メッセージが表示されます。本当は、メッセージが送られてきたときにdialog命令でメッセージボックスを表示しようと思ったのですが、そうするとメッセージボックスが表示されたり閉じられたりするたびにウィンドウがアクティブ・非アクティブになって無限に続いてしまうので、ウィンドウにメッセージを表示しています。
このスクリプトでは、変数の別名を与えるdup命令を使って、メッセージコードやwParam・lParamを別の変数として扱えるようにしています。
dup msg, msgval.1 ; メッセージコード dup wprm, msgval.2 ; wParam パラメータ dup lprm, msgval.3 ; lParam パラメータ
このようにしておくと、メッセージが送られた場合に、get_message命令でメッセージを取得した時点でそれぞれの変数がメッセージコード、wParamパラメータ、lParamパラメータになるので、スクリプトがわかりやすくなります。
あまり気にすることでもないのですが、メインルーチンで繰り返しのループをどう組むかについて、ちょっと書いておきましょう。
上のスクリプトのメインループ(メッセージ待機ループ)は以下のように書かれています。
*mainloop
get_message msgval
if msgval {
; ここで各種メッセージ処理を行なう
if msg == ... : ...
if msg == ... : ...
} else {
wait 10
; 必要ならばここでループごとの処理
...
}
goto *mainloop
しかし、人によっては、例えば次のように組んでしまうかもしれません。
*mainloop
wait 10 ; ここで wait または await を実行
get_message msgval
if msgval {
; ここで各種メッセージ処理を行なう
if msg == ... : ...
if msg == ... : ...
}
; 必要ならばここでループごとの処理
...
goto *mainloop
このようなスクリプトを作成した場合、1つのメッセージ処理が行なわれるたびに、必ず1度はwait命令が実行されることになります。しかし、たくさんのメッセージを取得するように設定していてそれらが連続して送られてくる場合や、メッセージが立て続けに送られてくる場合、wait命令を1回実行するだけで複数のメッセージを受け取っている可能性があります。1つ目のメッセージ処理の後に、waitを実行することなく次のメッセージを処理するようにした方が、その分だけ反応速度が高まることになりますよね。したがって、最初に書いてある手順で作成したほうが良いことがわかりますね。
もう少し別の組み方で、次のように書いてもいいでしょう。
*mainloop
wait 10 ; ここで wait または await を実行
repeat
; 取得メッセージがない場合は repeat ループから抜ける
get_message msgval : if msgval == 0 : break
; ここで各種メッセージ処理を行なう
if msg == ... : ... : continue ; continue は無くてもいいですが
if msg == ... : ... : continue
if msg == ... : ...
loop
; 必要ならばここでループごとの処理
...
goto *mainloop
こちらの書き方なら、最初の書き方と比べても、速度の面で変化はないはずです。自分が見やすい方で書けばいいでしょう。まあ、こちらのほうではrepeat〜loopを使っているので、このループからgotoで抜け出してしまうという、HSP初心者が最も陥りやすい罠にはまらないようにする注意は必要ですけどね。