HSP3 あれこれ <メニュー>

Last Update : 2009/01/xx

メニューバーの表示

 ウィンドウの上側、タイトルバーの真下に付いているメニューバー。一般的なアプリケーションに[ファイル]、[編集]、[表示]というような項目がよく用意されていると思います。これをHSP3でこしらえるサンプルスクリプトです。

 HSP2ではHSP拡張プラグインや「llmod.as」用モジュールを利用するのが一般的でしたが、HSP3では拡張プラグインなぞもはや不要です。メニューバーの表示関連のWin32 API関数を直で呼び出せばOK。メニューバー表示に関しては、HSP2時代のものですが、ちょくとさんのページを参照してください。

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

#include "user32.as"

#define ctype LOWORD(%1) (%1 & $FFFF)

;	項目ID
#enum IDM_XXX = 1
#enum IDM_YYY
#enum IDM_ZZZ
#enum IDM_BBB
#enum IDM_CCC
#enum IDM_KOUMOKU1
#enum IDM_KOUMOKU2


;	WM_COMMANDメッセージ
	oncmd gosub *command, $111

;	<ポップアップメニュー>
	CreatePopupMenu
	hMenu.3 = stat
;		第3パラはメニュー項目ID
		AppendMenu hMenu.3, 0, IDM_XXX, "XXX"
		AppendMenu hMenu.3, 0, IDM_YYY, "YYY"
		AppendMenu hMenu.3, 0, IDM_ZZZ, "ZZZ"

;		hMenu.3の$6〜$8をグループ化し、$7に黒丸チェックを入れる
		CheckMenuRadioItem hMenu.3, IDM_XXX, IDM_ZZZ, IDM_YYY, $100

	CreatePopupMenu
	hMenu.2 = stat
;		第2パラ$10はサブメニュー、第3パラにサブメニューのハンドル
		AppendMenu hMenu.2, $10, hMenu.3, "AAA"
;		第2パラ$1はグレイ表示
		AppendMenu hMenu.2, $1, IDM_BBB, "BBB"
;		第2パラ$8は項目チェック (オン/オフの処理必要)
		AppendMenu hMenu.2, $8, IDM_CCC, "CCC"

	CreatePopupMenu
	hMenu.1 = stat
		AppendMenu hMenu.1, 0, IDM_KOUMOKU1, "項目1"
		AppendMenu hMenu.1, 0, IDM_KOUMOKU2, "項目2"
		AppendMenu hMenu.1, $800, 0, ""	// 第2パラ$800は区切り線
		AppendMenu hMenu.1, 0, IDM_EXIT, "終了"

;	<メインのメニューバー>
	CreateMenu
	hMenu.0 = stat
;		第2パラ$10はポップアップメニュー、第3パラにポップアップメニューハンドル
		AppendMenu hMenu.0, $10, hMenu.1, "メニュー1"
		AppendMenu hMenu.0, $10, hMenu.2, "メニュー2"
;		第2パラ$4000を加えて以降のメニュー位置が右側に
		AppendMenu hMenu.0, $10 | $4000, hMenu.3, "メニュー3"

;	ウィンドウにメニューを付ける
	SetMenu hwnd, hMenu.0
	DrawMenuBar hwnd

	stop

//	WM_COMMANDメッセージ
*command
;	メニューからのウィンドウメッセージ
	if lparam = 0 {
;		wparamの下位ワードにメニュー項目ID
		wID = LOWORD(wparam)

;		メニュー項目 「項目1」
		if wID = IDM_KOUMOKU1 {
			dialog "項目1 でーす"

			return
		}

;		メニュー項目 「項目2」
		if wID = IDM_KOUMOKU2 {
			if checkmenu {
				uCheck = $0 : checkmenu = 0
			} else {
				uCheck = $8 : checkmenu = 1
			}

;			チェックのオン/オフ
;			第3パラに$0(チェックはずす)、$8(チェックする)
			CheckMenuItem hMenu.1, IDM_KOUMOKU2, uCheck

			return
		}

		if wID = IDM_EXIT {
			gosub *exit

			return
		}

;		メニュー項目 「XXX」/「YYY」/「ZZZ」
		if wID >= IDM_XXX & wID <= IDM_ZZZ {
;			hMenu.3の$6〜$8をグループ化し、選択したそのwIDに黒丸
			CheckMenuRadioItem hMenu.3, IDM_XXX, IDM_ZZZ, wID, $100

			return
		}

		return
	}

	return

