|
菜单的自描画(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()
{
m_bCheck = !m_bCheck;
AfxMessageBox(_T("Selected."));
}
void CMainFrame::OnUpdateEditOwnerdrawtest(CCmdUI *pCmdUI)
{
pCmdUI->SetCheck(m_bCheck);
}
void CMainFrame::OnDestroy()
{
CFrameWnd::OnDestroy();
m_OwnerDrawMenu.Detach();
}
|