const int MAX_MENUCOUNT = 60,ITEMHEIGHT = 26,ITEMWIDTH= 120; //菜单项数量



/**//*************************************
CMenuItemInfo结构用于记录菜单项信息
*************************************/
struct CMenuItemInfo


{
CString m_ItemText;//菜单项文本
int m_IconIndex;//菜单项索引
int m_ItemID;//菜单标记-2顶层菜单,-1弹出式菜单,0分隔条,其他普通菜单
};


class CIconMenu : public CMenu


{
public:
CMenuItemInfo m_ItemLists[MAX_MENUCOUNT]; //菜单项信息
int m_index; //临时索引
int m_iconindex;
CImageList m_imagelist;//存储菜单项图标

CIconMenu();
BOOL ChangeMenuItem(CMenu* m_menu,BOOL m_Toped = FALSE);
BOOL AttatchMenu(HMENU m_hmenu);
void DrawItemText(CDC* m_pdc,LPSTR str,CRect m_rect);
void DrawTopMenu(CDC* m_pdc,CRect m_rect,BOOL m_selected = FALSE); //绘制顶层菜单
void DrawSeparater(CDC* m_pdc,CRect m_rect);//绘制分隔条
void DrawComMenu(CDC* m_pdc,CRect m_rect,COLORREF m_fromcolor,COLORREF m_tocolor, BOOL m_selected = FALSE);
void DrawMenuIcon(CDC* m_pdc,CRect m_rect,int m_icon );
//override memu's viutual method
virtual ~CIconMenu();
virtual void MeasureItem( LPMEASUREITEMSTRUCT lpStruct );//设置菜单项大小
virtual void DrawItem( LPDRAWITEMSTRUCT lpStruct );//重绘菜单项

};


CIconMenu::CIconMenu()


{
m_index= 0;
m_iconindex= 0;
//创建图像列表
m_imagelist.Create(16,16,ILC_COLOR24|ILC_MASK,0,0);

//添加图标
m_imagelist.Add(AfxGetApp()->LoadIcon(IDI_ICON1));
m_imagelist.Add(AfxGetApp()->LoadIcon(IDI_ICON2));
m_imagelist.Add(AfxGetApp()->LoadIcon(IDI_ICON3));
m_imagelist.Add(AfxGetApp()->LoadIcon(IDI_ICON4));
m_imagelist.Add(AfxGetApp()->LoadIcon(IDI_ICON5));
m_imagelist.Add(AfxGetApp()->LoadIcon(IDI_ICON6));
m_imagelist.Add(AfxGetApp()->LoadIcon(IDI_ICON7));
m_imagelist.Add(AfxGetApp()->LoadIcon(IDI_ICON8));
m_imagelist.Add(AfxGetApp()->LoadIcon(IDI_ICON9));
m_imagelist.Add(AfxGetApp()->LoadIcon(IDI_ICON10));
}

CIconMenu::~CIconMenu()


{
m_imagelist.Detach();
}

BOOL CIconMenu::AttatchMenu(HMENU m_hmenu)


{
this->Attach(m_hmenu);
return TRUE;
}

BOOL CIconMenu::ChangeMenuItem(CMenu* m_menu,BOOL m_Toped)


{
if (m_menu != NULL)

{
int m_itemcount = m_menu->GetMenuItemCount();
for (int i=0;i<m_itemcount;i++)

{
m_menu->GetMenuString(i,m_ItemLists[m_index].m_ItemText,MF_BYPOSITION);
int m_itemID = m_menu->GetMenuItemID(i);
if (m_itemID==-1 && m_Toped)

{
m_itemID = -2;//顶层菜单
};
m_ItemLists[m_index].m_ItemID = m_itemID;
if (m_itemID>0)

{
m_ItemLists[m_index].m_IconIndex= m_iconindex;
m_iconindex+=1;
}
m_menu->ModifyMenu(i,MF_OWNERDRAW|MF_BYPOSITION |MF_STRING,m_ItemLists[m_index].m_ItemID,(LPSTR)&(m_ItemLists[m_index]));
m_index+=1;
CMenu* m_subMenu = m_menu->GetSubMenu(i);

if (m_subMenu)

{
ChangeMenuItem(m_subMenu);
}
}
}
return TRUE ;
}

void CIconMenu::MeasureItem( LPMEASUREITEMSTRUCT lpStruct )


{
if (lpStruct->CtlType==ODT_MENU)

{
lpStruct->itemHeight = ITEMHEIGHT;
lpStruct->itemWidth = ITEMWIDTH;
CMenuItemInfo* m_iteminfo;
m_iteminfo = (CMenuItemInfo*)lpStruct->itemData;
lpStruct->itemWidth = ((CMenuItemInfo*)lpStruct->itemData)->m_ItemText.GetLength()*10;
switch(m_iteminfo->m_ItemID)

{
case 0: //分隔条

{
lpStruct->itemHeight = 1;
break;
}
}
}
}

void CIconMenu::DrawItem( LPDRAWITEMSTRUCT lpStruct )


