- ベストアンサー
メニューの表示・非表示について
- ツールバーの場合、ダブルクリックすると表示されているときには非表示になり、非表示のときには表示することができます。
- メニューバーの場合、非表示になります。表示される場合は、メニューバーを再度表示することで表示されます。
- メニューバーの表示状態に関係なく、ツールバーのように表示されているときは非表示にし、非表示の場合は表示する方法が知りたいです。
- みんなの回答 (2)
- 専門家の回答
質問者が選んだベストアンサー
いま環境がないんで、とりあえずヒントだけ。 まず、メニューの有無をCWnd::GetMenu()で判断すれば、表示非表示の切りかえは、問題ないでしょう。 MFCのCFrameWndでは、初期表示時にメニューがあった場合、OnDestroyが呼ばれたタイミングで同じメニューがないとASSERTを吐くようです。(確認済み) なんで、初期表示時に表示していたメニューは、OnDestroyが呼ばれたタイミングで元に戻しておく必要があることになります。 載せていただいたソースなのですが、CMenu::Detach()の戻り値、ほったらかしですよね。 通常は、::DestroyMenu()を呼び出したり、HMENU型の変数に入れて保持しておかないと、リソースのリークが発生します。 今回は、HMENU型の変数をメンバ変数で定義しておけば、CMenu::Detach()で取得したメニューハンドルを使いまわすことで毎回CMenu::LoadMenu()を呼ぶ必要もなくなりますし、破棄をするのを忘れることもなくなりますし、 OnDestroy()でメニューを戻してあげることが可能になります。 もちろん、HMENUではなく、CMenuでメンバ変数を宣言しても可能ですよ。 あと、WM_COMMANDはSendMessageで送らないほうがいいですよ。PostMessageで送るべきです。
その他の回答 (1)
- taka_tetsu
- ベストアンサー率65% (1020/1553)
>menu.LoadMenu(IDR_MAINFRAME);は同じくメニューのポインタを >menuに代入しているのでしょうか? >プログラム的にはそうでないとおかしいと思うのですが、 >代入演算子=がないので、直感的にはおかしく感じるのですが。 Win32APIで使う、HMENUとMFCのCMenuのインスタンスを 混同されているようですね。 LoadMenuの1行上に、 CMenu menu; という記述がありますよね。 この時点で、CMenu型の、menuというインスタンスを作成しています。 (C++の文法的に、中カッコで囲まれている部分なので、 その上で宣言しているCMenu * の変数と同名でもエラーになりませんが、 ソースの可読性から見るとわけがわからなくなるのでやめた方がいいですよ) この時点では、 CMenuのインスタンス・・・存在 CMenuの中のメニューハンドル・・・存在しない という状態です。 menu.LoadMenu(IDR_MAINFRAME) をコールすることによって、 CMenuのインスタンス・・・存在 CMenuの中のメニューハンドル・・・存在 という状態になります。 ということで、代入ではありません。 直感の方が正しいです。 ここらへんは、MFCというよりC++ですね。
お礼
回答ありがとうございます。
お礼
>まず、メニューの有無をCWnd::GetMenu()で判断すれば、表示非表示の切りかえは、問題ないでしょう。 とりあえず以下のようにして、強引に目的のみは達成しました。 ここでまた疑問がひとつ。 CMenu *menu = wnd->GetMenu();のようなコードは、メニューのポインタをmenuに代入しているということが直感的に良く分かるのですが、 menu.LoadMenu(IDR_MAINFRAME);は同じくメニューのポインタをmenuに代入しているのでしょうか? プログラム的にはそうでないとおかしいと思うのですが、代入演算子=がないので、直感的にはおかしく感じるのですが。 アドバイスを頂きたいです。 *************************** CWnd *wnd = GetParent(); CMenu *menu = wnd->GetMenu(); if(*menu == NULL) { CMenu menu; menu.LoadMenu(IDR_MAINFRAME); AfxGetMainWnd()->SetMenu(&menu); menu.Detach(); } else { AfxGetMainWnd()->SetMenu(NULL); }