?? menuex.cpp
字號:
//*************************************************************************
// CMenuEx.cpp : implementation file
// Version : 2.3
// Date : June 22, 1998
// Author : Brent Corkum
//
// Portions of code supplied by:
// Ben Ashley,Girish Bharadwaj,Jean-Edouard Lachand-Robert,
// Robert Edward Caldecott,Kenny Goers,Leonardo Zide,
// Stefan Kuhr
//
// Bug Fixes:
// Stefan Kuhr,Martin Vladic,Kim Yoo Chul
//
// You are free to use/modify this code but leave this header intact.
//
//類名:CMenuEx
//功能:使菜單顯示為Office2000風(fēng)格
//修改人:徐景周(jingzhou_xu@163.net)
//組織:未來工作室(Future Studio)
//日期:2001.12.1
#include "stdafx.h" // Standard windows header file
#include "..\resource.h" //上一級目錄中
#include "MenuEx.h" // CMenuEx class declaration
#include <afxpriv.h> //SK: makes A2W and other spiffy AFX macros work
#ifdef ASK_APP_DRAW
#include "WinAppEx.h"
#endif
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#define GAP 1
#ifndef OBM_CHECK
#define OBM_CHECK 32760 // from winuser.h
#endif
#if _MFC_VER <0x400
#error This code does not work on Versions of MFC prior to 4.0
#endif
/////////////////////////////////////////////////////////////////////////////
// CMenuEx
IMPLEMENT_DYNAMIC( CMenuEx, CMenu );
static CPINFO CPInfo;
enum Win32Type{
Win32s,
Windoze95,
WinNT3,
WinNT4orHigher
};
Win32Type IsShellType()
{
Win32Type ShellType;
DWORD winVer;
OSVERSIONINFO *osvi;
winVer=GetVersion();
if(winVer<0x80000000){/*NT */
ShellType=WinNT3;
osvi= (OSVERSIONINFO *)malloc(sizeof(OSVERSIONINFO));
if (osvi!=NULL){
memset(osvi,0,sizeof(OSVERSIONINFO));
osvi->dwOSVersionInfoSize=sizeof(OSVERSIONINFO);
GetVersionEx(osvi);
if (osvi->dwMajorVersion>=4L)
ShellType=WinNT4orHigher;//yup, it is NT 4 or higher!
free(osvi);
}
}
else if (LOBYTE(LOWORD(winVer))<4)
ShellType=Win32s;/*Win32s*/
else
ShellType=Windoze95;/*Windoze95*/
return ShellType;
}
static Win32Type g_Shell=IsShellType();
void CMenuExData::SetAnsiString(LPCSTR szAnsiString)
{
ASSERT(szAnsiString);
USES_CONVERSION;
SetWideString(A2W(szAnsiString)); //SK: see MFC Tech Note 059
}
CString CMenuExData::GetString(void)//returns the menu text in ANSI or UNICODE
//depending on the MFC-Version we are using
{
CString strText;
if (m_szMenuText)
{
#ifdef UNICODE
strText = m_szMenuText;
#else
USES_CONVERSION;
strText=W2A(m_szMenuText); //SK: see MFC Tech Note 059
#endif
}
return strText;
}
/*
===============================================================================
CMenuEx::CMenuEx()
TCMeny::~CMenuEx()
-----------------
Constructor and Destructor.
===============================================================================
*/
CMenuEx::CMenuEx(BOOL bDrawGrayed, BOOL bShowLastArrow)
{
m_bDrawOnlyGray=FALSE;
disable_old_style=FALSE;
m_bEnableArrows=bShowLastArrow;
m_iconX = 16; // Icon sizes default to 16 x 16
m_iconY = 15; // ...
m_selectcheck = -1;
m_unselectcheck = -1;
checkmaps=NULL;
checkmapsshare=FALSE;
// set the color used for the transparent background in all bitmaps
m_bitmapBackground=RGB(192,192,192); //gray
m_bitmapBackgroundFlag=FALSE;
GetCPInfo(CP_ACP,&CPInfo);
hGlobal=NULL;
COLORREF m_clrBack=GetSysColor(COLOR_MENU);
m_clrHlt=GetSysColor(COLOR_3DHIGHLIGHT);
DWORD rr,gg,bb;
rr=((m_clrBack&0xff)+(m_clrHlt&0xff))>>1;
gg=(((m_clrBack>>8)&0xff)+((m_clrHlt>>8)&0xff))>>1;
bb=(((m_clrBack>>16)&0xff)+((m_clrHlt>>16)&0xff))>>1;
m_clrHlt=rr+(gg<<8)+(bb<<16);
m_bShowLastArrow=bShowLastArrow;
m_bDrawGrayed=bDrawGrayed;
}
CMenuEx::~CMenuEx()
{
DestroyMenu();
}
BOOL CMenuEx::IsNewShell ()
{
return (Windoze95==g_Shell || WinNT4orHigher==g_Shell);
}
CMenuExData::~CMenuExData()
{
if(bitmap)
delete(bitmap);
delete[] m_szMenuText; //Need not check for NULL because ANSI X3J16 allows "delete NULL"
}
void CMenuExData::SetWideString(const wchar_t *szWideString)
{
delete[] m_szMenuText;//Need not check for NULL because ANSI X3J16 allows "delete NULL"
if (szWideString)
{
m_szMenuText = new wchar_t[sizeof(wchar_t)*(wcslen(szWideString)+1)];
if (m_szMenuText)
wcscpy(m_szMenuText,szWideString);
}
else
m_szMenuText=NULL;//set to NULL so we need not bother about dangling non-NULL Ptrs
}
BOOL CMenuEx::IsMenu(CMenu *submenu)
{
int m;
int numSubMenus = m_SubMenus.GetUpperBound();
for(m=0;m<=numSubMenus;++m){
if(submenu==m_SubMenus[m])return(TRUE);
}
return(FALSE);
}
BOOL CMenuEx::DestroyMenu()
{
// Destroy Sub menus:
if (!::IsMenu(m_hMenu)) return TRUE;
int m;
int numSubMenus = m_SubMenus.GetUpperBound();
for(m = numSubMenus; m >= 0; m--)delete(m_SubMenus[m]);
m_SubMenus.RemoveAll();
// Destroy menu data
int numItems = m_MenuList.GetUpperBound();
for(m = 0; m <= numItems; m++)delete(m_MenuList[m]);
m_MenuList.RemoveAll();
if(checkmaps&&!checkmapsshare){
delete checkmaps;
checkmaps=NULL;
}
// Call base-class implementation last:
return(CMenu::DestroyMenu());
};
///////////////////////////////////////////////////////////////////////////
//
// CMenuEx message handlers
/*
==========================================================================
void CMenuEx::DrawItem(LPDRAWITEMSTRUCT)
---------------------------------------
Called by the framework when a particular item needs to be drawn. We
overide this to draw the menu item in a custom-fashion, including icons
and the 3D rectangle bar.
==========================================================================
*/
static OFFSET=0;
void CMenuEx::DrawItem (LPDRAWITEMSTRUCT lpDIS)
{
ASSERT(lpDIS != NULL);
BOOL grayedflag,lastarrowflag;
if (lpDIS->rcItem.bottom-lpDIS->rcItem.top==0)
return;
grayedflag=(((CMenuExData*) (lpDIS->itemData))->nFlagsEx) & MF_DRAWGRAYED;
int t;
if((!m_bEnableArrows)&&(((CMenuExData*) (lpDIS->itemData))->nFlags & MF_POPUP))
{
CMenuEx*pMenu=this;
t=FindMenuPos((CMenuExData*) (lpDIS->itemData),pMenu);
if (t>=0)grayedflag=pMenu->CheckIfGrayed(pMenu->GetSubMenu(t));
}
CDC* pDC = CDC::FromHandle(lpDIS->hDC);
CRect rect;
CBrush m_brLightBackground;
m_brLightBackground.CreateSolidBrush(m_clrHlt);
UINT state = (((CMenuExData*)(lpDIS->itemData))->nFlags);
if(state & MF_SEPARATOR)
{
if(grayedflag && !m_bDrawOnlyGray)
pDC->FillRect (&(lpDIS->rcItem),&m_brLightBackground);
rect.CopyRect(&lpDIS->rcItem);
rect.top+=rect.Height()>>1;
pDC->DrawEdge(&rect,EDGE_ETCHED,BF_TOP);
}
else
{
lastarrowflag=(((CMenuExData*)(lpDIS->itemData))->nFlagsEx) & MF_LASTARROW;
if (lastarrowflag)
{
if((lpDIS->itemState&ODS_SELECTED)&&(!m_bDrawOnlyGray))
{
CRect rect=lpDIS->rcItem;
int k=(rect.bottom-rect.top-12)>>1;
if (k<0) k=0;
rect.top+=k;
rect.bottom-=k;
pDC->FillRect (rect,&m_brLightBackground);
pDC->Draw3dRect (rect,GetSysColor(COLOR_3DHIGHLIGHT),GetSysColor(COLOR_3DSHADOW));
}
else
{
CBrush m_brSelect;
m_brSelect.CreateSolidBrush(GetSysColor(COLOR_MENU));
pDC->FillRect (&lpDIS->rcItem,&m_brSelect);
m_brSelect.DeleteObject();
}
const int width=5,height=8;
COLORREF crText;
crText = GetSysColor(COLOR_MENUTEXT);
int x,y;
x=(lpDIS->rcItem.left>>1)+((lpDIS->rcItem.right-width)>>1);
y=(lpDIS->rcItem.top>>1)+((lpDIS->rcItem.bottom-height)>>1);
DrawLastArrow(pDC,x,y,crText);
m_brLightBackground.DeleteObject();
return;
}
CRect rect2;
BOOL standardflag=FALSE,selectedflag=FALSE,disableflag=FALSE;
BOOL checkflag=FALSE;
CBitmap bitmapstandard;
COLORREF crText = GetSysColor(COLOR_MENUTEXT);
COLORREF m_clrBack=GetSysColor(COLOR_MENU);
CBrush m_brBackground,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,GetSysColor(COLOR_MENU));
m_brBackground.CreateSolidBrush(GetSysColor(COLOR_MENU));
m_brSelect.CreateSolidBrush(GetSysColor(COLOR_HIGHLIGHT));
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 action = lpDIS->itemAction;
UINT state = lpDIS->itemState;
CString strText;
LOGFONT lf;
lf = m_lf;
CFont dispFont;
CFont *pFont;
if(lpDIS->itemData != NULL){
nIconNormal = (((CMenuExData*)(lpDIS->itemData))->menuIconNormal);
xoffset = (((CMenuExData*)(lpDIS->itemData))->xoffset);
bitmap = (((CMenuExData*)(lpDIS->itemData))->bitmap);
strText = ((CMenuExData*) (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);
// You need only Text highlight and thats what you get
if(checkflag||standardflag||selectedflag||disableflag||state&ODS_CHECKED)
rect2.SetRect(rect.left+m_iconX+4+GAP,rect.top,rect.right,rect.bottom);
pDC->FillRect (rect2,&m_brSelect);
pDC->SelectObject (pOldPen);
if((HFONT)dispFont != NULL)dispFont.DeleteObject ();
dispFont.CreateFontIndirect (&lf);
crText = GetSysColor(COLOR_HIGHLIGHTTEXT);
}
else
{
CPen *pOldPen = pDC->SelectObject (&m_penBack);
if(grayedflag && !m_bDrawOnlyGray)
pDC->FillRect (rect,&m_brLightBackground);
else
pDC->FillRect (rect,&m_brBackground);
pDC->SelectObject (pOldPen);
// draw the up edges
if(grayedflag && !m_bDrawOnlyGray)
pDC->Draw3dRect (rect,m_clrHlt,m_clrHlt);
else
pDC->Draw3dRect (rect,m_clrBack,m_clrBack);
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);
if(grayedflag && !m_bDrawOnlyGray)
pDC->Draw3dRect (rect2,m_clrHlt,m_clrHlt);
else
pDC->Draw3dRect (rect2,m_clrBack,m_clrBack);
if(checkflag && checkmaps)
{
if(grayedflag && !m_bDrawOnlyGray)
pDC->FillRect (rect2,&m_brLightBackground);
else
pDC->FillRect (rect2,&m_brBackground);
rect2.SetRect(rect.left,rect.top+dy,rect.left+m_iconX+4,
rect.top+m_iconY+4+dy);
if(grayedflag && !m_bDrawOnlyGray)
pDC->Draw3dRect (rect2,m_clrHlt,m_clrHlt);
else
pDC->Draw3dRect (rect2,m_clrBack,m_clrBack);
CPoint ptImage(rect.left+2,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)
{
HBITMAP hbmp=LoadSysColorBitmap(nIconNormal);
if(hbmp)
{
bitmapstandard.Attach(hbmp);
rect2.SetRect(rect.left,rect.top+dy,rect.left+m_iconX+4,
rect.top+m_iconY+4+dy);
if(grayedflag && !m_bDrawOnlyGray)
pDC->Draw3dRect (rect2,m_clrHlt,m_clrHlt);
else
pDC->Draw3dRect (rect2,m_clrBack,m_clrBack);
if(disable_old_style)
DitherBlt(lpDIS->hDC,rect.left+2,rect.top+2+dy,m_iconX,m_iconY,
(HBITMAP)(bitmapstandard),xoffset*m_iconX,0);
else
DitherBlt2(pDC,rect.left+2,rect.top+2+dy,m_iconX,m_iconY,
bitmapstandard,xoffset*m_iconX,0);
bitmapstandard.DeleteObject();
}
}
}
else if(selectedflag)
{
if(grayedflag && !m_bDrawOnlyGray)
pDC->FillRect (rect2,&m_brLightBackground);
else
pDC->FillRect (rect2,&m_brBackground);
rect2.SetRect(rect.left,rect.top+dy,rect.left+m_iconX+4,
rect.top+m_iconY+4+dy);
if (IsNewShell())
{
if(state&ODS_CHECKED)
pDC->Draw3dRect(rect2,GetSysColor(COLOR_3DSHADOW),
GetSysColor(COLOR_3DHILIGHT));
else
pDC->Draw3dRect(rect2,GetSysColor(COLOR_3DHILIGHT),
GetSysColor(COLOR_3DSHADOW));
}
CPoint ptImage(rect.left+2,rect.top+2+dy);
if(bitmap)bitmap->Draw(pDC,xoffset,ptImage,ILD_TRANSPARENT);
}
else
{
if(state&ODS_CHECKED)
{
CBrush brush;
COLORREF col =GetSysColor(COLOR_3DLIGHT);
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
{
if(grayedflag && !m_bDrawOnlyGray)
pDC->FillRect (rect2,&m_brLightBackground);
else
pDC->FillRect (rect2,&m_brBackground);
rect2.SetRect(rect.left,rect.top+dy,rect.left+m_iconX+4,
rect.top+m_iconY+4+dy);
if(grayedflag && !m_bDrawOnlyGray)
pDC->Draw3dRect (rect2,m_clrHlt,m_clrHlt);
else
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);*/
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -