antenn-a
company profile

MFC航海日記 六十三日目(右クリックメニューのハンドリング)


さて、今回は右クリックメニューの実装方法です。
想像付くと思いますが、CMenu クラスを使います。
で、楽しようとか思ってうっかりMSDNのヘルプからパクって来ちゃったんですけど、これがまた動かなくてなんでだろー?と相当悩んでしまいました。
俺ってアホですな!
何が悪いって、今回のケースの場合は SDI アプリにダイアログを貼り付けて、その上でやろうとしてるワケですよ。
で、鼻歌交じりで以下のコードを書いたんだけど、
CMenu	menu;
CMenu	submenu;
submenu.CreatePopupMenu();

VERIFY( menu.LoadMenu( IDR_MENU_TEST ) );
CMenu* pPopup = menu.GetSubMenu(0);
ASSERT(pPopup != NULL);

pPopup->TrackPopupMenu( TPM_LEFTALIGN | TPM_RIGHTBUTTON, point.x, point.y, AfxGetMainWnd() );
						

当然メニューのイベントがハンドリング出来ないんですよ。ま、今見ると当たり前なんですが。
理由は TrackPopupMenu 関数の第4引数。
AfxGetMainWnd() とかちゃっかりなってて(俺が書いたんだろうが(笑))これじゃー取れるわけないですね。
ここ、結構間違えやすいポインツだと思うんですけど、こいつってばハンドリングするウィンドウクラスのポインタを渡す所なんですよ。
だから、本当は
pPopup->TrackPopupMenu( TPM_LEFTALIGN | TPM_RIGHTBUTTON, point.x, point.y, this );
とかしないと駄目だった、という落ちでした。

prev


ちなみに、上記コードで動くのはVC7です。VC5(VC6も?)は駄目です。
バグなんだか、仕様なんだか知らないんですけど、メッセージがダイアログに流れて来なくて、ダイアログで右クリックメニューを実装するのに偉い苦労したんですよ奥さん。
OnCmdMsg()をオーバーライトして、関数書かなきゃいけないし。と、いうトラウマが有ったんですが、VC7だとサックリ上記コードで動きます。
なーんだ、やっぱバグじゃんか、と言いたくなりますね!
で、実際にやりたい事は、これだけじゃ無くて、動的にメニューを追加したいんですよ。
写真を別のアルバムに移動させる時に、「写真の移動」-「アルバム名」としたいんですけど、アルバムの数は動的に変わるので、と。
下記がリソースエディタで作ったメニューにサブメニューを追加して、その下に項目を更に追加するコード。
CMenu        menu;
CMenu        submenu;
CStringArray m_MenuItems;
int		i;
submenu.CreatePopupMenu();

m_MenuItems.Add( _T( "プログラムで追加したメニュー1" ) );
m_MenuItems.Add( _T( "プログラムで追加したメニュー2" ) );
m_MenuItems.Add( _T( "プログラムで追加したメニュー3" ) );

VERIFY( menu.LoadMenu( IDR_MENU_TEST ) );
CMenu* pPopup = menu.GetSubMenu(0);
ASSERT(pPopup != NULL);

pPopup->AppendMenu( MF_POPUP, (UINT_PTR)submenu.m_hMenu, "プログラムにより追加したメニューたち" );
for( i = 0; i < 10; i++ )
    submenu.AppendMenu( MF_STRING, ID_MENUID_START_NUM + i, m_MenuItems[ i ] );
pPopup->TrackPopupMenu( TPM_LEFTALIGN | TPM_RIGHTBUTTON, point.x, point.y, this );
						

コードを見ていただければ分かると思いますが、こうやって実装するっぽいっすね。
ちなみに InsertMenu という関数も有るので、好きな位置に挿入できます。

prev


今回のサンプルはここからダウンロード出来ます。
ま、今回もちょっとしたTIPSみたいな物ですね。


antenn-a

prev next


antenn-a