メニューバーのデザイン

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
AC

メニューバーのデザイン

#1

投稿記事 by AC » 16年前

ただいまWin32API学習中の者です。
また、こちらのフォーラムで質問させていただきます。

さて、本題ですがタイトル通りメニューバーのデザインがちょっとした書き方の違いで変わることが分かりその原因を知りたいのです。
もともと以下のソースで付加していて、この時は立体的なデザインでした(メニューのリソース名をIDR_MENUとします)。
// 立体的なメニューバーになる場合(ウィンドウプロシージャ部分のみ)
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)
{
	static HMENU hMenu;
	switch(msg)
	{
	case WM_CREATE:
		hMenu = LoadMenu(NULL, _T("IDR_MENU"));
		SetMenu(hWnd, hMenu);
		break;
	case WM_DESTROY:
		DestroyMenu(hMenu);
		SetMenu(hWnd, NULL);
		PostQuitMessage(0);
		break;
	default:
		return DefWindowProc(hWnd, msg, wp, lp);
	}
	return 0;
}
で、上のソースを見ていてメニュー付加の部分だけを関数化できそうだったので
BOOL CreateMenuBar(HWND hWnd)
{
	HMENU hMenu;
	hMenu = LoadMenu(NULL, _T("IDR_MENU"));
	SetMenu(hWnd,hMenu);
	return	DestroyMenu(hMenu);
}
のようにして、CreateWindow()の直後に呼んでみたのですが、その結果メニューバーのスタイルがフラットになってしまいました。
また、WNDCLSSEX構造体で直接指定した場合は立体的なスタイルでした。

自分の考えとしては
CreateWindow()→WM_CREATEメッセージ送信(一度しか呼ばれない)→メニューセット→…
という流れだと思っているのでやってることは一緒じゃないのかなぁと思うのですが、どうなのでしょう?

もし原因のわかる方がいらっしゃいましたら、ご回答いただけたらと思います。
また、もしあとからCreateMenuBar()のようにして付加する場合で立体的なメニューバーを作成する方法があるのならば、その方法も教えていただけたらと思います。
よろしくお願いします。

toyo

Re:メニューバーのデザイン

#2

投稿記事 by toyo » 16年前

DestroyMenu(hMenu);
で壊してるからではないでしょうか。

AC

Re:メニューバーのデザイン

#3

投稿記事 by AC » 16年前

toyoさん回答ありがとうございます。
BOOL CreateMenuBar(HWND hWnd)
{
	HMENU hMenu;
	hMenu = LoadMenu(NULL, _T("IDR_MENU"));
	return SetMenu(hWnd,hMenu);
}
のようにしたところ、立体的なデザインになりました。
今MSDN見てみましたが、DestroyMenu()をしなければならない条件は「どのウィンドウにも割り当てられていないメニュー」ということですので、↑のような場合はSetMenuでhWndのウィンドウに割り当てられているので明示的に解放する必要はなかったのですね。

ただDestroyMenu()をするのとしないので何が変わっているのでしょうか?
なぜメニューのメモリを開放しないでおくと立体的なデザインのままで、解放するとフラットになるのでしょうか?
DestroyMenu()をしても、コントロールとしての機能は失われていないようなので(WM_COMMANDメッセージは送信されているようです)、そこの部分がどうも納得いかないのですが…。

それと、LoadMenu()第一引数はインスタンスハンドルをちゃんと指定した方が良いのでしょうか?

すこし細かい話ですが、よろしくお願いいたします。

御津凪

Re:メニューバーのデザイン

#4

投稿記事 by 御津凪 » 16年前

LoadMenu で取得したルリソースデータは、プログラムが終了するまでメモリ上に残り続けます。
なので、 DestroyMenu() を呼んだら開放されるわけではなく、
恐らく開放されない原因(バグ?)でフラットになっていると思いますがちょっと分かりません。

> それと、LoadMenu()第一引数はインスタンスハンドルをちゃんと指定した方が良いのでしょうか?

第一引数が NULL の場合、自分自身を指すので、外部DLLで読み込む場合以外は NULL で大丈夫です。

AC

Re:メニューバーのデザイン

#5

投稿記事 by AC » 16年前

御津凪さん、的確な回答いつもありがとうございます。

なるほど、バグっぽいですか。納得しました。

これで解決に致します。
回答してくださった皆様どうもありがとうございました。

閉鎖

“C言語何でも質問掲示板” へ戻る