オーナー描画メニューについて質問があります。
CMenu::DrawItem() と CMenu::MeasureItem() をオーバーライドして、
オーナー描画をしようとしているのですが、ポップアップメニューアイテムの
処理がうまくいきません。
手順は、
1.CFrameWnd 派生クラスの OnCreate() 内で、GetMenu()でメニューハンドルを取得。
2.上記ハンドルを静的属性のCMenu派生クラスオブジェクトにAttach()する。
3.アタッチしたメニューの各アイテム属性を、ModifyMenu() でオーナー描画に変更する。
上記で、通常メニューアイテムはうまく処理できるのですが、ポップアップメニューアイテム
をオーナー描画属性にしてしまうと、そこを選択しても、
サブメニューが開かなくなってしまいます。(描画自体はうまくいく)
アイテム属性の変更は、以下のようにしています。
・通常アイテムメニューアイテム
ModifyMenu(Pos, MF_BYPOSITION | MF_OWNERDRAW, 現在のID, アプリ定義の情報アドレス);
・ポップアップメニューアイテム
ModifyMenu(Pos, MF_BYPOSITION | MF_OWNERDRAW | MF_POPUP, CMenuオブジェクトアドレ
ス(サブメニューのもの), アプリ定義の情報アドレス);
ヘルプを見ると、MF_POPUPを設定するときは、
第三引数にはサブメニューのHMENUを指定するとあるので、
CMenu* pSubMenu = ...;
ModifyMenu(Pos, MF_BYPOSITION | MF_OWNERDRAW | MF_POPUP,
pSubMenu->GetSafeHmenu(), アプリ定義の情報アドレス);
では、ないでしょうか?
ところで、ポップアップメニューをオーナー描画するには、
WM_MEASUREITEMを自分で処理する必要があります。
MFCは、メニューIDを元にオーナー描画オブジェクトを検索するのですが、
ポップアップメニューには、IDがないからです。(MFCのバグ?)
ご返事ありがとうございます。
私も、最初は dairygoods さん指摘のとおり、
MF_POPUPを設定したときは、第三引数にはサブメニューのHMENUを
設定していたのですが、これだと、
CMenu::MeasureItem() がコールされませんでした。
そのため、色々試したなかで、第三引数にサブメニュークラスの
実体アドレスを設定すると、CMenu::MeasureItem()がコールされる
ようになったので、そのままにしていました。
(たぶん、コール元のCWnd::OnMeasureItem() がアドレスをメニューIDと
勘違いした結果だと思います。)
コール元関数のCWnd::OnMeasureItem() を
調べみたのですが、ポップアップメニューアイテムでは、
CMenu::MeasureItem()はコールされない構造みたいですね。
(未対応なのか、バグなのか?)
独自にWM_MEASUREITEMメッセージハンドラを追加して処理してみます。