{
if (lpStruct->CtlType==ODT_MENU)

{
if(lpStruct->itemData == NULL) return;
unsigned int m_state = lpStruct->itemState;
CDC* m_dc = CDC::FromHandle(lpStruct->hDC);
//m_dc.Attach(lpStruct->hDC);

CString str = ((CMenuItemInfo*)(lpStruct->itemData))->m_ItemText;
LPSTR m_str = str.GetBuffer(str.GetLength());

int m_itemID = ((CMenuItemInfo*)(lpStruct->itemData))->m_ItemID;
int m_itemicon = ((CMenuItemInfo*)(lpStruct->itemData))->m_IconIndex;
CRect m_rect = lpStruct->rcItem;

m_dc->SetBkMode(TRANSPARENT);

switch(m_itemID)

{
case -2:

{

DrawTopMenu(m_dc,m_rect,(m_state&ODS_SELECTED)||(m_state&0x0040)); //0x0040 ==ODS_HOTLIGHT

DrawItemText(m_dc,m_str,m_rect);
break;
}
case -1:

{
DrawItemText(m_dc,m_str,m_rect);
break;
}
case 0:

{
DrawSeparater(m_dc,m_rect);
break;
}
default:

{
DrawComMenu(m_dc,m_rect,0xfaa0,0xf00ff,m_state&ODS_SELECTED);
DrawItemText(m_dc,m_str,m_rect);
DrawMenuIcon(m_dc,m_rect,m_itemicon);
break;
}
}
}
}

/**//*************************************************************
功能描述: 绘制菜单项文本

参数说明: m_pdc标识画布对象,str标识菜单文本,m_rect标识菜单区域
*************************************************************/
void CIconMenu::DrawItemText(CDC* m_pdc,LPSTR str,CRect m_rect)


{
m_rect.DeflateRect(20,0);
m_pdc->DrawText(str,m_rect,DT_SINGLELINE|DT_VCENTER|DT_LEFT);
}

void CIconMenu::DrawTopMenu(CDC* m_pdc,CRect m_rect,BOOL m_selected )


{
if (m_selected)

{
m_pdc->SelectStockObject(BLACK_PEN);
m_pdc->Rectangle(&m_rect);
m_rect.DeflateRect(1,1);
m_pdc->FillSolidRect(m_rect,RGB(150, 185, 255));
}
else

{
CRect rect;
AfxGetMainWnd()->GetClientRect(rect);
rect.top = m_rect.top;
rect.bottom = m_rect.bottom;
rect.left= 360;
rect.right +=4;
//CRect c_rect(m_rect);
m_pdc->FillSolidRect(&rect,RGB(200,187, 255));
m_pdc->FillSolidRect(&m_rect,RGB(200,187, 255));
//m_pdc->SelectStockObject(BLACK_PEN);
//m_pdc->FillSolidRect(m_rect,RGB(100, 185, 255));
}
}

void CIconMenu::DrawSeparater(CDC* m_pdc,CRect m_rect)


{
if (m_pdc != NULL)

{
m_pdc->Draw3dRect(m_rect,RGB(255,0,0),RGB(0,0,255));
}
}

void CIconMenu::DrawComMenu(CDC* m_pdc,CRect m_rect,COLORREF m_fromcolor,COLORREF m_tocolor, BOOL m_selected )


{
if (m_selected)

{
m_pdc->Rectangle(m_rect);
m_rect.DeflateRect(1,1);
int r1,g1,b1;
//读取渐变起点的颜色值
r1 = GetRValue(m_fromcolor);
g1 = GetGValue(m_fromcolor);
b1 = GetBValue(m_fromcolor);
int r2,g2,b2;


//读取渐变终点的颜色值
r2 = GetRValue(m_tocolor);
g2 = GetGValue(m_tocolor);
b2 = GetBValue(m_tocolor);

float r3,g3,b3;//菜单区域水平方向每个点RGB值应该变化的度(范围)
r3 = ((float)(r2-r1)) / (float)(m_rect.Height());
g3 = (float)(g2-g1)/(float)(m_rect.Height());
b3 = (float)(b2-b1)/(float)(m_rect.Height());
COLORREF r,g,b;//菜单区域水平方向每个点的颜色值
CPen* m_oldpen ;

for (int i = m_rect.top;i<m_rect.bottom;i++)

{
r = r1+(int)r3*(i-m_rect.top);
g = g1+(int)g3*(i-m_rect.top);
b = b1+ (int)b3*(i-m_rect.top);
CPen m_pen (PS_SOLID,1,RGB(r,g,b));
m_oldpen = m_pdc->SelectObject(&m_pen);
m_pdc->MoveTo(m_rect.left,i);
m_pdc->LineTo(m_rect.right,i);
}

m_pdc->SelectObject(m_oldpen);
}
else

{
m_pdc->FillSolidRect(m_rect,RGB(0x000000F9, 0x000000F8, 0x000000F7));
}
}

void CIconMenu::DrawMenuIcon(CDC* m_pdc,CRect m_rect,int m_icon )


{
m_imagelist.Draw(m_pdc,m_icon,CPoint(m_rect.left+2,m_rect.top+4),ILD_TRANSPARENT);
}


【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· C#/.NET/.NET Core技术前沿周刊 | 第 29 期(2025年3.1-3.9)
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异