[kaze's test] プログラミングメモ →目次

メニューのオーナー描画(VC++)

一番簡単なメニューのオーナー描画の手順をメモします。SDIプロジェクトを作成します。メニューの[Edit]の一番下に[OwenerDrawTest]というメニュー項目を追加します。このメニュー項目の状態を色で表現するようにオーナー描画を行います。


//手動でCMenuクラスから、COwnerDrawMenuを派生します。
class COwnerDrawMenu : public CMenu
{
public:
	COwnerDrawMenu() {}
	virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);
	virtual void MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct);
};
//オーナー描画関数を実装します。
void COwnerDrawMenu::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
    CDC *pDC = CDC::FromHandle(lpDrawItemStruct->hDC);
	if (lpDrawItemStruct->itemAction & ODA_DRAWENTIRE)
	{
		pDC->FillSolidRect(&lpDrawItemStruct->rcItem, (COLORREF)0x00c0c0c0);
		CString rString;
		int iCount = GetMenuString(6, rString, MF_BYPOSITION);
		pDC->SetBkMode(TRANSPARENT);
		pDC->DrawText(rString, &lpDrawItemStruct->rcItem, 
                          DT_SINGLELINE|DT_VCENTER|DT_CENTER);
	}

	COLORREF cr = RGB(0,255,0);
	if (lpDrawItemStruct->itemState & ODS_CHECKED)
		cr = RGB(0,0,255) ;

	if (lpDrawItemStruct->itemAction & ODA_SELECT)
	{
		if (lpDrawItemStruct->itemState & ODS_SELECTED)
			cr = RGB(255,0,0) ;
	}
	
	CBrush br(cr);
	CRgn rgn;
	rgn.CreateRectRgnIndirect(&lpDrawItemStruct->rcItem) ;
	pDC->FrameRgn(&rgn,&br,4,4) ;

}
//MeasureItem関数を実装します
void COwnerDrawMenu::MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct)
{
	lpMeasureItemStruct->itemWidth = 100;
	lpMeasureItemStruct->itemHeight = 50;
}

//CMainFrameのクラスの中にCOwnerDrawMenu型の変数m_OwnerDrawMenuを追加します。
//class CMainFrame : public CFrameWnd
//{
//...
COwnerDrawMenu m_OwnerDrawMenu;
BOOL m_bCheck;
//...
//...

//[OwenerDrawTest]というメニュー項目のプロパティをオーナー描画に変更します。
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
	if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
		return -1;
	
	if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, 
            WS_CHILD | WS_VISIBLE | CBRS_TOP
		| CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) 
           ||
		!m_wndToolBar.LoadToolBar(IDR_MAINFRAME))
	{
		TRACE0("Failed to create toolbar\n");
		return -1;      // fail to create
	}

	if (!m_wndStatusBar.Create(this) ||
		!m_wndStatusBar.SetIndicators(indicators,
		  sizeof(indicators)/sizeof(UINT)))
	{
		TRACE0("Failed to create status bar\n");
		return -1;      // fail to create
	}

	// TODO: Delete these three lines 
      // if you don't want the toolbar to be dockable
	m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);
	EnableDocking(CBRS_ALIGN_ANY);
	DockControlBar(&m_wndToolBar);


	CMenu* pMenu = GetMenu();
	CMenu* pSubMenu = pMenu->GetSubMenu(1);		//Menu: [Edit]
	MENUITEMINFO MenuItemInfo;
	MenuItemInfo.cbSize = sizeof( MENUITEMINFO);
	MenuItemInfo.fMask = ( MIIM_STATE | 0x100);
	pSubMenu->GetMenuItemInfo(6, &MenuItemInfo, TRUE);
	MenuItemInfo.fType |= MFT_OWNERDRAW;
	SetMenuItemInfo(pSubMenu->m_hMenu, 6, TRUE, &MenuItemInfo);
	m_OwnerDrawMenu.Attach(pSubMenu->GetSafeHmenu());

	m_bCheck = TRUE;

	return 0;
}

void CMainFrame::OnEditOwnerdrawtest()
{
	// TODO: Add your command handler code here
	m_bCheck = !m_bCheck;
	AfxMessageBox(_T("Selected."));
}

void CMainFrame::OnUpdateEditOwnerdrawtest(CCmdUI *pCmdUI)
{
	pCmdUI->SetCheck(m_bCheck);
}

void CMainFrame::OnDestroy()
{
	CFrameWnd::OnDestroy();
	m_OwnerDrawMenu.Detach();
}