#include "stdafx.h"
#include "MenuEx.h"
// MenuEx.cpp: implementation of the CMenuEx class.
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
//IMPLEMENT_DYNAMIC(CMenuEx, CMenu)
CMenuEx::CMenuEx() :m_szDynamic(15, 15)
{
m_clrBack = RGB(239, 243, 255);
m_clrText = ::GetSysColor(COLOR_MENUTEXT);
m_clrSelectText = ::GetSysColor(COLOR_HIGHLIGHTTEXT);
m_clrLeft = m_clrBack;
m_clrSelectBorder = RGB(49, 106, 197);
m_clrSelectRect = RGB(193, 210, 238);
m_clrSideBarStart = RGB(0, 0, 0);
m_clrSideBarEnd = RGB(255, 255, 255);
m_clrSeparator = RGB(0, 122, 204);
m_nSeparator = 4; //sparator的默认高度
m_bBreak = FALSE;
m_bBreakBar = FALSE;
m_font.DeleteObject();
m_font.CreatePointFont(120, "MicrSoft YaHei");
}
CMenuEx::~CMenuEx()
{
Destroy();
}
void CMenuEx::Destroy()
{
for (int i = 0; i < m_arrSubMenu.GetSize(); i++)
{
CMenuEx *pSubMenu = m_arrSubMenu.GetAt(i);
delete pSubMenu;
}
for (int i = 0; i < m_arrMenuItem.GetSize(); i++)
{
CMenuExItem *pMenuItem = m_arrMenuItem.GetAt(i);
delete pMenuItem;
}
DestroyMenu();
}
/////////////////////////////////////////////////
//当菜单项为不可用时绘制灰色的文本
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::DrawMenuSepartor(CDC *pDC, CRect &rect)
{
CRect rcTemp(rect);
CPen pen(PS_SOLID, 1, m_clrSeparator);
CPen* pOldPen = pDC->SelectObject(&pen);
pDC->MoveTo(rcTemp.left, rcTemp.top + rcTemp.Height() / 2);
pDC->LineTo(rcTemp.right, rcTemp.top + rcTemp.Height() / 2);
pDC->SelectObject(pOldPen);
}
void CMenuEx::DrawMenuGrayed(CDC *pDC, CRect &rect, CMenuExItem* lpItem)
{
CRect rc(rect.left, rect.top, rect.left + m_szDynamic.cx + 4, rect.top + m_szDynamic.cy + 4);
CPoint pt(rc.left, rc.top);
CSize si(rc.Width(), rc.Height());
pDC->DrawState(pt, si, lpItem->m_strText, DSS_DISABLED, TRUE, 0, (HBRUSH)NULL);
}
void CMenuEx::DrawMenuDisabled(CDC *pDC, CRect &rect, CMenuExItem* lpItem)
{
CRect rc(rect.left, rect.top, rect.left + m_szDynamic.cx + 4 , rect.top + m_szDynamic.cy + 4);
}
void CMenuEx::DrawCheckedMark(CDC *pDC, CRect &rect, CMenuExItem* lpItem)
{
CRect rc(rect.left, rect.top, rect.left + m_szDynamic.cx + 4, rect.top + m_szDynamic.cy + 4);
CRect rcII(rect);
rcII.right = rcII.Height();
rc.MoveToXY(rcII.left + rcII.Width() / 3, rcII.top + rcII.Height() / 4);
COLORREF clrOld = pDC->SetTextColor(RGB(255, 255, 255));
pDC->DrawText("√", &rc, DT_EXPANDTABS | DT_VCENTER | DT_SINGLELINE);
pDC->SetTextColor(clrOld);
}
/////////////////////////////////////////////////
void CMenuEx::DrawMenuIcon(CDC *pDC, CRect &rect, BOOL bSelected, CMenuExItem* lpItem)
{
CRect rcImg(rect);
rcImg.right = rcImg.Height();
if (bSelected)
{
rcImg.DeflateRect(1, 1 , 1, 1 );
pDC->Draw3dRect(rcImg, RGB(255, 0, 0), RGB(255, 0, 0));
}
if (rcImg.Height() <= 16)
{
::DrawIconEx(pDC->m_hDC, rcImg.left, rcImg.top, lpItem->m_hIcon, rcImg.Width(), rcImg.Height(), 0, NULL, DI_NORMAL);
}
else
{
int dec = rect.Height()*(bSelected ? 0.2 : 0.3);
rcImg.DeflateRect(dec, dec, dec, dec);
DrawIconEx(pDC->m_hDC, rcImg.left, rcImg.top, lpItem->m_hIcon, rcImg.Width(), rcImg.Height(), 0, NULL, DI_NORMAL);
}
}
/////////////////////////////////////////////////
//绘制菜单项文本
//参数:rect:立体矩形的RECT
// rtText:菜单文本的RECT
void CMenuEx::DrawMenuText(CDC *pDC, CRect rect, CRect rcText, BOOL bSelected, CMenuExItem* lpItem)
{
//选中状态的菜单项要先画出立体矩形
if (bSelected)
{
CRect rcItem = rect;
CPen BorderPen, *pOldPen;
BorderPen.CreatePen(PS_SOLID, 1, m_clrSelectBorder); //边框颜色
CBrush BKBrush, *pOldBrush;
BKBrush.CreateSolidBrush(m_clrSelectRect); //选中后的颜色
pOldPen = pDC->SelectObject(&BorderPen);
pOldBrush = pDC->SelectObject(&BKBrush);
pDC->Rectangle(&rcItem);
pDC->SelectObject(pOldPen);
pDC->SelectObject(pOldBrush);
}
pDC->SelectObject(&m_font);
static int nLeft = rcText.bottom;
static int nTop = rect.Height();
rcText.MoveToXY(rcText.left + nLeft / 3, rcText.bottom - nTop);
rcText.bottom = rcText.top + nTop;
pDC->DrawText(lpItem->m_strText, rcText, DT_VCENTER | DT_SINGLELINE | DT_LEFT);
}
void CMenuEx::DrawItem(LPDRAWITEMSTRUCT lpDIS)
{
ASSERT(lpDIS);
if (lpDIS->CtlType != ODT_MENU)
return;
CDC dc;
CMenuExItem* lpItem;
CRect rect(lpDIS->rcItem);
dc.Attach(lpDIS->hDC);
lpItem = (CMenuExItem*)lpDIS->itemData;
//被选中的话,使用被选中的文本颜色
if (lpDIS->itemState & ODS_SELECTED)
dc.SetTextColor(m_clrSelectText);
else
dc.SetTextColor(m_clrText);
//设定背景色
CBrush brush(m_clrBack);
CRect rcII(rect);
rcII.MoveToX(rcII.left + rcII.Height() / 2);
dc.FillRect(&rcII, &brush);
CRect rcLeft = rect;
rcLeft.right = rcLeft.left + m_szDynamic.cx + 5;
dc.FillSolidRect(&rcLeft, m_clrLeft);
//设定显示模式
dc.SetBkMode(TRANSPARENT);
//绘制侧边位图
//get the drawing area
CRect rcItem = lpDIS->rcItem;
if (lpItem->m_bSideBar)
{
}
if (lpItem->m_nID == 0)//分隔条
{
DrawMenuSepartor(&dc, rect);
}
else
{
BOOL bSelected = lpDIS->itemState & ODS_SELECTED;
BOOL bChecked = lpDIS->itemState & ODS_CHECKED;
BOOL bGrayed = lpDIS->itemState & ODS_GRAYED;
BOOL bExistImage = (lpItem->m_hIcon != NULL) ? true : false;
BOOL bDisabled = lpDIS->itemState & ODS_DISABLED;
//绘制菜单文本
CRect rcText = rect;
rcText.left += rect.Height();
DrawMenuText(&dc, rect, rcText, bSelected, lpItem);
//绘制菜单位图
if (bExistImage)
{
DrawMenuIcon(&dc, rect, bSelected, lpItem);
}
if (bChecked)
{
DrawCheckedMark(&dc, rect, lpItem);
}
if (bGrayed)
{
DrawMenuGrayed(&dc, rect, lpItem);
}
if (bDisabled)
{
DrawMenuDisabled(&dc, rect, lpItem);
}
}
dc.SetBkMode(OPAQUE);
dc.Detach();
}
void CMenuEx::MeasureItem(LPMEASUREITEMSTRUCT lpMIS)
{
if (lpMIS->CtlType != ODT_MENU)
return;
CMenuExItem *lpItem = (CMenuExItem*)lpMIS->itemData;
if (!lpItem)
return;
if (lpItem->m_nID == 0)//分隔条
{
lpMIS->itemHeight = m_nSeparator;
}
else if (lpItem->m_bSideBar)
{
lpMIS->itemWidth = lpItem->m_nSize;
lpMIS->itemHeight = 0;
}
else
{
LOGFONT lg;
m_font.GetLogFont(&lg);
CString m_strText = lpItem->m_strText;
CSize size = GetTextSize(m_strText, lg);
lpMIS->itemWidth = size.cx;
lpMIS->itemHeight = m_szDynamic.cy + 20;
lpMIS->itemWidth += lpMIS->itemHeight*1.5;
}
int xx = 1;
}
void CMenuEx::SetTextColor(COLORREF crColor)
{
m_clrText = crColor;
for (int i = 0; i < m_arrSubMenu.GetSize(); i++)
{
CMenuEx *pSubMenu = m_arrSubMenu.GetAt(i);
pSubMenu->SetTextColor(crColor);
}
}
void CMenuEx::SetBackColor(COLORREF crColor)
{
m_clrBack = crColor;
for (int i = 0; i < m_arrSubMenu.GetSize(); i++)
{
CMenuEx *pSubMenu = m_arrSubMenu.GetAt(i);
pSubMenu->SetBackColor(crColor);
}
//偷懒不设置
SetLeftColor(crColor);
}
void CMenuEx::SetSelectTextColor(COLORREF crColor)
{
m_clrSelectText = crColor;
for (int i = 0; i < m_arrSubMenu.GetSize(); i++)
{
CMenuEx *pSubMenu = m_arrSubMenu.GetAt(i);
pSubMenu->SetSelectTextColor(crColor);
}
}
void CMenuEx::SetSelectRectColor(COLORREF clrRect, COLORREF clrBorder)
{
m_clrSelectRect = clrRect;
m_clrSelectBorder = clrBorder;
for (int i = 0; i < m_arrSubMenu.GetSize(); i++)
{
CMenuEx