// MenuEx.cpp: implementation of the CMenuEx class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "MenuEx.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CMenuEx::CMenuEx():m_szImage(16,15)
{
m_colMenu =::GetSysColor(COLOR_MENU);
m_colText =::GetSysColor(COLOR_MENUTEXT);
m_colTextSelected =::GetSysColor(COLOR_HIGHLIGHTTEXT);
m_bInitial =FALSE;
m_bHasImageLeft =FALSE;
m_nSeparator = 10; //sparator的默认高度
}
CMenuEx::~CMenuEx()
{
m_ImageList.DeleteImageList();
while(!m_ListMenu.IsEmpty())
delete m_ListMenu.RemoveHead();
if(m_bHasImageLeft)
m_bmpImageLeft.DeleteObject();
}
/////////////////////////////////////////////////
//当菜单项为不可用时绘制灰色的文本
void CMenuEx::GrayString(CDC *pDC, const CString &str, const CRect rect)
{
CRect rt(rect);
//int nMode =pDC->SetBkMode(TRANSPARENT);
rt.left +=1;
rt.top +=1;
pDC->SetTextColor(RGB(255,255,255));
pDC->DrawText(str,&rt,DT_EXPANDTABS|DT_VCENTER|DT_SINGLELINE);
rt.left -=1;
rt.top -=1;
pDC->SetTextColor(RGB(127,127,127));
pDC->DrawText(str,&rt,DT_EXPANDTABS|DT_VCENTER|DT_SINGLELINE);
//pDC->SetBkMode(nMode);
}
/////////////////////////////////////////////////
//绘制菜单项位图
void CMenuEx::DrawMenuItemImage(CDC *pDC, CRect &rect, BOOL bSelected, BOOL bChecked,
BOOL bGrayed, BOOL bHasImage,LPMENUITEM lpItem)
{
CRect rt(rect.left ,rect.top ,rect.left + m_szImage.cx + 4,
rect.top + m_szImage.cy + 4);
if(bChecked)
{
if(bGrayed)
{
//菜单不可用
GrayString(pDC,"√",rt);
}
else
{
if(bSelected)
{
//菜单选中
//当该项被选中仅多绘制一个立体矩形
pDC->Draw3dRect(&rt,RGB(255,255,255),RGB(127,127,127));
}
rt.InflateRect(-2,-2);
//画出"√"
pDC->SetBkMode(TRANSPARENT);
pDC->SetTextColor(m_colText);
pDC->DrawText("√",&rt,DT_EXPANDTABS|DT_VCENTER|DT_SINGLELINE);
}
rect.left +=m_szImage.cx + 4 +2 ;
return ;
}
if(bHasImage)
{
CPoint pt(rt.left+2 , rt.top+2 );
UINT uStyle =ILD_TRANSPARENT; //CImageList::Draw()绘制位图的风格
if(bGrayed)
{
uStyle |=ILD_BLEND50; //菜单不可用所以位图较暗
}
else
{
if(bSelected)
{
//当该项被选中仅多绘制一个立体矩形
pDC->Draw3dRect(&rt,RGB(255,255,255),RGB(127,127,127));
}
}
m_ImageList.Draw(pDC,lpItem->uIndex,pt,uStyle); //在菜单项中绘制位图
//调整可绘制矩形的大小
//4:位图外接矩形比位图大4
//2:菜单文本与位图外接矩形的间隔为2
rect.left +=m_szImage.cx + 4 + 2;
}
}
/////////////////////////////////////////////////
//绘制菜单项文本
//参数:rect:立体矩形的RECT
// rtText:菜单文本的RECT
void CMenuEx::TextMenu(CDC *pDC, CRect &rect,CRect rtText,BOOL bSelected, BOOL bGrayed, LPMENUITEM lpItem)
{
//选中状态的菜单项要先画出立体矩形
if(bSelected)
pDC->Draw3dRect(&rect,RGB(127,127,127),RGB(255,255,255));
if(bGrayed)
{
GrayString(pDC,lpItem->strText,rtText);
}
else
{
pDC->DrawText(lpItem->strText,rtText,DT_LEFT|DT_EXPANDTABS|DT_VCENTER);
}
}
void CMenuEx::DrawImageLeft(CDC *pDC, CRect &rect,LPMENUITEM lpItem)
{
if(!m_bHasImageLeft || lpItem->uPositionImageLeft ==-1)
return ;
CDC memDC;
memDC.CreateCompatibleDC(pDC);
CBitmap *oldBmp =(CBitmap *) memDC.SelectObject(&m_bmpImageLeft);
int cy; //设定该菜单项应从哪画起
if(m_szImageLeft.cy >= lpItem->uPositionImageLeft + rect.Height())
{
cy =(int) m_szImageLeft.cy - lpItem->uPositionImageLeft - rect.Height();
ASSERT(cy>=0);
}
else
cy =0;
pDC->BitBlt(rect.left ,rect.top ,m_szImageLeft.cx ,rect.Height(),&memDC,0,cy,SRCCOPY);
memDC.SelectObject(oldBmp);
memDC.DeleteDC();
rect.left +=m_szImageLeft.cx+1;
}
void CMenuEx::DrawItem(LPDRAWITEMSTRUCT lpDIS)
{
CDC dc;
LPMENUITEM lpItem;
CRect rect(lpDIS->rcItem);
dc.Attach(lpDIS->hDC);
lpItem =(LPMENUITEM)lpDIS->itemData;
if(lpDIS->itemState & ODS_SELECTED)
dc.SetTextColor(m_colTextSelected);
else
dc.SetTextColor(m_colText);
//设定背景色
CBrush brush(m_colMenu);
dc.FillRect(&rect, &brush);
//设定显示模式
dc.SetBkMode(TRANSPARENT);
//绘制侧边位图
DrawImageLeft(&dc,rect,lpItem);
if(lpItem->uID==0)//分隔条
{
rect.top =rect.Height()/2+rect.top ;
rect.bottom =rect.top +2;
rect.left +=2;
rect.right -=2;
dc.Draw3dRect(rect,RGB(64,0,128),RGB(255,255,255));
}
else
{
BOOL bSelected =lpDIS->itemState & ODS_SELECTED;
BOOL bChecked =lpDIS->itemState & ODS_CHECKED;
BOOL bGrayed =lpDIS->itemState & ODS_GRAYED;
BOOL bHasImage =(lpItem->uIndex!=-1);
//设定菜单文本的区域
CRect rtText(rect.left+m_szImage.cx+4+2, rect.top,rect.right ,rect.bottom );
rtText.InflateRect(-2,-2);
//绘制菜单位图
DrawMenuItemImage(&dc,rect,bSelected,bChecked,bGrayed,bHasImage,lpItem);
//绘制菜单文本
TextMenu(&dc,rect,rtText,bSelected,bGrayed,lpItem);
#ifdef MENUCHAR
//加入当前菜单链表
m_currentListMenu.AddTail(lpItem);
#endif
}
dc.Detach();
}
//////////////////////////////////////////////////////////
//改变菜单风格
//注意第二个参数:FALSE:表示pMenu指向的不是第一级菜单
void CMenuEx::ChangeStyle(CMenu *pMenu,CToolBar *pToolBar,BOOL bIsMainMenu)
{
ASSERT(pMenu);
TRACE("ChangeStyle\n");//AfxMessageBox("");
LPMENUITEM lpItem;
CMenu *pSubMenu;
int m,nPosition=0; //该变量用来绘制侧边位图的位置
int inx;
UINT idx,x;
for(int i=(int)pMenu->GetMenuItemCount()-1 ;i>=0; i--)
{
lpItem =new MENUITEM;
lpItem->uID =pMenu->GetMenuItemID(i);
if(!bIsMainMenu) //不是第一级菜单
lpItem->uPositionImageLeft =-1;//二级以下菜单不支持侧边位图
else
lpItem->uPositionImageLeft =nPosition;
if(lpItem->uID >0)
{
if(bIsMainMenu)
nPosition +=m_szImage.cy+4;
//保存菜单文本
pMenu->GetMenuString(i,lpItem->strText,MF_BYPOSITION);
#ifdef MENUCHAR
//保存菜单文本中&后的字符
//如果没有则lpItem->uChr为0
int ret=lpItem->strText.Find('&');
lpItem->uChr =0;
if(ret>=0)
lpItem->uChr =lpItem->strText[ret+1];
//字符统一成大小
lpItem->uChr &=~0x20;
#endif
//由工具栏位图中寻找菜单项的位图
//如果没有则uIndex为-1
lpItem->uIndex =-1;
if(pToolBar)
{
for(m=0; m<(pToolBar->GetToolBarCtrl().GetButtonCount()) ;m++)
{
pToolBar->GetButtonInfo(m,idx,x,inx);
if(idx==lpItem->uID)
{
lpItem->uIndex=inx;
break;
}
}
}
//如果该项下还有子菜单,则递归调用该函数来修改其子菜单的风格
pSubMenu =pMenu->GetSubMenu(i);
if(pSubMenu)
ChangeStyle(pSubMenu,pToolBar);
}
else
{
if(bIsMainMenu)
nPosition +=m_nSeparator;
}
//修改菜单风格为自绘
pMenu->ModifyMenu(i,MF_BYPOSITION|MF_OWNERDRAW,lpItem->uID,(LPCTSTR)lpItem);
m_ListMenu.AddTail(lpItem);
}
}
//////////////////////////////////////////////////////////
//由工具栏的位图来产生菜单所用的位图列表m_ImageList
int CMenuEx::GetImageFromToolBar(UINT uToolBar, CToolBar *pToolBar,COLORREF crMask/*工具栏位图的掩码*/)
{
if(!pToolBar)
return 0;
CBitmap bmp;
int nWidth,nHeight;
BITMAP bmpInfo;
bmp.LoadBitmap(uToolBar);
bmp.GetBitmap(&bmpInfo);
//得到位图的高度
nHeight =bmpInfo.bmHeight;
int nCount=0;
int ret =pToolBar->GetToolBarCtrl().GetButtonCount();
//得到工具栏中位图的个数nCount
for(int i=0;i<ret;i++)
if(pToolBar->GetItemID(i)!=ID_SEPARATOR)
nCount ++;
//计算出位图的宽度
nWidth =bmpInfo.bmWidth/nCount;
bmp.DeleteObject();
TRACE("Menu Bitmap--width:%d\theight:%d\n",nWidth,nHeight);
//创建位图列表
m_ImageList.Create(uToolBar,nWidth,nHeight,crMask);
m_szImage.cx =nWidth;
m_szImage.cy
没有合适的资源?快使用搜索试试~ 我知道了~
自制菜单vczx_CMenuEx
共38个文件
h:7个
cpp:6个
obj:5个
4星 · 超过85%的资源 需积分: 32 19 下载量 21 浏览量
2008-09-20
11:36:45
上传
评论
收藏 3.77MB RAR 举报
温馨提示
绘制各种漂亮的菜单,对于追求界面完美者,是一个很好的参考
资源推荐
资源详情
资源评论
收起资源包目录
vczx_CMenuEx.rar (38个子文件)
自制菜单vczx_CMenuEx
CMenuEx
MenuEx.cpp 11KB
MenuEx.h 3KB
Hello
Hello.rc 10KB
Hello.cpp 4KB
StdAfx.cpp 207B
resource.h 1KB
Hello.ncb 43KB
Hello.clw 2KB
Hello.suo 9KB
MenuEx.cpp 11KB
MainFrm.h 2KB
Hello.dsp 4KB
ChildView.cpp 2KB
Hello.vcproj 7KB
ChildView.h 1KB
Debug
Hello.exe 120KB
Hello.obj 27KB
Hello.res 24KB
vc70.idb 331KB
vc70.pdb 1012KB
BuildLog.htm 4KB
Hello.pdb 2.75MB
Hello.pch 10.19MB
MainFrm.obj 32KB
MenuEx.obj 67KB
StdAfx.obj 275KB
ChildView.obj 20KB
Hello.h 1KB
StdAfx.h 999B
MainFrm.cpp 4KB
MenuEx.h 3KB
res
Hello.rc2 397B
Hello.ico 1KB
1.bmp 19KB
Toolbar.bmp 718B
Hello.sln 899B
Hello.dsw 535B
demo
CustMenu.exe 56KB
共 38 条
- 1
资源评论
- wyxsyrfd2013-07-11还行,有一定的借鉴作用
- MyVC602014-03-02CMenuEx可以啊,但是就是不知道怎么在对话框里面用
jianjook
- 粉丝: 0
- 资源: 7
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功