1、在view中加入:
void CDrawMyMenuView::OnContextMenu(CWnd* pWnd, CPoint point)
{
// TODO: 在此处添加消息处理程序代码
//初始化菜单标题
CString strTitle[]=
{
_T("第一"),
_T("第二"),
_T("第三"),
_T("程序文档"),
_T("设置"),
_T("文档"),
_T("搜索"),
_T("帮助和支持"),
_T("运行"),
_T("关机")
};
//获取左栏位图大小
CBitmap bitmapTrans;
BITMAP bitmap;
bitmapTrans.LoadBitmap(IDB_LEFT);
bitmapTrans.GetBitmap(&bitmap);
int bmpHight = bitmap.bmHeight;
int bmpWidth = bitmap.bmWidth;
ItemData* menuItemData[10];
CRect leftBmpTranRect(0, 0, bmpWidth, 0);
CMenuMy menuMy;
menuMy.CreatePopupMenu();
for(int i = 0;i < 10;++i)
{
menuItemData[i] = new ItemData;
//设置背景色
menuItemData[i]->m_backCol = RGB(255, 255, 255);
//设置选中颜色
menuItemData[i]->m_selectCol = RGB(9, 51, 255);
//设置菜单标题
menuItemData[i]->m_title = strTitle[i];
//将位图切分成很多块
leftBmpTranRect.bottom = (i+1)*37;
menuItemData[i]->rect = leftBmpTranRect;
menuItemData[i]->m_id = IDB_ICON1;
menuMy.AppendMenu(MF_OWNERDRAW|MF_BYCOMMAND|MF_STRING, IDB_ICON1, (LPCTSTR)menuItemData[i]);
}
menuMy.TrackPopupMenu(TPM_CENTERALIGN |TPM_RIGHTBUTTON, point.x, point.y, pWnd);
for(int i = 0;i < 10;++i)
{
delete menuItemData[i];
menuItemData[i] = NULL;
}
}
//可响应一组消息处理,同ON_COMMAND
void CDrawMyMenuView::OnCommandRange(UINT nID)
{
CString message;
message.Format(_T("nid == %d\n"), nID);
MessageBox(message);
}
2、自绘菜单
void CMenuMy::MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct)
{
// TODO: 添加您的代码以确定指定项的大小
lpMeasureItemStruct->itemWidth = 140;
lpMeasureItemStruct->itemHeight = 37;
}
void CMenuMy::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
//获取dc
CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC);
CDC mem;
BITMAP bitmap;
CBitmap leftBitMap;
leftBitMap.LoadBitmap(IDB_LEFT);
leftBitMap.GetBitmap(&bitmap);
pDC->SetBkMode(TRANSPARENT);
mem.CreateCompatibleDC(pDC);
CBitmap* pOldBitMap = (CBitmap*)mem.SelectObject(&leftBitMap);
ItemData* menuItemData = (ItemData*) lpDrawItemStruct->itemData;
//接受菜单项色彩信息
COLORREF clrbgGround = menuItemData->m_backCol;
COLORREF clrselect = menuItemData->m_selectCol;
CBrush backBrush(clrbgGround);
pDC->FillRect(&lpDrawItemStruct->rcItem, &backBrush);
CRect leftRect = menuItemData->rect;
//绘制左栏位图
pDC->BitBlt(leftRect.left, leftRect.top, leftRect.right, leftRect.bottom, &mem, 0, 0, SRCCOPY);
mem.SelectObject(pOldBitMap);
//绘制菜单图标,图标与左栏图标间隔为5
HBITMAP hbitmap = (HBITMAP)::LoadBitmap(AfxGetInstanceHandle(), MAKEINTRESOURCE(menuItemData->m_id));
CBitmap icon_map;
icon_map.Attach(hbitmap);
CBitmap* pOldBitMap1 = (CBitmap*)mem.SelectObject(&icon_map);
pDC->BitBlt(lpDrawItemStruct->rcItem.left+bitmap.bmWidth+5, lpDrawItemStruct->rcItem.top, lpDrawItemStruct->rcItem.right, lpDrawItemStruct->rcItem.bottom, &mem, 0, 0, SRCCOPY);
mem.SelectObject(pOldBitMap1);
//绘制菜单项文本
CString strMenuTitle;
strMenuTitle = menuItemData->m_title;
CRect rect(lpDrawItemStruct->rcItem);
CBitmap iconBitMap;
BITMAP bitmap1;
iconBitMap.LoadBitmap(IDB_ICON1);
iconBitMap.GetBitmap(&bitmap1);
rect.left = lpDrawItemStruct->rcItem.left+bitmap.bmWidth + bitmap1.bmWidth + 8;
pDC->DrawText(strMenuTitle, rect, DT_SINGLELINE|DT_LEFT|DT_VCENTER);
if ( lpDrawItemStruct->itemState & ODS_SELECTED )
{
//左栏图像在光标移动时不被刷新
CRect selectRect(lpDrawItemStruct->rcItem);
selectRect.left += bitmap.bmWidth;
CBrush brushSelect(clrselect);
pDC->FillRect(&selectRect, &brushSelect);
//重新绘制菜单项图标
CBitmap* pOldBitMap2 = (CBitmap*)mem.SelectObject(&icon_map);
//pDC->BitBlt(lpDrawItemStruct->rcItem.left+bitmap.bmWidth+5, lpDrawItemStruct->rcItem.top, lpDrawItemStruct->rcItem.right, lpDrawItemStruct->rcItem.bottom, &mem, 0, 0, SRCCOPY);
TransparentBlt2(pDC->m_hDC,lpDrawItemStruct->rcItem.left+bitmap.bmWidth+5, lpDrawItemStruct->rcItem.top, bitmap1.bmWidth, bitmap1.bmHeight,mem.m_hDC,0,0,bitmap1.bmWidth, bitmap1.bmHeight,clrbgGround);
mem.SelectObject(pOldBitMap2);
//重新绘制文本
rect.left = lpDrawItemStruct->rcItem.left+bitmap.bmWidth + bitmap1.bmWidth + 8;
pDC->SetTextColor(RGB(255, 255, 255));
pDC->DrawText(strMenuTitle, rect, DT_SINGLELINE|DT_LEFT|DT_VCENTER);
}
// TODO: 添加您的代码以绘制指定项
}
void CMenuMy::TransparentBlt2( HDC hdcDest, // 目标DC
int nXOriginDest, // 目标X偏移
int nYOriginDest, // 目标Y偏移
int nWidthDest, // 目标宽度
int nHeightDest, // 目标高度
HDC hdcSrc, // 源DC
int nXOriginSrc, // 源X起点
int nYOriginSrc, // 源Y起点
int nWidthSrc, // 源宽度
int nHeightSrc, // 源高度
UINT crTransparent // 透明色,COLORREF类型
)
{
HBITMAP hOldImageBMP, hImageBMP = CreateCompatibleBitmap(hdcDest, nWidthDest, nHeightDest); // 创建兼容位图
HBITMAP hOldMaskBMP, hMaskBMP = CreateBitmap(nWidthDest, nHeightDest, 1, 1, NULL); // 创建单色掩码位图
HDC hImageDC = CreateCompatibleDC(hdcDest);
HDC hMaskDC = CreateCompatibleDC(hdcDest);
hOldImageBMP = (HBITMAP)SelectObject(hImageDC, hImageBMP);
hOldMaskBMP = (HBITMAP)SelectObject(hMaskDC, hMaskBMP);
// 将源DC中的位图拷贝到临时DC中
if (nWidthDest == nWidthSrc && nHeightDest == nHeightSrc)
BitBlt(hImageDC, 0, 0, nWidthDest, nHeightDest, hdcSrc, nXOriginSrc, nYOriginSrc, SRCCOPY);
else
StretchBlt(hImageDC, 0, 0, nWidthDest, nHeightDest,
hdcSrc, nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc, SRCCOPY);
// 设置透明色
SetBkColor(hImageDC, crTransparent);
// 生成透明区域为白色,其它区域为黑色的掩码位图
BitBlt(hMaskDC, 0, 0, nWidthDest, nHeightDest, hImageDC, 0, 0, SRCCOPY);
// 生成透明区域为黑色,其它区域保持不变的位图
SetBkColor(hImageDC, RGB(0,0,0));
SetTextColor(hImageDC, RGB(255,255,255));
BitBlt(hImageDC, 0, 0, nWidthDest, nHeightDest, hMaskDC, 0, 0, SRCAND);
// 透明部分保持屏幕不变,其它部分变成黑色
SetBkColor(hdcDest,RGB(255,255,255));
SetTextColor(hdcDest,RGB(0,0,0));
BitBlt(hdcDest, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest, hMaskDC, 0, 0, SRCAND);
// "或"运算,生成最终效果
BitBlt(hdcDest, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest, hImageDC, 0, 0, SRCPAINT);
// 清理、恢复
SelectObject(hImageDC, hOldImageBMP);
DeleteDC(hImageDC);
SelectObject(hMaskDC, hOldMaskBMP);
DeleteDC(hMaskDC);
DeleteObject(hImageBMP);
DeleteObject(hMaskBMP);
}