简单实现菜单自绘

简单对下面3 个消息处理 就可实现菜单自绘, 其他控件类似;

 

 

 //WM_DRAWITEM:绘制菜单的样式
//WM_MEASUREITEM:指定要绘制菜单的大小
//WM_INITMENU:把框架菜单全部改成带MF_OWNERDRAW标志

void CTestRgnDlg::OnInitMenu(CMenu* pMenu)
{
 //CDialog::OnInitMenu(pMenu);

 CMenu *pSubMenu;
 UINT nCount,nSubCount,nID;
 CString strText;
 nCount=pMenu->GetMenuItemCount();
 
 for(UINT i=0;i<nCount;i++)
 {
  pSubMenu =pMenu->GetSubMenu(i);
  nSubCount=pSubMenu->GetMenuItemCount();
  for(UINT j=0;j<nSubCount;j++)
  {
   nID=pSubMenu->GetMenuItemID(j);
   // 将框架菜单所有菜单都添加MF_OWNERDRAW标志
   pSubMenu->ModifyMenu(j,MF_BYPOSITION|MF_OWNERDRAW,nID);
   pSubMenu->GetMenuString(j,strText,MF_BYPOSITION);
  }
 }

 // TODO: 在此处添加消息处理程序代码
}

 

 

void CTestRgnDlg::OnDrawItem(int nIDCtl, LPDRAWITEMSTRUCT lpDrawItemStruct)
{
 LPDRAWITEMSTRUCT& lpD=lpDrawItemStruct; //起个别名,好用一点

 //判断是不是菜单自绘,因为按钮也可以自绘
 if(nIDCtl==0)
 {
  CDC* pDC=CDC::FromHandle(lpD->hDC); //得到菜单的设备指针,用来绘制菜单
  pDC->SetBkMode(TRANSPARENT);

  CMenu menu;
  menu.Attach((HMENU)lpD->hwndItem); //得到框架菜单对象
  CRect AllRgn(lpD->rcItem);   //得到当前绘制的菜单选项项大小
  CRect FrontRgn(AllRgn.left,AllRgn.top,20,AllRgn.bottom);
  CBrush brushAll(RGB( 250,250,250 )); //初始化画刷
  CBrush brushFront(RGB( 230,230,230 ));
  CBrush brushSel(RGB(148,170,214 ));
  CString strText;
  menu.GetMenuString(lpD->itemID,strText,MF_BYCOMMAND);//得到当前绘制的菜单选项文本                
  if(lpD->itemID!=ID_SEPARATOR) //菜单和分隔栏分别绘制
  {
   if(lpD->itemAction & ODA_SELECT) //菜单选中时的样式
   {
    pDC->FillRect(AllRgn,&brushSel);//绘制
    if(lpD->itemState &ODS_GRAYED)
     //设定文本颜色(在最后才绘制出来)
     pDC->SetTextColor(RGB(194,194,194));
    else if(lpD->itemState & ODS_SELECTED)
     pDC->SetTextColor(RGB(250,250,250));
   }

   //菜单非选中时的样式
   if(!((lpD->itemAction & ODA_SELECT) && (lpD->itemState & ODS_SELECTED)))
   {
    pDC->FillRect(AllRgn,&brushAll);//绘制
    pDC->FillRect(FrontRgn,&brushFront);
    if(lpD->itemState & ODS_GRAYED)
     pDC->SetTextColor(RGB(194,194,194 ));
    else
     pDC->SetTextColor(RGB(66,110,180 ));
   }
  }
  else
   pDC->FillRect(AllRgn,&brushFront);//绘制分隔栏

  pDC->TextOut(AllRgn.left+30,AllRgn.top+5,strText);//打印出字体

  menu.Detach();//分隔菜单句柄和对象(必要!)
 }

 //CDialog::OnDrawItem(nIDCtl, lpDrawItemStruct);
}

 

 

void CTestRgnDlg::OnMeasureItem(int nIDCtl, LPMEASUREITEMSTRUCT lpMeasureItemStruct)
{
 // TODO: 在此添加消息处理程序代码和/或调用默认值
 LPMEASUREITEMSTRUCT& lpM=lpMeasureItemStruct; //起个别名,好用一点

 if(lpM->CtlType==ODT_MENU)
 { //判断是不是菜单要自绘
  if(lpM->itemID!=ID_SEPARATOR)//分别设定普通菜单和分隔栏的大小  
  {
   lpM->itemHeight=20;//普通菜单大小 
   lpM->itemWidth=150;
  }
  else
  {
   lpM->itemHeight=1;//分隔栏大小
   lpM->itemWidth=150;
  }
 }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Blue_Dream_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值