menuex.cpp
来自「深入浅出Visual C++入门进阶与应用实例 随书光盘 作者 何志丹」· C++ 代码 · 共 254 行
CPP
254 行
// MenuEx.cpp: implementation of the CMenuEx class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "Ex030204.h"
#include "MenuEx.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CMenuEx::CMenuEx()
{
}
CMenuEx::~CMenuEx()
{
}
void CMenuEx::InitMenu(CMenu* pMenu )
{
CMenu *pSubMenu;
UINT nCount,nSubCount,nID;
nCount=pMenu->GetMenuItemCount();//子菜单的列数
for(UINT i=0;i<nCount;i++)
{
pSubMenu =pMenu->GetSubMenu(i);
if(NULL == pSubMenu)
{//出错忽略此列
ASSERT(false);
continue ;
}
nSubCount=pSubMenu->GetMenuItemCount();//此列菜单菜单项的个数
for(UINT j=0;j<nSubCount;j++)
{
nID=pSubMenu->GetMenuItemID(j);
//将框架菜单所有菜单都添加MF_OWNERDRAW标志
pSubMenu->ModifyMenu(j,MF_BYPOSITION|MF_OWNERDRAW,nID);
}
}
}
void CMenuEx::MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct )
{
if(ODT_MENU != lpMeasureItemStruct->CtlType )
return ;
if(ID_SEPARATOR != lpMeasureItemStruct->itemID) //设定非分隔线的大小
{
lpMeasureItemStruct->itemHeight = 18;
lpMeasureItemStruct->itemWidth = 138;
}
else//设定分隔线的大小
{
lpMeasureItemStruct->itemHeight = 1;
lpMeasureItemStruct->itemWidth = 138;
}
}
void CMenuEx::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct )
{
if(ODT_MENU != lpDrawItemStruct->CtlType)
return ;
LPDRAWITEMSTRUCT& lpDraw=lpDrawItemStruct; //起个别名,好用一点
LPMENUITEM lpItem;
lpItem =(LPMENUITEM)lpDrawItemStruct->itemData;
//得到菜单的设备指针,用来绘制菜单
CDC* pDC=CDC::FromHandle(lpDraw->hDC);
CBrush brushBK(RGB(255,255,255)) ;
pDC->FillRect(&lpDraw->rcItem,&brushBK);//填充背景,"白纸"
pDC->SetBkMode(TRANSPARENT);//透明的,有文字和没文字的地方背景一样
pDC->SetTextColor(RGB(0,0,0));//文字的颜色,"黑字"
pDC->TextOut(lpDraw->rcItem.left+30,lpDraw->rcItem.top+5,lpItem->strText); //输出菜单标题
}
BOOL CMenuEx::LoadMenu(UINT uMenu)
{
//重新读入菜单,创建为popup菜单,才能自画(由框架调用MesureItem() 和 DrawItem()
HMENU hMenu = ::CreateMenu();
this->Attach(hMenu);
CMenu Menu; //临时菜单
UINT uID;
Menu.LoadMenu(uMenu);
for(int i = 0; i < (int)Menu.GetMenuItemCount(); i++)
{
uID = Menu.GetMenuItemID(i);
if(uID == 0) //分隔符
{
::AppendMenu(hMenu,MF_SEPARATOR,0,NULL);
}
else if((int)uID == -1) //弹出菜单(即子菜单)
{
CMenu *pSubMenu = Menu.GetSubMenu(i);
//创建子菜单
HMENU hSubMenu = ::CreatePopupMenu();
CString strPopup;
Menu.GetMenuString(i,strPopup,MF_BYPOSITION);
::InsertMenu(hMenu,i,MF_BYPOSITION | MF_POPUP | MF_STRING,(UINT)hSubMenu,strPopup);
//对子菜单递归调用ChangeMenuStyle(),把子菜单改为MF_OWNERDRAW风格
ChangeMenuStyle(pSubMenu,hSubMenu);
}
else //正常的菜单项
{
CString strText;
Menu.GetMenuString(uID,strText,MF_BYCOMMAND);
AppendMenu(MF_STRING,uID,strText);
}
}
Menu.DestroyMenu(); //销毁临时菜单
return TRUE;
}
void CMenuEx::ChangeMenuStyle(CMenu *pMenu,HMENU hNewMenu)
{
CMenuEx *pNewMenu;
pNewMenu = new CMenuEx;
pNewMenu->Attach(hNewMenu);
m_SubMenuArr.Add(pNewMenu);
UINT uID;
int nItemCount = pMenu->GetMenuItemCount();
for(int i = 0; i < nItemCount; i++)
{
uID = pMenu->GetMenuItemID(i);
if(uID == 0) //分隔符
{
::AppendMenu(hNewMenu,MF_SEPARATOR,0,NULL);
CString strText;
MENUITEM *pMenuItem = new MENUITEM;
pMenuItem->uID = 0;
m_MenuItemArr.Add(pMenuItem);
::ModifyMenu(hNewMenu,i,MF_BYPOSITION | MF_OWNERDRAW,-1,(LPCTSTR)pMenuItem);
}
else if(uID == -1) //弹出菜单(即子菜单)
{
CMenu *pSubMenu = pMenu->GetSubMenu(i);
HMENU hPopMenu = ::CreatePopupMenu();
CString strPopup;
pMenu->GetMenuString(i,strPopup,MF_BYPOSITION);
::InsertMenu(hNewMenu,i,MF_BYPOSITION | MF_POPUP,(UINT)hPopMenu,strPopup);
MENUITEM *pMenuItem = new MENUITEM;
pMenuItem->uID = -1;
pMenuItem->strText = strPopup;
m_MenuItemArr.Add(pMenuItem);
::ModifyMenu(hNewMenu,i,MF_BYPOSITION | MF_OWNERDRAW,-1,(LPCTSTR)pMenuItem);
ChangeMenuStyle(pSubMenu,hPopMenu);
}
else //正常的菜单项
{
CString strText;
pMenu->GetMenuString(uID,strText,MF_BYCOMMAND);
MENUITEM *pMenuItem = new MENUITEM;
pMenuItem->uID = pMenu->GetMenuItemID(i);
pMenu->GetMenuString(pMenuItem->uID,pMenuItem->strText,MF_BYCOMMAND);
m_MenuItemArr.Add(pMenuItem);
UINT uState = pMenu->GetMenuState(i,MF_BYPOSITION);
::AppendMenu(hNewMenu,MF_OWNERDRAW | MF_BYCOMMAND | uState,uID,(LPCTSTR)pMenuItem);
}
}
}
BOOL CMenuEx::AppendMenuEx(UINT nFlags, UINT nIDNewItem, LPCTSTR lpszNewItem)
{
MENUITEM *pMenuItem = new MENUITEM;
pMenuItem->strText = lpszNewItem;
pMenuItem->uID = nIDNewItem;
nFlags &= ~MF_STRING;
nFlags |= MF_OWNERDRAW;
m_MenuItemArr.Add(pMenuItem);
return CMenu::AppendMenu(nFlags,nIDNewItem,(LPCTSTR)pMenuItem);
}
BOOL CMenuEx::ModifyMenuEx(UINT nPosition, UINT nFlags, UINT nIDNewItem, LPCTSTR lpszNewItem)
{
UINT uItemID = 0;
if(nFlags & MF_BYPOSITION)
{
uItemID = GetMenuItemID((int)nPosition);
}
else
{
uItemID = nPosition;
}
//普通菜单项和弹出式菜单
MENUITEM *pMenuItem = NULL;
for(int i = 0; i < m_MenuItemArr.GetSize(); i++)
{
pMenuItem = m_MenuItemArr.GetAt(i);
if(pMenuItem->uID == uItemID)
{
pMenuItem->strText = lpszNewItem;
if((int)nIDNewItem != 0)
pMenuItem->uID = nIDNewItem;
break;
}
}
//没找到对应的菜单项
if(i >= m_MenuItemArr.GetSize())
{
MENUITEM *pMenuItem = new MENUITEM;
pMenuItem->strText = lpszNewItem;
pMenuItem->uID = nIDNewItem;
m_MenuItemArr.Add(pMenuItem);
}
nFlags &= ~MF_STRING;
nFlags |= MF_OWNERDRAW;
return CMenu::ModifyMenu(nPosition,nFlags,nIDNewItem,(LPCTSTR)pMenuItem);
}
BOOL CMenuEx::RemoveMenuEx(UINT nPosition, UINT nFlags)
{
UINT uItemID = 0;
if(nFlags & MF_BYPOSITION)
{
uItemID = GetMenuItemID((int)nPosition);
}
else
{
uItemID = nPosition;
}
if((int) uItemID >= 0) //普通菜单项或分割条
{
for(int i = 0; i < m_MenuItemArr.GetSize(); i++)
{
MENUITEM *pMenuItem = m_MenuItemArr.GetAt(i);
if(pMenuItem->uID == uItemID)
{
m_MenuItemArr.RemoveAt(i);
break;
}
}
}
else //子菜单
{
}
return CMenu::RemoveMenu(nPosition,nFlags);
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?