ひろと申します。
あるディレクトリ配下のディレクトリやファイルで構成されている
オリジナルメニューを作成しようとしています。
そのときにオーナードローで、アイコンを設定しようと考えていますが、
ディレクトリ/ファイル名はメニューに設定されていますが、
ディレクトリの幅がきちんと設定されていません。
DrawItemとMeasureItemにダンプを追加してみたところ
DrawItemはディレクトリ/ファイルメニュー表示時に正常にコールされますが、
MeasureItemはディレクトリの時だけコールされませんでした。
主な処理は下記のようにしています。
BOOL CFooMenu::CreateMenu(CFooMenu *pFooMenu, int *piPos, ...)
{
CFooMenu *pFooSubMenu;
:
if (ディレクトリの場合) {
pFooSubMenu = new CFooMenu;
:
オリジナルデータ作成&設定
:
pFooSubMenu->CreatePopupMenu();
CreateMenu(pFooSubMenu, piPos, ...);
pFooMenu->InsertMenu(-1,
MF_BYPOSITION | MF_POPUP | MF_OWNERDRAW,
(UINT)pSubMenu->m_hMenu,
(LPCTSTR)オリジナルデータ);
:
}
else if (ファイルの場合) {
:
オリジナルデータ作成&設定
:
pFooMenu->InsertMenu(-1,
MF_BYPOSITION | MF_OWNERDRAW,
WM_USER + *piPos,
(LPCTSTR)オリジナルデータ);
(*piPos)++;
}
:
}
オリジナルデータには、DrawItemやMeasureItemで使用する
メニュー文字列やアイコンのハンドルを設定しています。
環境はWindows2000、VC++6.0、MFCです。
なにか心当たりがある方がいらっしゃいましたら
コメントをよろしくお願いします。
バグなのか仕様なのかは分かりませんが、
ポップアップメニュー項目に対するMeasureItemは呼び出されません。
CWnd::OnMeasureItem()
のソースを見てみると、メニューIDから対応するCMenuを探していますが、
ポップアップメニューにはIDがないためです。
OnMeasureItem()を自分で実装しなおせば何とかなると思います。
dairygoodsさま
リプライが遅くなり申し訳ございません。
体調を崩してしまい、仕事を休んでいます。
復帰後に下記のような感じで試してみます。
ヘッダ:FooMenu.h
afx_msg void OnMeasureItem(int nIDCtl,
LPMEASUREITEMSTRUCT lpMeasureItemStruct);
ソース:FooMenu.cpp
void CFooMenu::OnMeasureItem(int nIDCtl,
LPMEASUREITEMSTRUCT lpMeasureItemStruct)
{
if (lpMeasureItemStruct->CtlType == ODT_MENU) {
HMENU hMenu = (HMENU)lpMeasureItemStruct->itemID;
if (::IsMenu(hMenu)) {
CFooMenu* pMenu = CFooMenu::FromHandle(hMenu);
if (pMenu) {
pMenu->MeasureItem(lpMeasureItemStruct);
return;
}
}
}
CMenu::OnMeasureItem(nIDCtl, lpMeasureItemStruct);
}
あまり良く分かっていませんので、
つっこみどころがあればコメントいただければ幸いです。
よろしくお願いします。
> CFooMenu* pMenu = CFooMenu::FromHandle(hMenu);
CMenu::FromHandlePermanent(hMenu);
の方が良さそうです。
FromHandle()だと既存オブジェクトがない場合、
一時オブジェクトを作って返してきます。
dairygoodsさま
コメントありがとうございます。
よくよく考えたら、CMenuはCWndから派生されていませんので、
OnMeasureItemは呼ばれませんね。。。
ということで、教えていただきました
> CMenu::FromHandlePermanent(hMenu);
の部分を修正してCMainFrameに記述したところ
うまくいきました。
いろいろとありがとうございました。