📄 bcmenu.cpp
字号:
pDC->Draw3dRect(rect2,GetSysColor(COLOR_3DSHADOW),
GetSysColor(COLOR_3DHILIGHT));
}
else
{
pDC->FillRect (rect2,&m_brBackground);
rect2.SetRect(rect.left,rect.top+dy,rect.left+m_iconX+4,
rect.top+m_iconY+4+dy);
pDC->Draw3dRect (rect2,m_clrBack,m_clrBack);
}
CPoint ptImage(rect.left+2,rect.top+2+dy);
if(bitmap)bitmap->Draw(pDC,xoffset,ptImage,ILD_TRANSPARENT);
}
}
if(nIconNormal<0 && state&ODS_CHECKED && !checkflag)
{
rect2.SetRect(rect.left+1,rect.top+2+dy,rect.left+m_iconX+1,
rect.top+m_iconY+2+dy);
CMenuItemInfo info;
info.fMask = MIIM_CHECKMARKS;
::GetMenuItemInfo((HMENU)lpDIS->hwndItem,lpDIS->itemID,
MF_BYCOMMAND, &info);
if(state&ODS_CHECKED || info.hbmpUnchecked)
{
Draw3DCheckmark(pDC, rect2, state&ODS_SELECTED,
state&ODS_CHECKED ? info.hbmpChecked :
info.hbmpUnchecked);
}
}
//This is needed always so that we can have the space for check marks
x0=rect.left;y0=rect.top;
rect.left = rect.left + m_iconX + 8 + GAP;
if(!strText.IsEmpty())
{
CRect rectt(rect.left,rect.top-1,rect.right,rect.bottom-1);
// Find tabs
CString leftStr,rightStr;
leftStr.Empty();rightStr.Empty();
int tablocr=strText.ReverseFind(_T('\t'));
if(tablocr!=-1)
{
rightStr=strText.Mid(tablocr+1);
leftStr=strText.Left(strText.Find(_T('\t')));
rectt.right-=m_iconX;
}
else leftStr=strText;
int iOldMode = pDC->GetBkMode();
pDC->SetBkMode( TRANSPARENT);
// Draw the text in the correct colour:
UINT nFormat = DT_LEFT|DT_SINGLELINE|DT_VCENTER;
UINT nFormatr = DT_RIGHT|DT_SINGLELINE|DT_VCENTER;
if(!(lpDIS->itemState & ODS_GRAYED))
{
pDC->SetTextColor(crText);
pDC->DrawText (leftStr,rectt,nFormat);
if(tablocr!=-1) pDC->DrawText (rightStr,rectt,nFormatr);
}
else
{
// Draw the disabled text
if(!(state & ODS_SELECTED))
{
RECT offset = *rectt;
offset.left+=1;
offset.right+=1;
offset.top+=1;
offset.bottom+=1;
pDC->SetTextColor(GetSysColor(COLOR_BTNHILIGHT));
pDC->DrawText(leftStr,&offset, nFormat);
if(tablocr!=-1) pDC->DrawText (rightStr,&offset,nFormatr);
pDC->SetTextColor(GetSysColor(COLOR_GRAYTEXT));
pDC->DrawText(leftStr,rectt, nFormat);
if(tablocr!=-1) pDC->DrawText (rightStr,rectt,nFormatr);
}
else
{
// And the standard Grey text:
pDC->SetTextColor(m_clrBack);
pDC->DrawText(leftStr,rectt, nFormat);
if(tablocr!=-1) pDC->DrawText (rightStr,rectt,nFormatr);
}
}
pFont = pDC->SelectObject (&dispFont);
pDC->SetBkMode( iOldMode );
pDC->SelectObject (pFont); //set it to the old font
}
m_penBack.DeleteObject();
m_fontMenu.DeleteObject();
m_brSelect.DeleteObject();
dispFont.DeleteObject ();
}
m_brBackground.DeleteObject();
}
COLORREF BCMenu::LightenColor(COLORREF col,double factor)
{
if(factor>0.0&&factor<=1.0){
BYTE red,green,blue,lightred,lightgreen,lightblue;
red = GetRValue(col);
green = GetGValue(col);
blue = GetBValue(col);
lightred = (BYTE)((factor*(255-red)) + red);
lightgreen = (BYTE)((factor*(255-green)) + green);
lightblue = (BYTE)((factor*(255-blue)) + blue);
col = RGB(lightred,lightgreen,lightblue);
}
return(col);
}
//以XP的风格画菜单
void BCMenu::DrawItem_WinXP (LPDRAWITEMSTRUCT lpDIS)
{
ASSERT(lpDIS != NULL);
CDC* pDC = CDC::FromHandle(lpDIS->hDC);
#ifdef BCMENU_USE_MEMDC
BCMenuMemDC *pMemDC=NULL;
#endif
CRect rect,rect2;
UINT state = (((BCMenuData*)(lpDIS->itemData))->nFlags);
// COLORREF m_newclrBack=GetSysColor((IsNewShell())?COLOR_3DFACE:COLOR_MENU);
//这个颜色可以改变左边的一个条形颜色
COLORREF m_newclrBack=RGB(250,184,244);
//这个颜色可以改变菜单的表面颜色
// COLORREF m_clrBack=GetSysColor(COLOR_MENU);
COLORREF m_clrBack=RGB(250,250,220);
// COLORREF m_clrBack=GetSysColor(COLOR_3DFACE);
//
BOOL XPflag = m_newclrBack==m_clrBack ? FALSE : TRUE;
if(!XPflag)
{
m_newclrBack=LightenColor(m_newclrBack,0.35);
m_clrBack=RGB(255,255,255);
}
CBrush m_newbrBackground,m_brBackground;
m_brBackground.CreateSolidBrush(m_clrBack);
m_newbrBackground.CreateSolidBrush(m_newclrBack);
// remove the selected bit if it's grayed out
if(lpDIS->itemState & ODS_GRAYED&&!xp_select_disabled)
{
if(lpDIS->itemState & ODS_SELECTED)lpDIS->itemState=lpDIS->itemState & ~ODS_SELECTED;
#ifdef BCMENU_USE_MEMDC
pMemDC=new BCMenuMemDC(pDC,&lpDIS->rcItem);
pDC = pMemDC;
#endif
}
if(state & MF_SEPARATOR)
{
rect.CopyRect(&lpDIS->rcItem);
pDC->FillRect (rect,&m_brBackground);
rect2.SetRect(rect.left,rect.top,rect.left+m_iconX+4+GAP,rect.bottom);
rect.top+=rect.Height()>>1;
rect.left = rect2.right+4;
pDC->DrawEdge(&rect,EDGE_ETCHED,BF_TOP);
pDC->FillRect (rect2,&m_newbrBackground);
pDC->Draw3dRect (rect2,m_newclrBack,m_newclrBack);
}
else
{
BOOL standardflag=FALSE,selectedflag=FALSE,disableflag=FALSE;
BOOL checkflag=FALSE;
COLORREF crText = GetSysColor(COLOR_MENUTEXT);
COLORREF crSelect = GetSysColor(COLOR_HIGHLIGHT);
COLORREF crSelectFill;
if(!XPflag)crSelectFill=LightenColor(crSelect,0.85);
else crSelectFill=LightenColor(crSelect,0.7);
CBrush m_brSelect;
CPen m_penBack;
int x0,y0,dy;
int nIconNormal=-1,xoffset=-1;
CImageList *bitmap=NULL;
CFont m_fontMenu;
LOGFONT m_lf;
// set some colors and the font
m_penBack.CreatePen (PS_SOLID,0,m_clrBack);
m_brSelect.CreateSolidBrush(crSelectFill);
ZeroMemory ((PVOID) &m_lf,sizeof (LOGFONT));
NONCLIENTMETRICS nm;
nm.cbSize = sizeof (NONCLIENTMETRICS);
VERIFY (SystemParametersInfo(SPI_GETNONCLIENTMETRICS,nm.cbSize,&nm,0));
m_lf = nm.lfMenuFont;
m_fontMenu.CreateFontIndirect (&m_lf);
// draw the colored rectangle portion
rect.CopyRect(&lpDIS->rcItem);
rect2=rect;
// draw the up/down/focused/disabled state
UINT state = lpDIS->itemState;
CString strText;
LOGFONT lf;
lf = m_lf;
CFont dispFont;
CFont *pFont=NULL;
if(lpDIS->itemData != NULL)
{
nIconNormal = (((BCMenuData*)(lpDIS->itemData))->menuIconNormal);
xoffset = (((BCMenuData*)(lpDIS->itemData))->xoffset);
bitmap = (((BCMenuData*)(lpDIS->itemData))->bitmap);
strText = ((BCMenuData*) (lpDIS->itemData))->GetString();
if(state&ODS_CHECKED && nIconNormal<0)
{
if(state&ODS_SELECTED && m_selectcheck>0)checkflag=TRUE;
else if(m_unselectcheck>0) checkflag=TRUE;
}
else if(nIconNormal != -1)
{
standardflag=TRUE;
if(state&ODS_SELECTED && !(state&ODS_GRAYED))selectedflag=TRUE;
else if(state&ODS_GRAYED) disableflag=TRUE;
}
}
else
{
strText.Empty();
}
if(state&ODS_SELECTED)
{
// draw the down edges
CPen *pOldPen = pDC->SelectObject (&m_penBack);
pDC->FillRect (rect,&m_brSelect);
pDC->Draw3dRect (rect,crSelect,crSelect);
pDC->SelectObject (pOldPen);
if((HFONT)dispFont != NULL)dispFont.DeleteObject ();
dispFont.CreateFontIndirect (&lf);
}
else
{
rect2.SetRect(rect.left,rect.top,rect.left+m_iconX+4+GAP,rect.bottom);
CPen *pOldPen = pDC->SelectObject (&m_penBack);
pDC->FillRect (rect,&m_brBackground);
pDC->FillRect (rect2,&m_newbrBackground);
pDC->SelectObject (pOldPen);
// draw the up edges
pDC->Draw3dRect (rect,m_clrBack,m_clrBack);
pDC->Draw3dRect (rect2,m_newclrBack,m_newclrBack);
if ((HFONT)dispFont != NULL) dispFont.DeleteObject ();
dispFont.CreateFontIndirect (&lf); //Normal
}
// draw the text if there is any
//We have to paint the text only if the image is nonexistant
dy = (rect.Height()-4-m_iconY)/2;
dy = dy<0 ? 0 : dy;
if(checkflag||standardflag||selectedflag||disableflag)
{
rect2.SetRect(rect.left+1,rect.top+1+dy,rect.left+m_iconX+3,
rect.top+m_iconY+3+dy);
pDC->Draw3dRect (rect2,m_newclrBack,m_newclrBack);
if(checkflag && checkmaps)
{
pDC->FillRect (rect2,&m_newbrBackground);
rect2.SetRect(rect.left,rect.top+dy,rect.left+m_iconX+4,
rect.top+m_iconY+4+dy);
pDC->Draw3dRect (rect2,m_newclrBack,m_newclrBack);
CPoint ptImage(rect.left+3,rect.top+2+dy);
if(state&ODS_SELECTED)checkmaps->Draw(pDC,1,ptImage,ILD_TRANSPARENT);
else checkmaps->Draw(pDC,0,ptImage,ILD_TRANSPARENT);
}
else if(disableflag)
{
if(!selectedflag)
{
CBitmap bitmapstandard;
GetBitmapFromImageList(pDC,bitmap,xoffset,bitmapstandard);
rect2.SetRect(rect.left,rect.top+dy,rect.left+m_iconX+4,
rect.top+m_iconY+4+dy);
pDC->Draw3dRect (rect2,m_newclrBack,m_newclrBack);
COLORREF transparentcol=m_newclrBack;
if(state&ODS_SELECTED)transparentcol=crSelectFill;
if(disable_old_style)
DitherBlt(lpDIS->hDC,rect.left+2,rect.top+2+dy,m_iconX,m_iconY,
(HBITMAP)(bitmapstandard),0,0,transparentcol);
else
DitherBlt2(pDC,rect.left+2,rect.top+2+dy,m_iconX,m_iconY,
bitmapstandard,0,0,transparentcol);
if(state&ODS_SELECTED)pDC->Draw3dRect (rect,crSelect,crSelect);
bitmapstandard.DeleteObject();
}
}
else if(selectedflag)
{
pDC->FillRect (rect2,&m_brSelect);
if (IsNewShell() && state&ODS_CHECKED)
{
rect2.SetRect(rect.left,rect.top,rect.left+m_iconX+GAP+3,rect.bottom);
pDC->Draw3dRect(rect2,crSelect,crSelect);
}
CPoint ptImage(rect.left+3,rect.top+2+dy);
if(bitmap)bitmap->Draw(pDC,xoffset,ptImage,ILD_TRANSPARENT);
}
else
{
if(state&ODS_CHECKED)
{
if(!XPflag)rect2.SetRect(rect.left+1,rect.top,rect.left+m_iconX+GAP+3,rect.bottom);
else rect2.SetRect(rect.left+1,rect.top,rect.left+m_iconX+GAP+3,rect.bottom-1);
CBrush brushin;
brushin.CreateSolidBrush(LightenColor(crSelect,0.85));
pDC->FillRect(rect2,&brushin);
brushin.DeleteObject();
pDC->Draw3dRect(rect2,crSelect,crSelect);
}
else
{
pDC->FillRect (rect2,&m_newbrBackground);
rect2.SetRect(rect.left,rect.top+dy,rect.left+m_iconX+4,
rect.top+m_iconY+4+dy);
pDC->Draw3dRect (rect2,m_newclrBack,m_newclrBack);
}
CPoint ptImage(rect.left+3,rect.top+2+dy);
if(bitmap)bitmap->Draw(pDC,xoffset,ptImage,ILD_TRANSPARENT);
}
}
if(nIconNormal<0 && state&ODS_CHECKED && !checkflag)
{
CMenuItemInfo info;
info.fMask = MIIM_CHECKMARKS;
::GetMenuItemInfo((HMENU)lpDIS->hwndItem,lpDIS->itemID,
MF_BYCOMMAND, &info);
if(state&ODS_CHECKED || info.hbmpUnchecked)
{
if(XPflag)rect2.SetRect(rect.left+2,rect.top+2+dy,rect.left+m_iconX+2,rect.top+m_iconY+3+dy);
else rect2.SetRect(rect.left+2,rect.top+2+dy,rect.left+m_iconX+2,rect.top+m_iconY+2+dy);
DrawXPCheckmark(pDC, rect2,state&ODS_CHECKED ? info.hbmpChecked :
info.hbmpUnchecked,crSelect);
}
}
//This is needed always so that we can have the space for check marks
x0=rect.left;y0=rect.top;
rect.left = rect.left + m_iconX + 8 + GAP;
if(!strText.IsEmpty())
{
CRect rectt(rect.left,rect.top-1,rect.right,rect.bottom-1);
// Find tabs
CString leftStr,rightStr;
leftStr.Empty();rightStr.Empty();
int tablocr=strText.ReverseFind(_T('\t'));
if(tablocr!=-1)
{
rightStr=strText.Mid(tablocr+1);
leftStr=strText.Left(strText.Find(_T('\t')));
rectt.right-=m_iconX;
}
else leftStr=strText;
int iOldMode = pDC->GetBkMode();
pDC->SetBkMode( TRANSPARENT);
// Draw the text in the correct colour:
pFont = pDC->SelectObject (&dispFont);
UINT nFormat = DT_LEFT|DT_SINGLELINE|DT_VCENTER;
UINT nFormatr = DT_RIGHT|DT_SINGLELINE|DT_VCENTER;
if(!(lpDIS->itemState & ODS_GRAYED))
{
pDC->SetTextColor(crText);
pDC->DrawText (leftStr,rectt,nFormat);
if(tablocr!=-1) pDC->DrawText (rightStr,rectt,nFormatr);
}
else
{
RECT offset = *rectt;
offset.left+=1;
offset.right+=1;
offset.top+=1;
offset.bottom+=1;
if(!XPflag)
{
COLORREF graycol=GetSysColor(COLOR_GRAYTEXT);
graycol = LightenColor(graycol,0.55);
pDC->SetTextColor(graycol);
}
else pDC->SetTextColor(GetSysColor(COLOR_GRAYTEXT));
pDC->DrawText(leftStr,rectt, nFormat);
if(tablocr!=-1) pDC->DrawText (rightStr,rectt,nFormatr);
}
pDC->SetBkMode( iOldMode );
pDC->SelectObject (pFont); //set it to the old font
}
m_penBack.DeleteObject();
m_fontMenu.DeleteObject();
m_brSelect.DeleteObject();
dispFont.DeleteObject ();
}
m_brBackground.DeleteObject();
m_newbrBackground.DeleteObject();
#ifdef BCMENU_USE_MEMDC
if(pMemDC)delete pMemDC;
#endif
}
BOOL BCMenu::GetBitmapFromImageList(CDC* pDC,CImageList *imglist,int nIndex,CBitmap &bmp)
{
HICON hIcon = imglist->ExtractIcon(nIndex);
CDC dc;
dc.CreateCompatibleDC(pDC);
bmp.CreateCompatibleBitmap(pDC,m_iconX,m_iconY);
CBitmap* pOldBmp = dc.SelectObject(&bmp);
CBrush brush ;
brush.CreateSolidBrush(GetSysColor(COLOR_MENU));
::DrawIconEx(
dc.GetSafeHdc(),
0,
0,
hIcon,
m_iconX,
m_iconY,
0,
(HBRUSH)brush,
DI_NORMAL
);
dc.SelectObject( pOldBmp );
dc.DeleteDC();
// the icon is not longer needed
DestroyIcon(hIcon);
return(TRUE);
}
/*
==========================================================================
void BCMenu::MeasureItem(LPMEASUREITEMSTRUCT)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -