HSP3でメニューバーの表示 Yahoo!ブックマーク に追加 はてなブックマーク に追加

無料でゲームやらツールやらを作成できるWindows向けプログラミングツール『HSP』(Hot Soup Processor)でメニュー(GUIメニュー)を作成・表示・設置する方法を説明しましょう。

メニューというのは、プログラムのタイトルバーの真下によく付いているコントロールです。
 メニューバーの項目をクリックすると、ドロップダウンメニュー(サブメニュー)が垂れ下がって、 その中の項目をユーザーに選択させるというものですな。

たとえば、Windowsに付属するエディタ「メモ帳」には、[ファイル(F)]、[編集(E)]、[書式(O)]、 [表示(V)]、[ヘルプ(H)]というような感じの項目がバー上に表示されてると思います。そして、 [ファイル(F)]を選択すると、[新規(N)]、[開く(O)]、[上書き保存(S)]、[名前を付けて保存(A)...]・・・[メモ帳の終了(E)]という感じで項目リストが表示されるわけです。

メニューを付属のモジュールで実現

HSP2時代ではメニューを表示するのに拡張プラグインを利用してた人も多かったかと思いますが、 HSP3(HSP 3.x)ではプラグインというのはもはや不要です。
 HSP3は、より簡単にWin32 API関数を扱えるようになったので、関連する 関数群を直接呼んでしまいましょう。

ただ、Win32プログラミングの知識は基本的に必要で、Win32 API関数以外にもHSP3から対応したoncmd命令 を利用します。

◆ mod_menu.asモジュール

HSP自体に用意されてるモジュール「common\mod_menu.as」です。モジュール内でWin32 API関数を呼んでる ので、ひとまずこれをインクルードすれば利用できます。
 このモジュールを利用したHSP付属サンプルは、「sample\new\menusample.hsp」と「sample\new\menubar.hsp」です。 (HSP 3.2〜では「sample\basic\menusample.hsp」)

モジュール命令として「newmenu」、「addmenu」、「applymenu」という3命令が用意されており、 それぞれの命令の説明はモジュール内を参照してください。
 このモジュールは必ずしも多機能とは言えず、純粋なメニュー表示しかできません。たとえば、後から特定の 位置にメニュー項目を追加する、項目の文字列を変更する、項目を削除する、項目のチェックマーク(レ点)の 付け外し、といような処理はまったく用意されてません。

まず、newmenu命令でメニューの作成宣言をして、そこにaddmenu命令で項目の追加を行っていきます。 最終段階でapplymenu命令を呼んで、メニューの表示をウィンドウに反映させてやります。
 ポイントとして、スクリプトを書く上では、垂れ下がるポップアップメニュー(より深い階層)の方を先に 用意していき、バー部分(0階層目)は最終段階の直前で用意する形にします。

//	メニュー表示サンプル (by Kpan)

;	モジュールをインクルード
#include "mod_menu.as"

;	下位ワード取り出しマクロ
#define ctype LOWORD(%1) (%1 & $FFFF)

;	項目ID用マクロ
#enum ID_OPEN = 1
#enum ID_QUIT
#enum ID_ABOUT
#enum ID_HOYON

;	メッセージ割り込み指定(後で説明)
	oncmd gosub *command, WM_COMMAND

;	[ファイル]-[サブ]の2階層目メニュー
	newmenu hSubmenu.0, 1
		addmenu hSubmenu.0, "ホヨーン(&H)", ID_HOYON

;	[ファイル]の1階層目メニュー
	newmenu hSubmenu.1, 1
		addmenu hSubmenu.1, "開く(&O)", ID_OPEN
		addmenu hSubmenu.1, "サブ(&S)", hSubmenu.0, $10
		addmenu hSubmenu.1, "", 0, $800
		addmenu hSubmenu.1, "終了(&X)", ID_QUIT

;	[ヘルプ]の1階層目メニュー
	newmenu hSubmenu.2, 1
		addmenu hSubmenu.2, "バージョン情報(&A)", ID_ABOUT

;	0階層目のバー
	newmenu hMenu, 0
		addmenu hMenu, "ファイル(&F)", hSubmenu.1, $10
		addmenu hMenu, "ヘルプ(&H)", hSubmenu.2, $10

;	メニューバーをウィンドウに反映
	applymenu hMenu

	stop

;	WM_COMMANDメッセージ用
*command
//	後で説明
        return

