📄 bcmenu.cpp
字号:
pDC->FillRect(rect2,&brush);
brush.DeleteObject();
rect2.SetRect(rect.left,rect.top+dy,rect.left+m_iconX+4,
rect.top+m_iconY+4+dy);
if (IsNewShell())
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 + BCMENU_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);
}
}
pDC->SetBkMode( iOldMode );
}
m_penBack.DeleteObject();
m_brSelect.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);
}
COLORREF BCMenu::DarkenColor(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)(red-(factor*red));
lightgreen = (BYTE)(green-(factor*green));
lightblue = (BYTE)(blue-(factor*blue));
col = RGB(lightred,lightgreen,lightblue);
}
return(col);
}
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(COLOR_3DFACE);
COLORREF m_clrBack=GetSysColor(COLOR_WINDOW);
m_clrBack=DarkenColor(m_clrBack,0.02);
CFont m_fontMenu,*pFont=NULL;
LOGFONT m_lf;
if(!IsWinXPLuna())m_newclrBack=LightenColor(m_newclrBack,0.25);
CBrush m_newbrBackground,m_brBackground;
m_brBackground.CreateSolidBrush(m_clrBack);
m_newbrBackground.CreateSolidBrush(m_newclrBack);
int BCMENU_PAD=4;
if(xp_draw_3D_bitmaps)BCMENU_PAD=7;
int barwidth=m_iconX+BCMENU_PAD;
// 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;
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);
pFont = pDC->SelectObject (&m_fontMenu);
#endif
}
if(state & MF_SEPARATOR){
rect.CopyRect(&lpDIS->rcItem);
pDC->FillRect (rect,&m_brBackground);
rect2.SetRect(rect.left,rect.top,rect.left+barwidth,rect.bottom);
rect.top+=rect.Height()>>1;
rect.left = rect2.right+BCMENU_PAD;
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(!IsWinXPLuna())crSelectFill=LightenColor(crSelect,0.85);
else crSelectFill=LightenColor(crSelect,0.7);
CBrush m_brSelect;
CPen m_penBack;
int x0,y0,dx,dy;
int nIconNormal=-1,xoffset=-1,global_offset=-1;
int faded_offset=1,shadow_offset=2,disabled_offset=3;
CImageList *bitmap=NULL;
BOOL CanDraw3D=FALSE;
// set some colors
m_penBack.CreatePen (PS_SOLID,0,m_clrBack);
m_brSelect.CreateSolidBrush(crSelectFill);
// draw the colored rectangle portion
rect.CopyRect(&lpDIS->rcItem);
rect2=rect;
// draw the up/down/focused/disabled state
UINT state = lpDIS->itemState;
CString strText;
if(lpDIS->itemData != NULL){
nIconNormal = (((BCMenuData*)(lpDIS->itemData))->menuIconNormal);
xoffset = (((BCMenuData*)(lpDIS->itemData))->xoffset);
bitmap = (((BCMenuData*)(lpDIS->itemData))->bitmap);
strText = ((BCMenuData*) (lpDIS->itemData))->GetString();
global_offset = (((BCMenuData*)(lpDIS->itemData))->global_offset);
if(xoffset==0&&xp_draw_3D_bitmaps&&bitmap&&bitmap->GetImageCount()>2)CanDraw3D=TRUE;
if(nIconNormal<0&&xoffset<0&&global_offset>=0){
xoffset=global_offset;
nIconNormal=0;
bitmap = &m_AllImages;
if(xp_draw_3D_bitmaps&&CanDraw3DImageList(global_offset)){
CanDraw3D=TRUE;
faded_offset=global_offset+1;
shadow_offset=global_offset+2;
disabled_offset=global_offset+3;
}
}
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);
}
else {
rect2.SetRect(rect.left,rect.top,rect.left+barwidth,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);
}
// draw the text if there is any
//We have to paint the text only if the image is nonexistant
dy = (int)(0.5+(rect.Height()-m_iconY)/2.0);
dy = dy<0 ? 0 : dy;
dx = (int)(0.5+(barwidth-m_iconX)/2.0);
dx = dx<0 ? 0 : dx;
rect2.SetRect(rect.left+1,rect.top+1,rect.left+barwidth-2,rect.bottom-1);
if(checkflag||standardflag||selectedflag||disableflag){
if(checkflag && checkmaps){
pDC->FillRect (rect2,&m_newbrBackground);
CPoint ptImage(rect.left+dx,rect.top+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){
if(CanDraw3D){
CPoint ptImage(rect.left+dx,rect.top+dy);
bitmap->Draw(pDC,disabled_offset,ptImage,ILD_TRANSPARENT);
}
else{
CBitmap bitmapstandard;
GetBitmapFromImageList(pDC,bitmap,xoffset,bitmapstandard);
COLORREF transparentcol=m_newclrBack;
if(state&ODS_SELECTED)transparentcol=crSelectFill;
if(disable_old_style)
DitherBlt(lpDIS->hDC,rect.left+dx,rect.top+dy,m_iconX,m_iconY,
(HBITMAP)(bitmapstandard),0,0,transparentcol);
else
DitherBlt2(pDC,rect.left+dx,rect.top+dy,m_iconX,m_iconY,
bitmapstandard,0,0,transparentcol);
if(state&ODS_SELECTED)pDC->Draw3dRect (rect,crSelect,crSelect);
bitmapstandard.DeleteObject();
}
}
}
else if(selectedflag){
CPoint ptImage(rect.left+dx,rect.top+dy);
if(state&ODS_CHECKED){
CBrush brushin;
brushin.CreateSolidBrush(LightenColor(crSelect,0.55));
pDC->FillRect(rect2,&brushin);
brushin.DeleteObject();
pDC->Draw3dRect(rect2,crSelect,crSelect);
ptImage.x-=1;ptImage.y-=1;
}
else pDC->FillRect (rect2,&m_brSelect);
if(bitmap){
if(CanDraw3D&&!(state&ODS_CHECKED)){
CPoint ptImage1(ptImage.x+1,ptImage.y+1);
CPoint ptImage2(ptImage.x-1,ptImage.y-1);
bitmap->Draw(pDC,shadow_offset,ptImage1,ILD_TRANSPARENT);
bitmap->Draw(pDC,xoffset,ptImage2,ILD_TRANSPARENT);
}
else bitmap->Draw(pDC,xoffset,ptImage,ILD_TRANSPARENT);
}
}
else{
if(state&ODS_CHECKED){
CBrush brushin;
brushin.CreateSolidBrush(LightenColor(crSelect,0.85));
pDC->FillRect(rect2,&brushin);
brushin.DeleteObject();
pDC->Draw3dRect(rect2,crSelect,crSelect);
CPoint ptImage(rect.left+dx-1,rect.top+dy-1);
if(bitmap)bitmap->Draw(pDC,xoffset,ptImage,ILD_TRANSPARENT);
}
else{
pDC->FillRect (rect2,&m_newbrBackground);
pDC->Draw3dRect (rect2,m_newclrBack,m_newclrBack);
CPoint ptImage(rect.left+dx,rect.top+dy);
if(bitmap){
if(CanDraw3D)
bitmap->Draw(pDC,faded_offset,ptImage,ILD_TRANSPARENT);
else
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) {
DrawXPCheckmark(pDC, rect2,state&ODS_CHECKED ? info.hbmpChecked :
info.hbmpUnchecked,crSelect,state&ODS_SELECTED);
}
}
//This is needed always so that we can have the space for check marks
x0=rect.left;y0=rect.top;
rect.left = rect.left + barwidth + 8;
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{
RECT offset = *rectt;
offset.left+=1;
offset.right+=1;
offset.top+=1;
offset.bottom+=1;
if(!IsWinXPLuna()){
COLORREF graycol=GetSysColor(COLOR_GRAYTEXT);
if(!(state&ODS_SELECTED))graycol = LightenColor(graycol,0.4);
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 );
}
m_penBack.DeleteObject();
m_brSelect.DeleteObject();
}
m_brBackground.DeleteObject();
m_newbrBackground.DeleteObject();
#ifdef BCMENU_USE_MEMDC
if(pFont)pDC->SelectObject (pFont); //set it to the old font
m_fontMenu.DeleteObject();
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 ;
COLORREF m_newclrBack;
m_newclrBack=GetSysColor(COLOR_3DFACE);
brush.CreateSolidBrush(m_newclrBack);
::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)
---------------------------------------------
Called by the framework when it wants to know what the width and height
of our item will be. To accomplish this we provide the width of the
icon plus the width of the menu text, and then the height of the icon.
==========================================================================
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -