MFC_CMenu_CIconMenu_带图标的菜单

效果图:

1. 如何修改单文档的标题(注:一个窗口的图标是由两部分组成的:文档标题+应用标题,此处修改的是文档标题)

在*doc.h中添加:

virtual void SetTitle(LPCTSTR lpszTitle);

之后实现:
void ***Doc::SetTitle(LPCTSTR lpszTitle)
{
 lpszTitle = "带图标的程序菜单"; 
 CDocument::SetTitle(lpszTitle);
}

2. 设置应用的标题

在CMainFrame::OnCreate中添加:

this->SetTitle("明日科技");

3. 如何实现

3.1 添加类CIconMenu,所需文件IconMenu1.h、IconMenu1.cpp

3.2 在CMainFrame添加消息

 ON_WM_DRAWITEM()
 ON_WM_MEASUREITEM()

 

afx_msg void OnDrawItem(int nIDCtl, LPDRAWITEMSTRUCT lpDrawItemStruct);
 afx_msg void OnMeasureItem(int nIDCtl, LPMEASUREITEMSTRUCT lpMeasureItemStruct);


void CMainFrame::OnDrawItem(int nIDCtl, LPDRAWITEMSTRUCT lpDrawItemStruct)
{
 m_menu.DrawItem(lpDrawItemStruct);
 // CFrameWnd::OnDrawItem(nIDCtl, lpDrawItemStruct);
}

void CMainFrame::OnMeasureItem(int nIDCtl, LPMEASUREITEMSTRUCT lpMeasureItemStruct)
{
 m_menu.MeasureItem(lpMeasureItemStruct); 
 // CFrameWnd::OnMeasureItem(nIDCtl, lpMeasureItemStruct);
}

3.3 在CMainFrame::OnCreate添加:

  m_menu.AttatchMenu(this->GetMenu()->GetSafeHmenu());
  m_menu.ChangeMenuItem(&m_menu,TRUE);

 

注:CIconMenu m_menu;

附:IconMenu1.h

// IconMenu1.h: interface for the CIconMenu class.
//
//

#if !defined(AFX_ICONMENU1_H__FAA8B855_EE72_4332_96D7_73F8FA07E521__INCLUDED_)
#define AFX_ICONMENU1_H__FAA8B855_EE72_4332_96D7_73F8FA07E521__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

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 virtual method
 virtual ~CIconMenu();
 virtual void MeasureItem( LPMEASUREITEMSTRUCT lpStruct );//设置菜单项大小
 virtual void DrawItem( LPDRAWITEMSTRUCT lpStruct );//重绘菜单项

};

#endif // !defined(AFX_ICONMENU1_H__FAA8B855_EE72_4332_96D7_73F8FA07E521__INCLUDED_)

附:IconMenu1.cpp

// IconMenu1.cpp: implementation of the CIconMenu class.
//
//

#include "stdafx.h"
#include "IconMenu.h"
#include "IconMenu1.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//
// Construction/Destruction
//

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);
}

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值