次へメニューバーメニューバーWindowsアプリケーションなら当たり前というぐらいに、いろいろなアプリケーションがウィンドウにメニューバーを持っています。HSPでは、標準機能だけではメニューを実現させることができません。APIを用いてメニューバーを表示させてみることにします。今回作成するのは右のようなメニューバーです。メニューの項目にサブメニューを持たせていないので、メニュー項目をクリックしても新しいメニューが表示されてきたりはしません。プログラミング言語では、メニューを作成するのに『メニューリソース』と呼ばれるものを使うことができるため、メニューを作るのは簡単なのですが、HSPでメニューを作ろうとすると、一からAPIで作成していかなければならないため、やや煩雑になってしまいます。簡単なところからやっていきましょう。今回は階層が1つだけの簡単なメニューを作成します。作成する手順は以下のようになります。メニュー項目を追加する。項目が複数あれば必要なだけ実行する。メニューをウィンドウに割り当てる。メニューを再描画する。順番に見ていきましょう。メニューバーの作成まずはメニューバーを作成します。メニューバーを作成するにはCreateMenu関数を呼び出します。CreateMenu(VOID);この関数は、メニューバーとしてウィンドウに表示するためのメニューを作成して、そのハンドルを返します。このハンドルはメニューを識別するための値で、以後、このメニューを操作するにはこのハンドルを用いることになります。余談になりますが、メニューもまた、Windowsオブジェクトの1つです。『メニューオブジェクト』であるということです。したがって、他のWindowsオブジェクトと同じように、ハンドルによって識別されています。メニューなどのようなユーザーインターフェースの機能は、主にuser32.dllによって提供されているものです。以前に紹介したWindowsオブジェクトの3つの分類から考えると、メニューは「ユーザーオブジェクト」に属するというわけです。Windowsオブジェクトについての詳細は、『プロセス間共有メモリ』の項を参照してください。メニュー項目の追加メニューを作成したら、そのメニューに項目を追加していきます。メニュー項目を追加するにはAppendMenu関数を呼び出します。表示する文字列);この関数は、指定されたメニューの最後尾に新しい項目を追加します。追加する項目の数だけ呼び出します。第3引数(uIDNewItemパラメータ)には、追加するメニュー項目のIDを指定するようになっています。ユーザーがメニュー項目を選択したとき、Windowsはそのメニューを所有するウィンドウにWM_COMMANDメッセージを送信します。このメッセージには付加情報として、wParamパラメータの下位ワードに、このパラメータで指定された項目IDが含まれています。項目ごとに違うIDを指定していくことで、メッセージが送られたときにどの項目が選択されたのかを判別することができます。第4引数(pNewItemパラメータ)には、メニュー項目に表示する文字列のアドレスを指定します。この文字列に、「終了(&Q)」というように、アルファベットの直前にアンパサンド(&)を指定すると、[ALT]キーとそのアルファベットのキーを同時に押すことでその項目を選択することができるようになります。アンパサンド自体はメニューには表示されず、アルファベットに下線が引かれます。ウィンドウへの割り当てと再描画さて、メニューの準備ができたら、ウィンドウにそのメニューを割り当てて、さらに再描画を行ないます。これによってウィンドウにメニューバーが表示されます。ウィンドウにメニューを割り当てるにはSetMenu関数を使います。メニューハンドル);続いて、メニューの再描画を行なうためにDrawMenuBar関数を呼び出します。ウィンドウハンドル);ウィンドウにメニューを割り当ててから、メニュー項目を追加していくこともできます。この場合は、項目を追加し終わった後で必ずDrawMenuBar関数を呼び出して、メニューを再描画するようにしてください。メニューオブジェクトの削除について以前まで扱ってきたWindowsオブジェクトは、必要なくなった時点で削除しなければなりませんでした。メニューもオブジェクトである以上は削除しておく必要があるのでしょうか。結論から言うと、今回の場合は削除する必要がありません。本来ならメニューもDestroyMenu関数を呼び出して、メニューオブジェクトの削除をしなければならないのですが、ウィンドウに割り当てられているメニュー(およびそのサブメニュー)は、ウィンドウが破棄されるときに自動的に削除されるようになっているためです。メッセージの処理ここまでの処理により、ウィンドウにはメニューバーが表示されています。あとはメニュー項目が選択された時にウィンドウが受け取るメッセージを監視していればOKです。項目が選択されると、ウィンドウはWM_COMMANDメッセージを受け取ります。WM_COMMANDメッセージのメッセージコードは0x0111です。WM_COMMANDメッセージで渡されるwParamパラメータの下位ワードの値は選択されたメニュー項目のIDになります。この値からどの項目が選択されたのかを知ることができます。このWM_COMMANDメッセージは、メニュー以外でもさまざまな目的で使われているため、WM_COMMANDメッセージを受け取ったからといって、メニュー項目が選択されたのだとは限らないのです。エディットコントロール(mesbox命令やinput命令で作成されるHSPオブジェクト)やコンボボックス、リストボックスなどの『Windows標準コントロール』と呼ばれるものは、何らかのイベントが発生したときに、親ウィンドウに対してWM_COMMANDメッセージを送信します。ツールバーなどの『コモンコントロール』にも、WM_COMMANDメッセージを送信するものがあります。したがって、mesbox命令を使ってウィンドウにエディットコントロールを作成してしまっていると、例えばエディットコントロールをクリックしたりしただけでも、親ウィンドウはWM_COMMANDメッセージを受け取ってしまうわけです。そこで、メニューから送られたのか、それ以外のコントロールから送られたのかを判別する必要があります。WM_COMMANDメッセージがコントロールから送られると、lParamパラメータの値がコントロールのハンドルになるのですが、メニューから送られた場合にはこの値が0になるのです。そこで、lParamパラメータが0であるかどうかで判別することにします。サンプルスクリプト実際にスクリプトを書いてみます。メニュー項目IDの値を最初に定数名として#defineまたは#constで定義しておくと、スクリプトがよりわかりやすくなります。メニューを設置するウィンドウのウィンドウハンドルが必要になるので、システム変数hwndを指定します。end}returnこのスクリプトを実行させてみましょう。メニューアイテムをクリックすると、それぞれの処理を行なっています。アイテムを選択することができるようになっています。