⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 coolmenu.cpp

📁 (VC)又一个酒店管理系统, (VC)又一个酒店管理系统,(VC)又一个酒店管理系统
💻 CPP
📖 第 1 页 / 共 4 页
字号:
	uMenuID:	菜单资源ID
	uToolBarID: 工具栏资源ID,用来提取图标资源
==========================================================================*/
BOOL CCoolMenu::LoadMenu(UINT uMenuID, UINT uToolBarID)
{
	ClearData();
	BOOL bRet = CMenu::LoadMenu(uMenuID);
	if (bRet)
	{
		//依次设置菜单为自绘风格并设置相关信息-------------
		ModifyStyle(GetSafeHmenu(), MDS_TOP_MENU);
		//从工具栏中添加图标资源---------------------------
		SetImageList(uToolBarID);
	}
	return bRet;
}

/*========================================================================
	功能:		将Windows菜单句柄连接到CCoolMenu对象.
	------------------------------------------------
	hMenu:		要连接的菜单名柄
	uToolBarID: 对应工具栏资源ID,用来提取图标资源
==========================================================================*/
BOOL CCoolMenu::Attach(HMENU hMenu, UINT uToolBarID)
{
	ClearData();
	BOOL bRet = CMenu::Attach(hMenu);
	if (bRet)
	{
		//依次设置菜单为自绘风格并设置相关信息-------------
		ModifyStyle(GetSafeHmenu(), MDS_TOP_MENU);
		//从工具栏中添加图标资源---------------------------
		SetImageList(uToolBarID);
	}
	return bRet;
}

/*========================================================================
	功能:		断开与菜单句柄的连接并清除相关数据
==========================================================================*/
HMENU CCoolMenu::Detach()
{
	ClearData();
	return CMenu::Detach();
}

/*========================================================================
	功能:		添加菜单项
	-------------------------------------------
	uID:		菜单ID
	strText:	菜单文本
	nlevel:		菜单级别,请参考相关函数
==========================================================================*/
void CCoolMenu::AppendMenu(UINT uFlags, UINT uNewMenuItemID, CString strNewMenuItem, int nlevel)
{
	LPCOOLMENU lpMenu = new COOLMENU;
	lpMenu->nMenuID = uNewMenuItemID;
	lpMenu->strText = strNewMenuItem;
	lpMenu->nMenuLevel = nlevel;
	CMenu::AppendMenu(MF_BYPOSITION | MF_OWNERDRAW | uFlags, lpMenu->nMenuID, LPCTSTR(lpMenu));
	m_obMenuList.AddTail((CObject *)lpMenu);
}

/*========================================================================
	功能:	子类化指定窗口
==========================================================================*/
void CCoolMenu::SubClass(HWND hwnd)
{
	m_MenuHook.HookWindow(hwnd);
}

/*########################################################################
					-----------------------
							绘制菜单	
					-----------------------
  ########################################################################*/

