📄 menuex.cpp
字号:
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 CMenuEx_USE_MEMDC
if(pFont)pDC->SelectObject (pFont); //set it to the old font
m_fontMenu.DeleteObject();
if(pMemDC)delete pMemDC;
#endif
}
BOOL CMenuEx::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 CMenuEx::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.
==========================================================================
*/
void CMenuEx::MeasureItem( LPMEASUREITEMSTRUCT lpMIS )
{
UINT state = (((CMenuExData*)(lpMIS->itemData))->nFlags);
int CMenuEx_PAD=4;
if(IsLunaMenuStyle()&&xp_draw_3D_bitmaps)CMenuEx_PAD=7;
if(state & MF_SEPARATOR){
lpMIS->itemWidth = 0;
int temp = GetSystemMetrics(SM_CYMENU)>>1;
if(IsLunaMenuStyle())
lpMIS->itemHeight = 3;
else
lpMIS->itemHeight = temp>(m_iconY+CMenuEx_PAD)/2 ? temp : (m_iconY+CMenuEx_PAD)/2;
}
else{
CFont m_fontMenu;
LOGFONT m_lf;
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);
// Obtain the width of the text:
CWnd *pWnd = AfxGetMainWnd(); // Get main window
if (pWnd == NULL) pWnd = CWnd::GetDesktopWindow();
CDC *pDC = pWnd->GetDC(); // Get device context
CFont* pFont=NULL; // Select menu font in...
if (IsNewShell())
pFont = pDC->SelectObject (&m_fontMenu);// Select menu font in...
//Get pointer to text SK
const wchar_t *lpstrText = ((CMenuExData*)(lpMIS->itemData))->GetWideString();//SK: we use const to prevent misuse
SIZE size;
size.cx=size.cy=0;
if (Win32s!=g_Shell)
VERIFY(::GetTextExtentPoint32W(pDC->m_hDC,lpstrText,
wcslen(lpstrText),&size)); //SK should also work on 95
#ifndef UNICODE //can't be UNICODE for Win32s
else{//it's Win32suckx
RECT rect;
rect.left=rect.top=0;
size.cy=DrawText(pDC->m_hDC,(LPCTSTR)lpstrText,
wcslen(lpstrText),&rect,
DT_SINGLELINE|DT_LEFT|DT_VCENTER|DT_CALCRECT);
//+3 makes at least three pixels space to the menu border
size.cx=rect.right-rect.left+3;
size.cx += 3*(size.cx/wcslen(lpstrText));
}
#endif
CSize t = CSize(size);
if(IsNewShell())
pDC->SelectObject (pFont); // Select old font in
pWnd->ReleaseDC(pDC); // Release the DC
// Set width and height:
if(IsLunaMenuStyle())lpMIS->itemWidth = m_iconX+CMenuEx_PAD+8+t.cx;
else lpMIS->itemWidth = m_iconX + t.cx + m_iconX + CMenuEx_GAP;
int temp = GetSystemMetrics(SM_CYMENU);
lpMIS->itemHeight = temp>m_iconY+CMenuEx_PAD ? temp : m_iconY+CMenuEx_PAD;
m_fontMenu.DeleteObject();
}
}
void CMenuEx::SetIconSize (int width, int height)
{
m_iconX = width;
m_iconY = height;
}
BOOL CMenuEx::AppendODMenuA(LPCSTR lpstrText,UINT nFlags,UINT nID,
int nIconNormal)
{
USES_CONVERSION;
return AppendODMenuW(A2W(lpstrText),nFlags,nID,nIconNormal);//SK: See MFC Tech Note 059
}
BOOL CMenuEx::AppendODMenuW(wchar_t *lpstrText,UINT nFlags,UINT nID,
int nIconNormal)
{
// Add the MF_OWNERDRAW flag if not specified:
if(!nID){
if(nFlags&MF_BYPOSITION)nFlags=MF_SEPARATOR|MF_OWNERDRAW|MF_BYPOSITION;
else nFlags=MF_SEPARATOR|MF_OWNERDRAW;
}
else if(!(nFlags & MF_OWNERDRAW))nFlags |= MF_OWNERDRAW;
if(nFlags & MF_POPUP){
m_AllSubMenus.Add((HMENU)nID);
m_SubMenus.Add((HMENU)nID);
}
CMenuExData *mdata = new CMenuExData;
m_MenuList.Add(mdata);
mdata->SetWideString(lpstrText); //SK: modified for dynamic allocation
mdata->menuIconNormal = -1;
mdata->xoffset = -1;
if(nIconNormal>=0){
CImageList bitmap;
int xoffset=0;
LoadFromToolBar(nID,nIconNormal,xoffset);
if(mdata->bitmap){
mdata->bitmap->DeleteImageList();
mdata->bitmap=NULL;
}
bitmap.Create(m_iconX,m_iconY,ILC_COLORDDB|ILC_MASK,1,1);
if(AddBitmapToImageList(&bitmap,nIconNormal)){
mdata->global_offset = AddToGlobalImageList(&bitmap,xoffset,nID);
}
}
else mdata->global_offset = GlobalImageListOffset(nID);
mdata->nFlags = nFlags;
mdata->nID = nID;
BOOL returnflag=CMenu::AppendMenu(nFlags, nID, (LPCTSTR)mdata);
if(m_loadmenu)RemoveTopLevelOwnerDraw();
return(returnflag);
}
BOOL CMenuEx::AppendODMenuA(LPCSTR lpstrText,UINT nFlags,UINT nID,
CImageList *il,int xoffset)
{
USES_CONVERSION;
return AppendODMenuW(A2W(lpstrText),nFlags,nID,il,xoffset);
}
BOOL CMenuEx::AppendODMenuW(wchar_t *lpstrText,UINT nFlags,UINT nID,
CImageList *il,int xoffset)
{
// Add the MF_OWNERDRAW flag if not specified:
if(!nID){
if(nFlags&MF_BYPOSITION)nFlags=MF_SEPARATOR|MF_OWNERDRAW|MF_BYPOSITION;
else nFlags=MF_SEPARATOR|MF_OWNERDRAW;
}
else if(!(nFlags & MF_OWNERDRAW))nFlags |= MF_OWNERDRAW;
if(nFlags & MF_POPUP){
m_AllSubMenus.Add((HMENU)nID);
m_SubMenus.Add((HMENU)nID);
}
CMenuExData *mdata = new CMenuExData;
m_MenuList.Add(mdata);
mdata->SetWideString(lpstrText); //SK: modified for dynamic allocation
if(il){
mdata->menuIconNormal = 0;
mdata->xoffset=0;
if(mdata->bitmap)mdata->bitmap->DeleteImageList();
else mdata->bitmap=new(CImageList);
ImageListDuplicate(il,xoffset,mdata->bitmap);
}
else{
mdata->menuIconNormal = -1;
mdata->xoffset = -1;
}
mdata->nFlags = nFlags;
mdata->nID = nID;
return(CMenu::AppendMenu(nFlags, nID, (LPCTSTR)mdata));
}
BOOL CMenuEx::InsertODMenuA(UINT nPosition,LPCSTR lpstrText,UINT nFlags,UINT nID,
int nIconNormal)
{
USES_CONVERSION;
return InsertODMenuW(nPosition,A2W(lpstrText),nFlags,nID,nIconNormal);
}
BOOL CMenuEx::InsertODMenuW(UINT nPosition,wchar_t *lpstrText,UINT nFlags,UINT nID,
int nIconNormal)
{
if(!(nFlags & MF_BYPOSITION)){
int iPosition =0;
CMenuEx* pMenu = FindMenuOption(nPosition,iPosition);
if(pMenu){
return(pMenu->InsertODMenuW(iPosition,lpstrText,nFlags|MF_BYPOSITION,nID,nIconNormal));
}
else return(FALSE);
}
if(!nID)nFlags=MF_SEPARATOR|MF_OWNERDRAW|MF_BYPOSITION;
else if(!(nFlags & MF_OWNERDRAW))nFlags |= MF_OWNERDRAW;
int menustart=0;
if(nFlags & MF_POPUP){
if(m_loadmenu){
menustart=GetMenuStart();
if(nPosition<(UINT)menustart)menustart=0;
}
m_AllSubMenus.Add((HMENU)nID);
m_SubMenus.InsertAt(nPosition,(HMENU)nID);
}
//Stephane Clog suggested adding this, believe it or not it's in the help
if(nPosition==(UINT)-1)nPosition=GetMenuItemCount();
CMenuExData *mdata = new CMenuExData;
m_MenuList.InsertAt(nPosition-menustart,mdata);
mdata->SetWideString(lpstrText); //SK: modified for dynamic allocation
mdata->menuIconNormal = nIconNormal;
mdata->xoffset=-1;
if(nIconNormal>=0){
CImageList bitmap;
int xoffset=0;
LoadFromToolBar(nID,nIconNormal,xoffset);
if(mdata->bitmap){
mdata->bitmap->DeleteImageList();
mdata->bitmap=NULL;
}
bitmap.Create(m_iconX,m_iconY,ILC_COLORDDB|ILC_MASK,1,1);
if(AddBitmapToImageList(&bitmap,nIconNormal)){
mdata->global_offset = AddToGlobalImageList(&bitmap,xoffset,nID);
}
}
else mdata->global_offset = GlobalImageListOffset(nID);
mdata->nFlags = nFlags;
mdata->nID = nID;
BOOL returnflag=CMenu::InsertMenu(nPosition,nFlags,nID,(LPCTSTR)mdata);
if(m_loadmenu)RemoveTopLevelOwnerDraw();
return(returnflag);
}
BOOL CMenuEx::InsertODMenuA(UINT nPosition,LPCSTR lpstrText,UINT nFlags,UINT nID,
CImageList *il,int xoffset)
{
USES_CONVERSION;
return InsertODMenuW(nPosition,A2W(lpstrText),nFlags,nID,il,xoffset);
}
BOOL CMenuEx::InsertODMenuW(UINT nPosition,wchar_t *lpstrText,UINT nFlags,UINT nID,
CImageList *il,int xoffset)
{
if(!(nFlags & MF_BYPOSITION)){
int iPosition =0;
CMenuEx* pMenu = FindMenuOption(nPosition,iPosition);
if(pMenu){
return(pMenu->InsertODMenuW(iPosition,lpstrText,nFlags|MF_BYPOSITION,nID,il,xoffset));
}
else return(FALSE);
}
if(!nID)nFlags=MF_SEPARATOR|MF_OWNERDRAW|MF_BYPOSITION;
else if(!(nFlags & MF_OWNERDRAW))nFlags |= MF_OWNERDRAW;
if(nFlags & MF_POPUP){
m_AllSubMenus.Add((HMENU)nID);
m_SubMenus.InsertAt(nPosition,(HMENU)nID);
}
//Stephane Clog suggested adding this, believe it or not it's in the help
if(nPosition==(UINT)-1)nPosition=GetMenuItemCount();
CMenuExData *mdata = new CMenuExData;
m_MenuList.InsertAt(nPosition,mdata);
mdata->SetWideString(lpstrText); //SK: modified for dynamic allocation
mdata->menuIconNormal = -1;
mdata->xoffset = -1;
if(il){
if(mdata->bitmap){
mdata->bitmap->DeleteImageList();
mdata->bitmap=NULL;
}
mdata->global_offset = AddToGlobalImageList(il,xoffset,nID);
}
mdata->nFlags = nFlags;
mdata->nID = nID;
return(CMenu::InsertMenu(nPosition,nFlags,nID,(LPCTSTR)mdata));
}
BOOL CMenuEx::ModifyODMenuA(const char * lpstrText,UINT nID,int nIconNormal)
{
USES_CONVERSION;
return ModifyODMenuW(A2W(lpstrText),nID,nIconNormal);//SK: see MFC Tech Note 059
}
BOOL CMenuEx::ModifyODMenuW(wchar_t *lpstrText,UINT nID,int nIconNormal)
{
int nLoc;
CMenuExData *mdata;
CArray<CMenuEx*,CMenuEx*>bcsubs;
CArray<int,int&>bclocs;
// Find the old CMenuExData structure:
CMenuEx *psubmenu = FindMenuOption(nID,nLoc);
do{
if(psubmenu && nLoc>=0)mdata = psubmenu->m_MenuList[nLoc];
else{
// Create a new CMenuExData structure:
mdata = new CMenuExData;
m_MenuList.Add(mdata);
}
ASSERT(mdata);
if(lpstrText)
mdata->SetWideString(lpstrText); //SK: modified for dynamic allocation
mdata->menuIconNormal = -1;
mdata->xoffset = -1;
if(nIconNormal>=0){
CImageList bitmap;
int xoffset=0;
LoadFromToolBar(nID,nIconNormal,xoffset);
if(mdata->bitmap){
mdata->bitmap->DeleteImageList();
mdata->bitmap=NULL;
}
bitmap.Create(m_iconX,m_iconY,ILC_COLORDDB|ILC_MASK,1,1);
if(AddBitmapToImageList(&bitmap,nIconNormal)){
mdata->global_offset = AddToGlobalImageList(&bitmap,xoffset,nID);
}
}
else mdata->global_offset = GlobalImageListOffset(nID);
mdata->nFlags &= ~(MF_BYPOSITION);
mdata->nFlags |= MF_OWNERDRAW;
mdata->nID = nID;
bcsubs.Add(psubmenu);
bclocs.Add(nLoc);
if(psubmenu && nLoc>=0)psubmenu = FindAnotherMenuOption(nID,nLoc,bcsubs,bclocs);
else psubmenu=NULL;
}while(psubmenu);
return (CMenu::ModifyMenu(nID,mdata->nFlags,nID,(LPCTSTR)mdata));
}
BOOL CMenuEx::ModifyODMenuA(const char * lpstrText,UINT nID,CImageList *il,int xoffset)
{
USES_CONVERSION;
return ModifyODMenuW(A2W(lpstrText),nID,il,xoffset);
}
BOOL CMenuEx::ModifyODMenuW(wchar_t *lpstrText,UINT nID,CImageList *il,int xoffset)
{
int nLoc;
CMenuExData *mdata;
CArray<CMenuEx*,CMenuEx*>bcsubs;
CArray<int,int&>bclocs;
// Find the old CMenuExData structure:
CMenuEx *psubmenu = FindMenuOption(nID,nLoc);
do{
if(psubmenu && nLoc>=0)mdata = psubmenu->m_MenuList[nLoc];
else{
// Create a new CMenuExData structure:
mdata = new CMenuExData;
m_MenuList.Add(mdata);
}
ASSERT(mdata);
if(lpstrText)
mdata->SetWideString(lpstrText); //SK: modified for dynamic allocation
mdata->menuIconNormal = -1;
mdata->xoffset = -1;
if(il){
if(mdata->bitmap){
mdata->bitmap->DeleteImageList();
mdata->bitmap=NULL;
}
mdata->global_offset = AddToGlobalImageList(il,xoffset,nID);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -