因为框架窗口是菜单的所有者,它接收自制菜单项产生的消息WM_MEASUREITEM和WM_DRAWITEM。
1、在MainFrame中实现 OnMeasureItem和OnDrawItem函数
void CMainFrame::OnMeasureItem( int nIDCtl, LPMEASUREITEMSTRUCT lpMeasureItemStruct )
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
lpMeasureItemStruct->itemWidth = ::GetSystemMetrics( SM_CYMENU ) * 4;
lpMeasureItemStruct->itemHeight = ::GetSystemMetrics( SM_CYMENU );
CFrameWnd::OnMeasureItem( nIDCtl, lpMeasureItemStruct );
}
void CMainFrame::OnDrawItem( int nIDCtl, LPDRAWITEMSTRUCT lpDrawItemStruct )
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
BITMAP bm;
CBitmap bitmap;
bitmap.LoadOEMBitmap( OBM_CHECK );
bitmap.GetObject( sizeof( bm ), &bm );
CDC dc;
dc.Attach( lpDrawItemStruct->hDC );
CBrush* pBrush = new CBrush( ::GetSysColor( ( lpDrawItemStruct->itemState &
ODS_SELECTED ) ? COLOR_HIGHLIGHT : COLOR_MENU ) );
dc.FrameRect( &( lpDrawItemStruct->rcItem ), pBrush );
delete pBrush;
if ( lpDrawItemStruct->itemState & ODS_CHECKED ) {
CDC dcMem;
dcMem.CreateCompatibleDC( &dc );
CBitmap* pOldBitmap = dcMem.SelectObject( &bitmap );
dc.BitBlt( lpDrawItemStruct->rcItem.left + 4, lpDrawItemStruct->rcItem.top +
( ( ( lpDrawItemStruct->rcItem.bottom - lpDrawItemStruct->rcItem.top ) -
bm.bmHeight ) / 2 ), bm.bmWidth, bm.bmHeight, &dcMem,
0, 0, SRCCOPY );
dcMem.SelectObject( pOldBitmap );
}
UINT itemID = lpDrawItemStruct->itemID & 0xFFFF; // Fix for Win95/98 bug
pBrush = new CBrush( m_wndView.m_clrColors[itemID - ID_COLOR_RED] );
CRect rect = lpDrawItemStruct->rcItem;
rect.DeflateRect( 6, 4 );
rect.left += bm.bmWidth;
dc.FillRect( rect, pBrush );
delete pBrush;
dc.Detach();
CFrameWnd::OnDrawItem( nIDCtl, lpDrawItemStruct );
}
2、在CXXXApp实现标题栏菜单的重绘
</pre><pre name="code" class="cpp">CXXXApp::InitInstance()
{
...
<span style="white-space:pre"> </span>// 唯一的一个窗口已初始化,因此显示它并对其进行更新
pFrame->ShowWindow(SW_SHOW);
pFrame->UpdateWindow();
//
// Convert the items in the Color menu to owner-draw.
//
CMenu* pMenu = pFrame->GetMenu();
ASSERT( pMenu != NULL );
for ( int i = 0; i < 5; i++ )
pMenu->ModifyMenu( ID_COLOR_RED + i, MF_OWNERDRAW,
ID_COLOR_RED + i );
return TRUE;
}