/*========================================================================
	功能:	计算菜单大小
	--------------------------------------------
	lpMIS:	LPMEASUREITEMSTRUCT结构体
==========================================================================*/
void CCoolMenu::MeasureItem(LPMEASUREITEMSTRUCT lpMIS)
{
	LPCOOLMENU lpMenu = (LPCOOLMENU)(lpMIS->itemData);
	
	//分隔条---------------------------------
	if(lpMenu->nMenuID == 0)
	{
		lpMIS->itemHeight = 5;
		lpMIS->itemWidth = 50;
		return;
	}

	//非分隔条-------------------------------
	lpMIS->itemWidth = 50; // default width
	lpMIS->itemHeight = 19;

	CString strText = lpMenu->strText + lpMenu->strKeyName;
	int nLen = strText.GetLength();
	if (nLen > 0)
	{
	//计算绘制菜单文本所需宽度-------------------
		
		CFont fontMenu;
		LOGFONT lf;
		ZeroMemory(&lf, sizeof(LOGFONT));
		NONCLIENTMETRICS nm;
		nm.cbSize = sizeof(NONCLIENTMETRICS);
		VERIFY(SystemParametersInfo(SPI_GETNONCLIENTMETRICS, nm.cbSize, &nm, 0)); 
		lf = nm.lfMenuFont;
		fontMenu.CreateFontIndirect(&lf);
		
		CDC *pDC = AfxGetMainWnd()->GetDC();
		CFont *old = pDC->SelectObject(&fontMenu);
		CSize sz = pDC->GetTextExtent(lpMenu->strText);  
		pDC->SelectObject(&old);
		AfxGetMainWnd()->ReleaseDC(pDC);
		fontMenu.DeleteObject();

		//调整有快捷键提示的菜单的宽度,使宽度适中-------------
		if (lpMenu->strKeyName != "") sz.cx += (62 - (strText.GetLength() % 8) * (sz.cx/strText.GetLength()));
		
		if(lpMenu->nMenuID == -2)
		{
			//顶级菜单宽度---------------------------
			lpMIS->itemWidth = sz.cx - 6;
		}
		else if (lpMenu->nMenuLevel <= MDS_TOP_SUBMENU)
		{
			//主菜单项宽度---------------------------
			lpMIS->itemWidth = sz.cx + m_szMenuLogo.cx + m_szMenuIcon.cx + MENU_SPACE * 5;
		}
		else 
		{
			//普通菜单宽度---------------------------
			lpMIS->itemWidth = sz.cx  + m_szMenuIcon.cx + MENU_SPACE * 5;
		}
	}

}

/*========================================================================
	功能:		获取菜单命令ID对应的图标序列号
	----------------------------------------------
	uID:		菜单命令ID
==========================================================================*/
int CCoolMenu::GetIndex(UINT uID)
{
	for(int i = 0; i < m_uIDArray.GetSize(); i ++)
	{
		if(uID == m_uIDArray[i])
		{
			if (i >= m_iImageList.GetImageCount()) return -1;
			return i;
		}
	}
	return -1;
}

/*========================================================================
	功能:		绘制菜单
	------------------------------------------------
	lpDIS:		自绘信息结构体
==========================================================================*/
void CCoolMenu::DrawItem(LPDRAWITEMSTRUCT lpDIS)
{
	LPCOOLMENU lpMenu = (LPCOOLMENU)(lpDIS->itemData);
	if(!AfxIsValidAddress(lpMenu, sizeof(COOLMENU))) return ;

	CDC *pdc = CDC::FromHandle(lpDIS->hDC);
	const CRect rect = lpDIS->rcItem;
//#ifdef _DEBUG
//    CMemoryState oldmem,newmem,diff;
//	oldmem.Checkpoint();
//#endif
	//建立内存上下文---------------------------------------	
	CDC *pDC = new CDC();
//#ifdef _DEBUG
//	newmem.Checkpoint();
//	if(diff.Difference(oldmem,newmem))
//	{
//		ASSERT(0);
//	}
//#endif
	pDC->CreateCompatibleDC(pdc);
	CBitmap *bitmap, *oldbitmap;
	bitmap = new CBitmap;
	bitmap->CreateCompatibleBitmap(pdc,rect.right, rect.bottom);//improtant
	oldbitmap = pDC->SelectObject(bitmap);

	//把菜单字体选入内存设备上下文-----------------------------
	CFont fontMenu, *oldfont;
	LOGFONT lf;
	ZeroMemory(&lf, sizeof(LOGFONT));
	NONCLIENTMETRICS nm;
	nm.cbSize = sizeof(NONCLIENTMETRICS);
	VERIFY(SystemParametersInfo(SPI_GETNONCLIENTMETRICS, nm.cbSize, &nm, 0)); 
	lf = nm.lfMenuFont;
//	lf.lfUnderline=true; 

	fontMenu.CreateFontIndirect(&lf);
	oldfont = pDC->SelectObject(&fontMenu);

	pDC->SetBkColor(m_crMenuColor);
	pDC->SetBkMode(TRANSPARENT);
	pDC->SelectStockObject(NULL_BRUSH);

    //用位图填充菜单背景
//	CRect rect2;
//	rect2.left+=m_szMenuLogo.cx;
//    DrawBackGroundBmp(pdc,rect2,true);

	//当当前菜单为主菜单时,空出左边用于绘制LOGO图片----------
	int nMenuLogoBarcx = 0;	//左边LOGO栏宽度
	if (lpMenu->nMenuLevel <= MDS_TOP_SUBMENU) nMenuLogoBarcx = m_szMenuLogo.cx;

	//绘制LOGO图片----------------------------
	if (nMenuLogoBarcx > 0 && (lpDIS->itemAction & ODA_DRAWENTIRE) 
		&& lpMenu->nMenuLevel != MDS_TOP_SUBMENU)
	{
		DrawLogoBar(pdc, CRect(0, 0, m_szMenuLogo.cx, rect.bottom));
	}

	//取得菜单状态----------------------------
	BOOL bIsSelected = (lpDIS->itemState & ODS_SELECTED);
	BOOL bIsChecked  = (lpDIS->itemState & ODS_CHECKED);
	BOOL bIsGrayed   = (lpDIS->itemState & ODS_GRAYED);
	BOOL bIsHotLight  = (lpDIS->itemState & ODS_HOTLIGHT );

	//擦除背景---------------------------------
	CRect rc = rect;
	rc.left += nMenuLogoBarcx;
	if (lpMenu->nMenuID == -2)//顶级菜单-------
	{
		CBrush Brush(::GetSysColor(COLOR_3DFACE));//即是非弹出菜单
		pDC->FillRect(rc, &Brush);
	}
	else//非顶级菜单---------------------------
	{
		CBrush Brush(m_crMenuColor);
		pDC->FillRect(rc, &Brush);
	}

	//绘制Office XP风格的图标栏灰色背景------------
	if (lpMenu->nMenuID != -2 && (GetStyle() & CMS_ICONBAR != 0) && nMenuLogoBarcx == 0)
	{
		rc.right = rc.left + m_szMenuIcon.cx + MENU_SPACE*2 - 1;
		pDC->FillSolidRect(rc,m_crIconBarColor);
	}

	//绘制分隔条-----------------------------------
	if(lpMenu->nMenuID == 0)
	{
		rc = rect;
		rc.top += rect.Height()/2; //居矩形区域中间
		rc.bottom = rc.top + 2;	//高两个象素
		rc.left += (nMenuLogoBarcx + MENU_SPACE); //空出左边LOGO栏区
		if ((GetStyle() & CMS_ICONBAR != 0) && nMenuLogoBarcx == 0) 
		{
			//在XP风格下空出左边图标栏区域----------
			rc.left += (m_szMenuIcon.cx + MENU_SPACE);
		}

		pDC->Draw3dRect(rc, ::GetSysColor(COLOR_GRAYTEXT), RGB(240, 240, 240));
	}
	else
	{
	//显示菜单文字-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

		//禁止菜单========================================================
		if(bIsGrayed) 
		{
			rc = rect;
			rc.left += nMenuLogoBarcx; //空出左边LOGO栏区域
			
			// 菜单被选择----------------------------------
			if(bIsSelected) 
			{
			//	DrawLightBar(pDC, rc, FALSE);
			}

			//菜单文本----------------------------
			if(lpMenu->strText.GetLength() > 0)
			{
				rc.left += (m_szMenuIcon.cx + MENU_SPACE*3 + 1); 
				rc.top += 2;
				rc.right -= 11;//调节快捷方式的宽度"ctrl+o"
				//绘制立体字---------------------------
				pDC->SetTextColor(::GetSysColor(COLOR_3DLIGHT));
				pDC->DrawText(lpMenu->strText, &rc, DT_EXPANDTABS | DT_VCENTER | DT_SINGLELINE);
				pDC->DrawText(lpMenu->strKeyName, &rc, DT_EXPANDTABS | DT_VCENTER | DT_SINGLELINE | DT_RIGHT);
			
				pDC->SetTextColor(::GetSysColor(COLOR_GRAYTEXT));
				rc.InflateRect(1,1,-1,-1);
				pDC->DrawText(lpMenu->strText, &rc, DT_EXPANDTABS | DT_VCENTER | DT_SINGLELINE);
				pDC->DrawText(lpMenu->strKeyName, &rc, DT_EXPANDTABS | DT_VCENTER | DT_SINGLELINE | DT_RIGHT);
			}
			
		}
	//非禁止菜单==========================================================
		else 
		{
			//顶层菜单------------------------------------------
			if (lpMenu->nMenuID == -2) 
			{
				rc = rect;
				rc.right -= 4;
				
				m_rcMenuItem = rect;

				//选择状态----------------------------
				if (bIsSelected) 
				{
					DrawMenuBar(pDC, rect);
					pDC->SetTextColor(::GetSysColor(COLOR_MENUTEXT));
					m_rcMenuItem = rect;
					CRect rcFram; 
					AfxGetMainWnd()->GetWindowRect(&rcFram);
					m_rcMenuItem.OffsetRect(rcFram.TopLeft());
				}

				//焦点状态----------------------------
				else if (bIsHotLight)  
				{
					DrawLightBar(pDC, rc);
					pDC->SetTextColor(m_crHighLightColor);
					m_rcMenuItem.SetRectEmpty();
				}

				//正常状态----------------------------
				else 
				{
					pDC->SetTextColor(::GetSysColor(COLOR_MENUTEXT));
					m_rcMenuItem.SetRectEmpty();
				}

				//菜单文本----------------------------
				if(lpMenu->strText.GetLength() > 0)
				{
					pDC->DrawText(lpMenu->strText, &rc, DT_EXPANDTABS | DT_CENTER | DT_VCENTER | DT_SINGLELINE);
				}
			}
			//非顶层菜单,是弹出菜单或者一个菜单项目---------------
			else 
			{
				rc = rect;
				rc.left += nMenuLogoBarcx;
				//选择状态-----------------------------
				if(bIsSelected)
				{
					DrawLightBar(pDC, rc);
					pDC->SetTextColor(m_crHighLightColor);
				}
				//非选择状态---------------------------
				else
				{
					pDC->SetTextColor(m_crTextColor);
				}

				//菜单文本----------------------------
				if(lpMenu->strText.GetLength() > 0)
				{
					rc.left += (m_szMenuIcon.cx + MENU_SPACE*3);
					rc.right -= 12;
					pDC->DrawText(lpMenu->strText, &rc, DT_EXPANDTABS |
						DT_VCENTER | DT_SINGLELINE);
					pDC->DrawText(lpMenu->strKeyName, &rc, DT_EXPANDTABS | 
						DT_VCENTER | DT_SINGLELINE | DT_RIGHT);
				}
			}
		}

	//<<绘制图标或Check标志-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-

		rc = rect;
		rc.left += (nMenuLogoBarcx + MENU_SPACE -1);
		rc.top += ((rect.Height() - m_szMenuIcon.cy)/2 + 1);
		rc.right = rc.left + m_szMenuIcon.cx;
		rc.bottom = rc.top + m_szMenuIcon.cy;

		int nIndex = GetIndex(lpMenu->nMenuID);

		//如果有图标------------------------------------------
		if(nIndex >= 0) 
		{
			//画图标Check框-----------------------------------
			if(bIsChecked)
			{
				CRect rcc = rect;
				rcc.left += nMenuLogoBarcx;
				rcc.right = rcc.left + rect.Height() + 1;
				if (bIsSelected)
				{
				//	rcc.InflateRect(-1,-1);
				//	pDC->FillSolidRect(rcc,m_crMenuColor);
				//	pDC->Draw3dRect(rcc, RGB(255,255,255), TOP_COLOR);
				}
				else 
				{
					pDC->FillSolidRect(rcc,RGB(235,235,235));
					pDC->Draw3dRect(rc, RGB(160,170,210), RGB(160,170,210));

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -