maru さん
お世話になっております。
Create関数の中で下記のように実装しました。
if (menu.m_hMenu == NULL)
{
menu.LoadMenu(IDR_xxxxx); // メニューをリソースからロード
}
m_hMenuShared = menu.m_hMenu;
LPCTSTR lpszClass = AfxRegisterWndClass(CS_HREDRAW | CS_VREDRAW,
LoadCursor(NULL, IDC_ARROW),reinterpret_cast<HBRUSH>(COLOR_WINDOW+1),
/*LoadIcon(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDI_MANDELBROT))*/ NULL);
int position = 1;
CMenu* pMenu = GetMenu();
CMenu* pSub = pMenu->GetSubMenu(position);
pMenu->ModifyMenu(position, MF_BYPOSITION | MF_POPUP
, UINT_PTR(pSub->m_hMenu), _T(test));
DrawMenuBar();
ですが、やはりGetMenu()でアプリケーションエラーになってしまいます。
LoadMenu()はエラーが返ってきておりませんので、正常に登録できているのだと思うので
すが、なぜか取得することができません。
親ウィンドウとの違いが何なのかイマイチ分かりません。。。
> ですが、やはりGetMenu()でアプリケーションエラーになってしまいます。
> LoadMenu()はエラーが返ってきておりませんので、
すでにメニューオブジェクト(static CMenu menu;)を持っているのにどうして
GetMenu()しようとするのかな?
LoadMenu()したオブジェクトに変更を加えればいいのに...
それに、メニューに変更を加えるとしたら、メニューのロードを行った時だけで
よいはずなので、ModifyMenu()等は
if (menu.m_hMenu == NULL)
{
menu.LoadMenu(IDR_xxxxx); // メニューをリソースからロード
の直後でしょ。
> 親ウィンドウとの違いが何なのかイマイチ分かりません。。。
ここはCreate()の中で、ここではまだウィンドウを作成していないのだから
GetMenu()がエラーになるのは当たり前のような...
元のコードでは、この関数(create)の最後に派生元クラス(CMDIChildWnd)
のCreateを呼んでいるんだから。
やみくもにコードを書いて試すより、じっくりと内容を理解してからコーディング
することをお勧めします。メニューの動的更新にはMFCに「DYNAMENU」というサン
プルコードがあります。
> LoadMenu()したオブジェクトに変更を加えればいいのに...
というか、以前に
> タフマンさんの場合、ここでLoadMenuの代わりにCMenuを用意されたテキストファイル
> から生成して、そのハンドルをhMenuShared にセットしてあげればいいんじゃないか
と。
と書いたとおり、CMenu::LoadMenuの代わりにCMenu::CreateMenu、CMenu::AppendMenu
等のCMenuクラスのメソッドを駆使して自前のメニューを作りあげることを提案したこと
を思い出しました。
まあ、ロードしてから変更するのも、自前で生成するのも結果は同じなんだろうけど。
maru さん
いつもありがとうございます。
結果から言いますと、変更できました。
ですが、問題があります。
Releaseモードだと実行可能ですが、Debugモードですとアプリケーションエラーが発生し
ます。
逆のパターンはよくあるのですが。。。
一部抜粋しますと、
int loop1;
CMenu menu;
CMenu* pSub;
if (menu.m_hMenu == NULL)
{
menu.LoadMenu(IDR_xxxxxxx); // メニューをリソースからロード
// メインメニューを変更
for(loop1 = 0; loop1 < 5; loop1++){
pSub = menu.GetSubMenu(loop1);
menu.ModifyMenu(loop1, MF_BYPOSITION | MF_POPUP, UINT_PTR(pSub->m_hMenu),
test));
}
}
m_hMenuShared = menu.m_hMenu;
LPCTSTR lpszClass = AfxRegisterWndClass(CS_HREDRAW | CS_VREDRAW,
LoadCursor(NULL, IDC_ARROW),reinterpret_cast<HBRUSH>(COLOR_WINDOW+1),
/*LoadIcon(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDI_MANDELBROT))*/ NULL);
このような形で実装しています。
m_hMenuShared = menu.m_hMenu;
をコメントアウトするとアプリケーションエラーは発生しません。
メインメニューを変更している部分も削除して、menu.LoadMenu()だけにしても同じです。
m_hMenuSharedにロード&モディファイしたメニューを設定しなければならないと思うの
ですが、何か悪いのでしょうか?
>ここはCreate()の中で、ここではまだウィンドウを作成していないのだから
>GetMenu()がエラーになるのは当たり前のような...
メインフレームの方はOnCreate()の中で同じ処理をしていたので、子フレームのCreate()
の方でも同じことだと思いました。
なぜメインフレームの方は大丈夫なのでしょうか。
私の環境では特に問題なく実行できていますが。。。
全体がわからないので、アプリケーションエラーの原因は分かりかねます。
デバッグモードで発生するのであれば、発生か所を特定し、その原因を調べることは
可能では無いですか?
以前にも挙げていますが、MSDNにいろいろなサンプルがありますのでそれらを研究し
たら如何。
今、改めてコードを見て原因が思いつきました。
タフマンさんのコードでは
CMenu menu;
がローカルに宣言されています。ローカルに宣言したオブジェクトのメンバーを
m_hMenuShared = menu.m_hMenu;
としているので、アプリケーションエラーが発生しているものと思われます。
以前のサンプルコードをよく確かめて、menu がどこに宣言されているか、確認して
みてください。
maru さん
サンプルも参考にしながら色々とやってみると変更する事ができました。
しかし、数点変更したので何が原因だったのか分からなくなってしまったのですが(汗)。
maruさんにご指摘頂いたように、CMenuをローカル宣言していたのがアプリケーションエ
ラーの理由でした。
大変お恥ずかしいです。バグまで発見して頂いてお詫びと感謝いたします。
おかげで変更することができ、とても感謝しております。
ありがとうございました。