*exit
	dialog "終了しますか?", 2
	if stat = 7 : return

	end

 ちなみに、HSP3自体にメニュー表示のためのモジュール「common\mod_menu.as」も用意されてます(参考)。そのサンプルコード「sample\new\menubar.hsp」(HSP 3.2〜では「sample\basic\menusample.hsp」)です。モジュール内で上と同じ形でWin32 API関数を呼んでます。

↑TOP↑

右クリックメニューの表示

 ウィンドウ上でマウスを右クリックすると、右クリックメニュー(ポップアップメニュー、ショートカットメニュー)を表示させるサンプルスクリプトです。ここではonclick命令で右クリックを判定し、TrackPopupMenu関数でメニューを出現させてます。システム変数statに選択した項目IDが返ります。項目選択がキャンセルされた場合は0です。

//	ポップアップメニューの表示サンプルソース (by Kpan)
//	(注) エディタの[HSP]メニュー→[HSP拡張マクロを使用する]を要有効。 

#include "user32.as"

;	項目ID
#enum IDM_ITEM1 = 1
#enum IDM_ITEM2
#enum IDM_ITEM3
#enum IDM_ITEM4

	onclick gosub *onjump ; マウスをクリックした時
;	あるいはWM_CONTEXTMENU
;	oncmd gosub *onjump, $7B

	onexit *exit

;	<サブのポップアップメニュー>
;	サブメニューを作成し、ハンドルを取得
	CreatePopupMenu
	hMenu.0 = stat
;		第3パラはメニュー項目ID
		AppendMenu hMenu.0, 0, IDM_ITEM3, "サブメニュー項目 3"
		AppendMenu hMenu.0, 0, IDM_ITEM4, "サブメニュー項目 4"

;	<メインのポップアップメニュー>
;	メインのポップアップメニューを作成し、ハンドルを取得
	CreatePopupMenu
	hMenu.1 = stat
		AppendMenu hMenu.1, 0, IDM_ITEM1, "メニュー項目 1"
;		第2パラを$800にするとセパレータ(区切り線)になる。
		AppendMenu hMenu.1, $800, 0, ""
		AppendMenu hMenu.1, 0, IDM_ITEM2, "メニュー項目 2"
;		第2パラメータを$10にするとサブメニューへ。
;		第3パラにサブメニューのハンドルを入れる。
		AppendMenu hMenu.1, $10, hMenu.0, "サブメニュー"

	stop

*onjump
;	右クリックされた時
	if wparam = 2 {
;		ポップアップメニュー表示。第1パラに開くメニューのハンドル
		TrackPopupMenu hMenu.1, $100, ginfo(0), ginfo(1), 0, hwnd, 0
		if stat = 0 : return	; 選択キャンセル

;		statにメニュー項目ID
		dialog "項目 "+stat+" を選択!"

		return
	}

	return

*exit
;	どこのウィンドウにも張り付いていないメニューは明示的に破棄
	DestroyMenu hMenu.1

	end

↑TOP↑

ボタン脇にポップアップメニューの表示

 上の「右クリックメニューの表示」ではマウスの右クリックでメニューが表示されますが、ボタン(button命令)を押した時に、オブジェクト脇にポップアップメニュー表示させるサンプルスクリプトです。(ドロップダウンメニュー「風」?

 GetWindowRect関数でボタンの表示されている座標位置を取得し、それをポップアップメニューの表示位置として反映してやればOK。メニューの表示については上の2項目を参照。ボタンオブジェクトのハンドル取得はobjinfo関数を利用。

//	ボタン脇ポップアップメニュー表示サンプルソース (by Kpan)

#include "user32.as"

	onexit *exit

;	RECT構造体
	dim RECT, 4

	CreatePopupMenu
	hMenu.0 = stat
		AppendMenu hMenu.0, 0, $10, "は(&A)"
		AppendMenu hMenu.0, 0, $20, "ひ(&I)"
		AppendMenu hMenu.0, 0, $30, "ふ(&U)"
		AppendMenu hMenu.0, 0, $40, "へ(&E)"
		AppendMenu hMenu.0, 0, $50, "ほ(&O)"
		AppendMenu hMenu.0, 0, $60, "ー(&X)"

	pos 50, 50
	objsize 55, 24

	button ">>>", *openmenu
	hButton = objinfo(stat, 2) ; ボタンのハンドルを取得。

	stop

*openmenu
;	オブジェクトのサイズを取得するGetWindowRect関数
;	RECT構造体として左上XY座標、右下XY座標が返る
	GetWindowRect hButton, varptr(RECT)

;	ボタンの右側にメニュー表示
;	第3、第4パラにボタンの右上XY座標を指定
;	(RECT.0、RECT.3を指定すると、ボタンの真下にメニュー表示)
	TrackPopupMenu hMenu.0, $100, RECT.2, RECT.1, 0, hwnd, 0
	if stat = 0 : stop

	if stat = $10 : mes "は"
	if stat = $20 : mes "ひ"
	if stat = $30 : mes "ふ"
	if stat = $40 : mes "へ"
	if stat = $50 : mes "ほ"
	if stat = $60 : goto *exit

	stop

*exit
;	どこのウィンドウにも張り付いていないメニューは明示的に破棄
	DestroyMenu hMenu.0

	end

↑TOP↑

システムメニューに新たな項目追加

 システムメニューというのは、ウィンドウのタイトルバー上で右クリックした時とか、そのバーにあるアイコンをクリックした時に表示されるメニューです。[元のサイズに戻す]、[移動]、[サイズ変更]・・・、[閉じる]というような感じの項目が用意されてると思います。そこに自前の項目を用意してやるサンプルスクリプトです。

//	システムメニューに新規項目追加サンプルコード (by Kpan)

#include "user32.as"

;	項目ID
#enum IDM_ADD1 = 1
#enum IDM_ADD2

;	WM_SYSCOMMAND (システムメニューが選択された時)
	oncmd gosub *syscommand, $112

;	システムメニューのハンドルを取得
	GetSystemMenu hwnd, 0
		hSystemMenu = stat

;	第2パラメータに挿入位置(一番上が0)、第4パラがメニュー項目ID、
;	第5パラにメニュー項目に表示する文字列
	InsertMenu hSystemMenu, 0, $400, IDM_ADD1, "追加したー(&M)"
;	+$800 で区切り線
	InsertMenu hSystemMenu, 1, $400 | $800, 0, ""
	InsertMenu hSystemMenu, 5, $400, IDM_ADD2, "も一つ追加(&O)"

	stop

*syscommand
;	wparamにメニュー項目IDが返る
	if wparam = IDM_ADD1 {
		dialog "追加したものだー"
		return
	}

	if wparam = IDM_ADD2 {
		dialog "も一つ追加したものでアール"
		return
	}

	return

↑TOP↑

システムメニューの監視

 システムメニュー内の項目選択を監視します。メニューが選択されるとWM_SYSCOMMANDメッセージが通知されるので、wparamの下位ワードをチェックすると選択した項目が分かります。

//	システムメニューの監視 (by Kpan)

#define ctype LOWORD(%1) (%1 & $FFFF)

;	WM_SYSCOMMAND (システムメニューが選択された時)
	oncmd gosub *syscommand, $0112

	stop

*syscommand
;		$F010=ウィンドウが移動した
;		$F020=ウィンドウが最小化された
;		$F120=ウィンドウが元の位置に戻った
;		$F180=クエスチョンマーク?付きマウスポインタでクリックされた
	mes strf("$%X", LOWORD(wparam))

	return

↑TOP↑

システムメニューの項目削除 (移動できないウィンドウ)

 システムメニューにあらかじめ用意されている項目を削除します。これにより、タイトルバーをドラッグしてもウィンドウ位置を変更できないウィンドウにさせることもできます。ただ、[閉じる]項目は削除してしまうとプログラムの終了ができなくなるので注意(「Ctrl+Alt+Del」でプロセスを終了させる方法を)。

//	システムメニューの項目削除 (by Kpan)

#include "user32.as"

;	システムメニューのハンドルを取得
	GetSystemMenu hwnd, 0
	hSystemMenu = stat

;	メニュー項目削除。第2パラに削除するメニュー項目を指定
;	$F000=サイズ変更、$F010=移動、$F020=最小化、$F030=最大化、
;	$F060=閉じる、$F120=元のサイズに戻す、$0=区切り線
	DeleteMenu hSystemMenu, $F010, 0

↑TOP↑

〜HSP3 あれこれ〜
ウィンドウ | オブジェクト | ファイル | フォルダ | キーボード | マウス | メニュー | システム | 文字列 | COM | その他

Copyright © 2005-2012 . All rights reserved.