これでメニューそのものの表示は実現できました。
 色分けした変数は、それぞれのパラメータで同じ変数を指定しなけれなばならいことを示してます。 newmenu命令の段階で、この変数にはメニューのハンドル値(簡単に言えば内部識別番号のようなもの)が 返ってきています。

addmenu命令のメニュー項目で表示する文字列に「&○」が出てきますが、この直後の半角文字 (アルファベットor数値)にアンダーラインが付きます。これはマウスがない状況でもキーボードの「Altキー+指定文字」による メニュー選択を実現するWindowsの機能です。

また、第4パラメータに「$10」を指定することで階層としてサブメニュー表示が可能になります。 その場合、第3パラメータには表示するサブメニューのハンドル値を指定します。「$800」の場合は セパレータライン(区切り線)です。(モジュール内ではWin32 API関数のAppendMenu関数が呼ばれてる)

さてさて、メニューの項目を実際に選択してみてください。といっても、これだけでは何も起こりません。
 そこでHSPの標準命令であるoncmd命令の登場です。

◆ oncmd命令とウィンドウメッセージ

メニュー項目を選択したら、具体的にどの項目がクリックされたのか知る必要があります。
 項目がクリックされると「WM_COMMAND」というウィンドウメッセージがWindowsから通知されるので、 これをHSPで受け取るのにoncmd命令を利用します。「WM_COMMAND」は具体的には「0x0111」(16進数)という 数値で、mod_menu.asモジュール内の#const命令で定義されてます。

oncmd命令は必ずサブルーチンジャンプ「gosub」を指定してください。ここでは「*command」という ラベルを用意しておいて、「WM_COMMAND」メッセージが通知されたら、そのラベルへサブルーチンジャンプせよ! と指定してるわけです。
 そして、サブルーチンジャンプの掟として、ラベル先で必ずreturnさせてください。

で、実際にラベルにジャンプしたら、メニュー選択の場合はシステム変数lparamに「0」が返るので、 まずここで処理を振り分けます。というのも、「WM_COMMAND」メッセージはメニュー選択以外からの通知も あるためです。
 HSPに用意されてるサンプルにはこの部分の処理が用意されてませんが、不具合が起こってもおかしくないので 必ず用意してください。

//	〜モジュールインクロードやメニュー表示関連は省略してます〜

	oncmd gosub *command, WM_COMMAND

	stop

*command
;	メニューからの通知
	if lparam = 0 {
//		どの項目が設置されたかの取得(下で説明)

		return
	}

	return

そして、lparamで振り分けて以降の話です。HSPのシステム変数wparamの下位ワードには、選択した 項目ID値が返ります。
 下位ワードというのは、通常のHSPには出てこない概念ですが、HSPの数値型変数4バイト中の後ろ2バイト の数値です(ちょくとさんのページ参照)。「wparam & $FFFF」を演算することで取り出せます。ここでは下位ワードを取り出すマクロ 定義を用意してあります。

//	〜ラベルジャンプ先の処理以外は省略してます〜

*command
	if lparam = 0 {
;		wparamの下位ワードの数値を取り出す
		wID = LOWORD(wparam)

		dialog ""+wID

		return
	}

	return

HSP(HSP3)でメニューの表示 之図 一番上のメニュー表示サンプルを例にすると、[開く(O)]は1、[終了(X)]は2、[バージョン情報(A)]は3、[ホヨーン(H)]は4、がそれぞれ項目IDとして返ってくることになります。(「#enum」命令で宣言したとおりの数値)

上のサンプルコードでは単純にダイアログを表示するだけですが、実際にはここでその数値を見て処理を振り分けるわけです。(その振り分け先でも必ずreturnを用意!)

以上でおしまい。ちなみに、こっちにもちょっとした実例(Yahoo!ニュースのRSSフィードを取得して表示)を載せてます。

メニュー表示モジュール以上のことを行いたい場合はWin32 API関数を勉強する必要があります。まずは、 ちょくとさんのページ「メニューバーを作成してみる」を。掲載されてるコードはHSP2時代のものなのでHSP3でコンパイルできませんが、解説部分はぜんぜん通用します。

キーワード de HSP

HSPミニ講座

★ Yahoo!経由用ページ : ファイル | フォルダ | メニュー | マウス | ウィンドウ | オブジェクト | 文字列 | システム | 関数 | sendmsg命令 | その他 | サイトマップ | リンク