掲示板システム
ホーム
アクセス解析
カテゴリ
ログアウト
オーナードロウメニューについて (ID:52814)
名前
ホームページ(ブログ、Twitterなど)のURL (省略可)
本文
レスありがとうございます。 メニューはダイアログ上のOnRButtonUp()ないで、TrackPopupMenu()で ポップアップメニューとして表示させています。 開発環境は、celeron700MHz/Windows98SE/VC++ sp5 です。 メニュークラスはClass Wizardで「MFC:generic CWnd」で 「CCustomMenu」を作成して、CWndからの継承をCMenuに書き換えました。 (宣言:class CCustomMenu : public CMenu{ 〜 };) そして、 virtual void DrawItem( LPDRAWITEMSTRUCT lpDrawItemStruct ); virtual void MeasureItem( LPMEASUREITEMSTRUCT lpMeasureItemStruct ); として、オーバーライドしています。 また、アイテム追加用関数を作成しました。CMenu::AppnedMenuとほとんど同じ仕様です。 (オーナードロウの場合、アイテム情報を自前で用意しなければならないようなので) m_listItemPtrはCList型で、自前のアイテム情報構造体のポインタのリストです。 BOOL CCustomMenu::AppendItem (UINT uFlags, UINT uID, LPCTSTR strText, HICON hIcon) { //セパレータなら、アイテム情報は作成しません if( uFlags & MF_SEPARATOR ) return CMenu::AppendMenu( MF_OWNERDRAW); //アイテム情報の設定 PCUSTOMMENUITEM pitem = new CUSTOMMENUITEM; m_listItemPtr.AddTail(pitem); pitem->uID = uID; pitem->strText = strText; pitem->hIcon = hIcon; pitem->pSubMenu = NULL; //サブメニューの場合、新たにサブメニューを作成します if( uFlags & MF_POPUP ) { CCustomMenu* pSubMenu = (CCustomMenu*)uID; pitem->pSubMenu = new CCustomMenu; pitem->pSubMenu->Attach(pSubMenu->Detach()); uID = (UINT)(pitem->pSubMenu->GetSafeHmenu()); } return CMenu::AppendMenu(uFlags | MF_OWNERDRAW, uID, (LPCTSTR)pitem); } これで、ポップアップメニューを以下のように表示させます。 void CTestCustomMenuDlg::OnRButtonUp(UINT nFlags, CPoint point) { CPoint pt = point; ClientToScreen(&pt); CCustomMenu sub2; sub2.CreatePopupMenu(); sub2.AppendItem( NULL, 31, "menu3-1"); CCustomMenu sub1; sub1.CreatePopupMenu(); sub1.AppendItem( NULL, 21, "menu2-1"); sub1.AppendItem( MF_POPUP, (UINT)&sub2, "menu2-2"); sub1.AppendItem( NULL, 23, "menu2-3"); CCustomMenu menu; menu.CreatePopupMenu(); menu.AppendItem( NULL, 11, "menu1-1"); menu.AppendItem( MF_POPUP, (UINT)&sub1, "menu1-2"); menu.AppendItem( NULL, 13, "menu1-3"); menu.TrackPopupMenu( TPM_LEFTALIGN, pt.x, pt.y, this); CDialog::OnRButtonUp(nFlags, point); } すると、MF_POPUPを指定しているアイテムだけオーバーライドした CCustomMenu::MeasureItem()を呼び出してくれません。 (DrawItemはやっぱり呼び出されています。) また、この代行策は、メニューアイテム情報を持つための親クラスを持たない クラスを作成して、仮想関数でないDrawItem/MeaureItemを用意しました。 そして、メニュー呼び出したダイアログウィンドウのWindowProc()を オーバーライドして、以下のようにしてオーナードロウを実現しました。 if( message == WM_DRAWITEM && wParam == 0 ) { DrawItem( (LPDRAWITEMSTRUCT)lParam); } else if( message == WM_MEASUREITEM && wParam == 0 ) { MeasureItem( (LPMEASUREITEMSTRUCT)lParam); } ただ、どちらの方法でもWindows98では通常に表示されますが WinodwsXPでは最初の発言のような現象になります。
←解決時は質問者本人がここをチェックしてください。
戻る
掲示板システム
Copyright 2021 Takeshi Okamoto All Rights Reserved.