📄 bcmenu.cpp
字号:
if(bitmap)bitmap->Draw(pDC,xoffset,ptImage,ILD_TRANSPARENT);
}
else{
if(state&ODS_CHECKED){
CBrush brush;
COLORREF col = m_clrBack;
col = LightenColor(col,0.6);
brush.CreateSolidBrush(col);
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);
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;
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;
}
}
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;
if(checkflag||standardflag||selectedflag||disableflag){
rect2.SetRect(rect.left+1,rect.top+1,rect.left+barwidth-1,
rect.bottom-1);
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){
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){
pDC->FillRect (rect2,&m_brSelect);
CPoint ptImage(rect.left+dx,rect.top+dy);
if(state&ODS_CHECKED){
pDC->Draw3dRect(rect2,crSelect,crSelect);
ptImage.x-=1;ptImage.y-=1;
}
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){
dy = (int)(0.5+(rect.Height()-16)/2.0);
dy = dy<0 ? 0 : dy;
dx = (int)(0.5+(barwidth-16)/2.0);
dx = dx<0 ? 0 : dx;
CMenuItemInfo info;
info.fMask = MIIM_CHECKMARKS;
::GetMenuItemInfo((HMENU)lpDIS->hwndItem,lpDIS->itemID,
MF_BYCOMMAND, &info);
if(state&ODS_CHECKED || info.hbmpUnchecked) {
rect2.SetRect(rect.left+dx,rect.top+dy,rect.left+dx+16,rect.top+dy+16);
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 + 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)
---------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -