📄 bcmenu.cpp
字号:
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 BCMenu::MeasureItem( LPMEASUREITEMSTRUCT lpMIS )
{
UINT state = (((BCMenuData*)(lpMIS->itemData))->nFlags);
int BCMENU_PAD=4;
if(IsLunaMenuStyle()&&xp_draw_3D_bitmaps)BCMENU_PAD=7;
if(state & MF_SEPARATOR){
lpMIS->itemWidth = 0;
int temp = GetSystemMetrics(SM_CYMENU)>>1;
lpMIS->itemHeight = temp>(m_iconY+BCMENU_PAD)/2 ? temp : (m_iconY+BCMENU_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 = ((BCMenuData*)(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+BCMENU_PAD+8+t.cx;
else lpMIS->itemWidth = m_iconX + t.cx + m_iconX + BCMENU_GAP;
int temp = GetSystemMetrics(SM_CYMENU);
lpMIS->itemHeight = temp>m_iconY+BCMENU_PAD ? temp : m_iconY+BCMENU_PAD;
m_fontMenu.DeleteObject();
}
}
void BCMenu::SetIconSize (int width, int height)
{
m_iconX = width;
m_iconY = height;
}
BOOL BCMenu::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 BCMenu::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);
}
BCMenuData *mdata = new BCMenuData;
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 BCMenu::AppendODMenuA(LPCSTR lpstrText,UINT nFlags,UINT nID,
CImageList *il,int xoffset)
{
USES_CONVERSION;
return AppendODMenuW(A2W(lpstrText),nFlags,nID,il,xoffset);
}
BOOL BCMenu::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);
}
BCMenuData *mdata = new BCMenuData;
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 BCMenu::InsertODMenuA(UINT nPosition,LPCSTR lpstrText,UINT nFlags,UINT nID,
int nIconNormal)
{
USES_CONVERSION;
return InsertODMenuW(nPosition,A2W(lpstrText),nFlags,nID,nIconNormal);
}
BOOL BCMenu::InsertODMenuW(UINT nPosition,wchar_t *lpstrText,UINT nFlags,UINT nID,
int nIconNormal)
{
if(!(nFlags & MF_BYPOSITION)){
int iPosition =0;
BCMenu* 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();
BCMenuData *mdata = new BCMenuData;
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 BCMenu::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 BCMenu::InsertODMenuW(UINT nPosition,wchar_t *lpstrText,UINT nFlags,UINT nID,
CImageList *il,int xoffset)
{
if(!(nFlags & MF_BYPOSITION)){
int iPosition =0;
BCMenu* 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();
BCMenuData *mdata = new BCMenuData;
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 BCMenu::ModifyODMenuA(const char * lpstrText,UINT nID,int nIconNormal)
{
USES_CONVERSION;
return ModifyODMenuW(A2W(lpstrText),nID,nIconNormal);//SK: see MFC Tech Note 059
}
BOOL BCMenu::ModifyODMenuW(wchar_t *lpstrText,UINT nID,int nIconNormal)
{
int nLoc;
BCMenuData *mdata;
CArray<BCMenu*,BCMenu*>bcsubs;
CArray<int,int&>bclocs;
// Find the old BCMenuData structure:
BCMenu *psubmenu = FindMenuOption(nID,nLoc);
do{
if(psubmenu && nLoc>=0)mdata = psubmenu->m_MenuList[nLoc];
else{
// Create a new BCMenuData structure:
mdata = new BCMenuData;
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 BCMenu::ModifyODMenuA(const char * lpstrText,UINT nID,CImageList *il,int xoffset)
{
USES_CONVERSION;
return ModifyODMenuW(A2W(lpstrText),nID,il,xoffset);
}
BOOL BCMenu::ModifyODMenuW(wchar_t *lpstrText,UINT nID,CImageList *il,int xoffset)
{
int nLoc;
BCMenuData *mdata;
CArray<BCMenu*,BCMenu*>bcsubs;
CArray<int,int&>bclocs;
// Find the old BCMenuData structure:
BCMenu *psubmenu = FindMenuOption(nID,nLoc);
do{
if(psubmenu && nLoc>=0)mdata = psubmenu->m_MenuList[nLoc];
else{
// Create a new BCMenuData structure:
mdata = new BCMenuData;
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);
}
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 BCMenu::ModifyODMenuA(const char * lpstrText,UINT nID,CBitmap *bmp)
{
USES_CONVERSION;
return ModifyODMenuW(A2W(lpstrText),nID,bmp);
}
BOOL BCMenu::ModifyODMenuW(wchar_t *lpstrText,UINT nID,CBitmap *bmp)
{
if(bmp){
CImageList temp;
temp.Create(m_iconX,m_iconY,ILC_COLORDDB|ILC_MASK,1,1);
if(m_bitmapBackgroundFlag)temp.Add(bmp,m_bitmapBackground);
else temp.Add(bmp,GetSysColor(COLOR_3DFACE));
return ModifyODMenuW(lpstrText,nID,&temp,0);
}
return ModifyODMenuW(lpstrText,nID,NULL,0);
}
// courtesy of Warren Stevens
BOOL BCMenu::ModifyODMenuA(const char * lpstrText,UINT nID,COLORREF fill,COLORREF border,int hatchstyle,CSize *pSize)
{
USES_CONVERSION;
return ModifyODMenuW(A2W(lpstrText),nID,fill,border,hatchstyle,pSize);
}
BOOL BCMenu::ModifyODMenuW(wchar_t *lpstrText,UINT nID,COLORREF fill,COLORREF border,int hatchstyle,CSize *pSize)
{
CWnd *pWnd = AfxGetMainWnd(); // Get main window
CDC *pDC = pWnd->GetDC(); // Get device context
SIZE sz;
if(!pSize){
sz.cx = m_iconX;
sz.cy = m_iconY;
}
else{
sz.cx = pSize->cx;
sz.cy = pSize->cy;
}
CSize bitmap_size(sz);
CSize icon_size(m_iconX,m_iconY);
CBitmap bmp;
ColorBitmap(pDC,bmp,bitmap_size,icon_size,fill,border,hatchstyle);
pWnd->ReleaseDC(pDC);
return ModifyODMenuW(lpstrText,nID,&bmp);
}
BOOL BCMenu::ModifyODMenuA(const char *lpstrText,const char *OptionText,
int nIconNormal)
{
USES_CONVERSION;
return ModifyODMenuW(A2W(lpstrText),A2W(OptionText),nIconNormal);//SK: see MFC Tech Note 059
}
BOOL BCMenu::ModifyODMenuW(wchar_t *lpstrText,wchar_t *OptionText,
int nIconNormal)
{
BCMenuData *mdata;
// Find the old BCMenuData structure:
CString junk=OptionText;
mdata=FindMenuOption(OptionText);
if(mdata){
if(lpstrText)
mdata->SetWideString(lpstrText);//SK: modified for dynamic allocation
mdata->menuIconNormal = nIconNormal;
mdata->xoffset=-1;
if(nIconNormal>=0){
mdata->xoffset=0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -