Visual C++ 2008 MFC、XPです。
いままでTrackPopupMenu()で表示していたコンテキストメニューを
CMFCPopupMenuを使ったものに置き換えようとしています。
TrackPopupMenu()は、メニューが閉じられるまでそこで処理が止まり、
また、TPM_RETURNCMDを使えばコマンドをその場で取得することもできたのですが、
このへんの動きはCMFCPopupMenuでも実現できるものでしょうか?
CMFCPopupMenu::Create()では、作成した段階で次の処理に移ってしまうため、
現状で以下のような問題が発生しています。
・ツリービューのまだ選択されていないノード上で右クリックすると、
メニューが出たまま選択位置が元の位置に戻ってしまう
(NM_RCLICKのハンドラで移動してしまわないと見た目が不自然)
・右ドラッグ後の「ここに移動」などのようなものは、
OnContextMenu()ではなくOnRButtonUp()の中で表示しているが、
ドラッグ対象などの情報をOnRButtonUp()の最後で消しているため、
関数を抜けてからコマンドを受け取っても処理を行えない
(TPM_RETURNCMDを使いたい)
よろしくお願いいたします。
カメれすですみません。
3年以上前になりますか・・・(とほい目)。
http://rarara.cafe.coocan.jp/cgi-bin/lng/vc/vclng.cgi?print+200802/08020020.txt
で、TPM_RETURNCMDを選択したのがあだになっているかも知れませんねぇ。
CMFCPopupMenuはいわゆる純粋なメニューではなくてウインドウの一種になって
しまっています。実際、派生元を辿ればCWndですよね。
ということは、WM_CREATEを含む一連のメッセージを受信して動作することになり、
メニューの表示からユーザーの選択結果取得までを一気に実行して戻ってくる
といったことは原理的にできないのではないかと考えられます。
そうなると2択になってしまうかもしれません。
1.TrackPopupMenu()を使う
2.TPM_RETURNCMDを使わない仕組みに母屋を変更して、CMFCPopupMenuを使う
ですね。
ただし、CMFCPopupMenuの中身を良く追ってはいないので、それを派生させた
クラスで工夫をするとTPM_RETURNCMD相当の動作をさせらる可能性も
ゼロではないかもしれません。
労多くして実り少なしであればまだよいのですが、まったくの徒労になる
可能性が高いと考えられますが、どうでしょう(vv;)。
追加、orz.
モーダルっぽいコンテキストメニューを表示する方法として
CContextMenuManager::TrackPopupMenu()
ってのもあります。戻り値がIDぢゃなくてインデックスってのがアレですが、
TPM_RETURNCMD相当の動作と言えなくもないですね。
もっとも、母屋の土台がCWinAppExでないとだめだそうですが、
GetContextMenuManager()->AddMenu (_T(My menu), IDR_CONTEXT_MENU);
INDX indx = GetContextMenuManager()->TrackPopupMenu(・・・);
みたいな・・・。
仲澤@失業者さんに頂いたヒントを元に調べてみたところ、
ボタンを押した際にポップアップメニューが表示されるCMFCMenuButtonが、
キーやマウスが押されたタイミングで以下のようなことをやっていました。
if (!m_bOSMenu && afxContextMenuManager != NULL)
{
m_nMenuResult = afxContextMenuManager->TrackPopupMenu(m_hMenu, x, y, this);
SetFocus();
}
else
{
m_nMenuResult = ::TrackPopupMenu(m_hMenu, TPM_LEFTALIGN | TPM_LEFTBUTTON |
TPM_NONOTIFY | TPM_RETURNCMD, x, y, 0, GetSafeHwnd(), NULL);
}
if (m_nMenuResult != 0)
{
//-------------------------------------------------------
// Trigger mouse up event(to button click notification):
//-------------------------------------------------------
CWnd* pParent = GetParent();
if (pParent != NULL)
{
pParent->SendMessage( WM_COMMAND, MAKEWPARAM(GetDlgCtrlID(), BN_CLICKED),
(LPARAM) m_hWnd);
}
}
これはまさに、TPM_RETURNCMDを使っているTrackPopupMenu()を
CMFCPopupMenuに置き換えるための方法のようです。
このままだと、TPM_RIGHTBUTTONを再現することはできないでしょうけど、
その実現方法も含めてもうちょっと調べてみようと思います。
きっかけを頂きありがとうございます。
なお、以前教えていただいたOnMenuSelect()は、
CMFCPopupMenuを使ったコンテキストメニューでは呼ばれないようです。
任意のウィンドウやダイアログに、
CMFCPopupMenuが閉じるタイミングを知る仕組みがあればよいのですが。