📄 bcmenu.cpp
字号:
m_lf = nm.lfMenuFont;
m_fontMenu.CreateFontIndirect (&m_lf);
// Obtain the width of the text:
CWnd *pWnd = AfxGetMainWnd(); // Get main window
CDC *pDC = pWnd->GetDC(); // Get device context
CFont* pFont; // Select menu font in...
if (Windoze95==g_Shell || WinNT4orHigher==g_Shell)
pFont = pDC->SelectObject (&m_fontMenu);// Select menu font in...
//Get pointer to text SK
wchar_t *lpstrText = ((BCMenuData*)(lpMIS->itemData))->menuText;
SIZE size;
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(Windoze95==g_Shell || WinNT4orHigher==g_Shell)
pDC->SelectObject (pFont); // Select old font in
AfxGetMainWnd()->ReleaseDC(pDC); // Release the DC
// Set width and height:
lpMIS->itemWidth = m_iconX + t.cx + m_iconX + GAP;
int temp = GetSystemMetrics(SM_CYMENU);
lpMIS->itemHeight = temp>m_iconY+4 ? temp : m_iconY+4;
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)
{
ASSERT(lpstrText);
int iBufSize=(CPInfo.MaxCharSize==1)?strlen(lpstrText):
_mbstrlen(lpstrText);
iBufSize++;//Increment for the terminating NULL
wchar_t *szText=new wchar_t[iBufSize];
VERIFY(MultiByteToWideChar(
CP_ACP, // code page
MB_PRECOMPOSED, // character-type options
lpstrText, // address of string to map
-1, // number of characters in string
szText, // address of wide-character buffer
iBufSize*sizeof(wchar_t)// size of buffer
));
BOOL bRetVal=AppendODMenuW(szText,nFlags,nID,nIconNormal);
delete[] szText;
return bRetVal;
}
BOOL BCMenu::AppendODMenuW(wchar_t *lpstrText,UINT nFlags,UINT nID,
int nIconNormal)
{
// Add the MF_OWNERDRAW flag if not specified:
ASSERT(lpstrText);
if(!nID)nFlags=MF_SEPARATOR|MF_OWNERDRAW;
else if(!(nFlags & MF_OWNERDRAW))nFlags |= MF_OWNERDRAW;
BCMenuData *mdata = new BCMenuData;
m_MenuList.Add(mdata);
wcscpy(mdata->menuText, lpstrText);
int iBufSize=wcslen(lpstrText)+1;
char *szTemp=new char[iBufSize*sizeof(wchar_t)];
if (*lpstrText){
VERIFY(WideCharToMultiByte(
CP_ACP, // code page
0, // performance and mapping flags
lpstrText, // address of wide-character string
-1, // number of characters in string
szTemp, // address of buffer for new string
iBufSize*sizeof(wchar_t), // size of buffer
NULL, // address of default for unmappable characters
NULL // address of flag set when default char. used
));
}
else szTemp[0]=0x00;
delete[] szTemp;
mdata->menuIconNormal = nIconNormal;
mdata->xoffset=-1;
if(nIconNormal>=0){
mdata->xoffset=0;
LoadFromToolBar(nID,nIconNormal,mdata->xoffset);
if(mdata->bitmap)mdata->bitmap->DeleteImageList();
else mdata->bitmap=new(CImageList);
mdata->bitmap->Create(m_iconX,m_iconY,ILC_COLORDDB|ILC_MASK,1,1);
AddBitmapToImageList(mdata->bitmap,nIconNormal);
}
mdata->nFlags = nFlags;
mdata->nID = nID;
return(CMenu::AppendMenu(nFlags, nID, (LPCTSTR)mdata));
}
BOOL BCMenu::ModifyODMenuA(const char * lpstrText,UINT nID,int nIconNormal)
{
BOOL bRetVal;
wchar_t *szText=NULL;
if (lpstrText){
int iBufSize=(CPInfo.MaxCharSize==1)?strlen(lpstrText):
_mbstrlen(lpstrText);
iBufSize++;//Increment for the terminating NULL
szText=new wchar_t[iBufSize];
VERIFY(MultiByteToWideChar(
CP_ACP, // code page
MB_PRECOMPOSED, // character-type options
lpstrText, // address of string to map
-1, // number of characters in string
szText, // address of wide-character buffer
iBufSize*sizeof(wchar_t)// size of buffer
));
}
bRetVal=ModifyODMenuW(szText,nID,nIconNormal);
delete[] szText;
return bRetVal;
}
BOOL BCMenu::ModifyODMenuW(wchar_t *lpstrText,UINT nID,int nIconNormal)
{
int nLoc;
BCMenuData *mdata;
// Find the old BCMenuData structure:
BCMenu *psubmenu = FindMenuOption(nID,nLoc);
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)
wcscpy(mdata->menuText, lpstrText);
mdata->menuIconNormal = nIconNormal;
mdata->xoffset=-1;
if(nIconNormal>=0){
mdata->xoffset=0;
LoadFromToolBar(nID,nIconNormal,mdata->xoffset);
if(mdata->bitmap)mdata->bitmap->DeleteImageList();
else mdata->bitmap=new(CImageList);
mdata->bitmap->Create(m_iconX,m_iconY,ILC_COLORDDB|ILC_MASK,1,1);
AddBitmapToImageList(mdata->bitmap,nIconNormal);
}
mdata->nFlags = MF_BYCOMMAND | MF_OWNERDRAW;
mdata->nID = nID;
return (CMenu::ModifyMenu(nID,mdata->nFlags,nID,(LPCTSTR)mdata));
}
BOOL BCMenu::ModifyODMenuA(const char *lpstrText,const char *OptionText,
int nIconNormal)
{
BOOL bRetVal;
wchar_t *szText=NULL;
wchar_t *szOptionText=NULL;
int iBufSize;
if(lpstrText){
iBufSize=(CPInfo.MaxCharSize==1)?strlen(lpstrText):
_mbstrlen(lpstrText);
iBufSize++;//Increment for the terminating NULL
szText=new wchar_t[iBufSize];
VERIFY(MultiByteToWideChar(
CP_ACP, // code page
MB_PRECOMPOSED, // character-type options
lpstrText, // address of string to map
-1, // number of characters in string
szText, // address of wide-character buffer
iBufSize*sizeof(wchar_t)// size of buffer
));
}
if(OptionText){
iBufSize=(CPInfo.MaxCharSize==1)?strlen(OptionText):
_mbstrlen(OptionText);
iBufSize++;//Increment for the terminating NULL
szOptionText=new wchar_t[iBufSize];
VERIFY(MultiByteToWideChar(
CP_ACP, // code page
MB_PRECOMPOSED, // character-type options
OptionText, // address of string to map
-1, // number of characters in string
szOptionText, // address of wide-character buffer
iBufSize*sizeof(wchar_t)// size of buffer
));
}
bRetVal=ModifyODMenuW(szText,szOptionText,nIconNormal);
delete[] szText;
delete[] szOptionText;
return bRetVal;
}
BOOL BCMenu::ModifyODMenuW(wchar_t *lpstrText,wchar_t *OptionText,
int nIconNormal)
{
BCMenuData *mdata;
// Find the old BCMenuData structure:
mdata=FindMenuOption(OptionText);
if(mdata){
if(lpstrText)wcscpy(mdata->menuText, lpstrText);
mdata->menuIconNormal = nIconNormal;
mdata->xoffset=-1;
if(nIconNormal>=0){
mdata->xoffset=0;
if(mdata->bitmap)mdata->bitmap->DeleteImageList();
else mdata->bitmap=new(CImageList);
mdata->bitmap->Create(m_iconX,m_iconY,ILC_COLORDDB|ILC_MASK,1,1);
AddBitmapToImageList(mdata->bitmap,nIconNormal);
}
return(TRUE);
}
return(FALSE);
}
BCMenuData *BCMenu::NewODMenu(UINT pos,UINT nFlags,UINT nID,CString string)
{
BCMenuData *mdata;
mdata = new BCMenuData;
mdata->menuIconNormal = -1;
mdata->xoffset=-1;
#ifdef UNICODE
wcscpy(mdata->menuText,string);//SK
#else
mdata->SetAnsiString(string);
#endif
mdata->nFlags = nFlags;
mdata->nID = nID;
if (nFlags&MF_OWNERDRAW){
ASSERT(!(nFlags&MF_STRING));
ModifyMenu(pos,nFlags,nID,(LPCTSTR)mdata);
}
else if (nFlags&MF_STRING){
ASSERT(!(nFlags&MF_OWNERDRAW));
ModifyMenu(pos,nFlags,nID,mdata->GetString());
}
else{
ASSERT(nFlags&MF_SEPARATOR);
ModifyMenu(pos,nFlags,nID);
}
return(mdata);
};
BOOL BCMenu::LoadToolbars(const UINT *arID,int n)
{
ASSERT(arID);
BOOL bRet=TRUE;
for(int i=0;i<n;++i)
bRet |= LoadToolbar(arID[i]);
return(bRet);
}
BOOL BCMenu::LoadToolbar(UINT nToolBar)
{
UINT nID;
BOOL returnflag=FALSE;
CToolBar bar;
bar.Create(AfxGetMainWnd());
if(bar.LoadToolBar(nToolBar)){
for(int i=0;i<bar.GetCount();++i){
nID = bar.GetItemID(i);
if(nID && GetMenuState(nID, MF_BYCOMMAND)
!=0xFFFFFFFF)ModifyODMenu(NULL,nID,nToolBar);
}
returnflag=TRUE;
}
return(returnflag);
}
BOOL BCMenu::LoadFromToolBar(UINT nID,UINT nToolBar,int& xoffset)
{
int xset,offset;
UINT nStyle;
BOOL returnflag=FALSE;
CToolBar bar;
bar.Create(AfxGetMainWnd());
if(bar.LoadToolBar(nToolBar)){
offset=bar.CommandToIndex(nID);
if(offset>=0){
bar.GetButtonInfo(offset,nID,nStyle,xset);
if(xset>0)xoffset=xset;
returnflag=TRUE;
}
}
return(returnflag);
}
BCMenu *BCMenu::FindMenuOption(int nId,int& nLoc)
{
int i;
BCMenu *psubmenu,*pgoodmenu;
for(i=0;i<(int)(GetMenuItemCount());++i){
#ifdef _CPPRTTI
psubmenu=dynamic_cast<BCMenu *>(GetSubMenu(i));
#else
psubmenu=(BCMenu *)GetSubMenu(i);
#endif
if(psubmenu){
pgoodmenu=psubmenu->FindMenuOption(nId,nLoc);
if(pgoodmenu)return(pgoodmenu);
}
else if(nId==(int)GetMenuItemID(i)){
nLoc=i;
return(this);
}
}
nLoc = -1;
return(NULL);
}
BCMenuData *BCMenu::FindMenuOption(wchar_t *lpstrText)
{
int i;
BCMenu *psubmenu;
BCMenuData *pmenulist;
for(i=0;i<(int)(GetMenuItemCount());++i){
#ifdef _CPPRTTI
psubmenu=dynamic_cast<BCMenu *>(GetSubMenu(i));
#else
psubmenu=(BCMenu *)GetSubMenu(i);
#endif
if(psubmenu){
pmenulist=psubmenu->FindMenuOption(lpstrText);
if(pmenulist)return(pmenulist);
}
else{
for(i=0;i<=m_MenuList.GetUpperBound();++i){
if(!wcscmp(lpstrText,m_MenuList[i]->menuText))
return(m_MenuList[i]);
}
}
}
return(NULL);
}
BOOL BCMenu::LoadMenu(int nResource)
{
return(BCMenu::LoadMenu(MAKEINTRESOURCE(nResource)));
};
BOOL BCMenu::LoadMenu(LPCTSTR lpszResourceName)
{
TRACE(_T(
"IMPORTANT:Use BCMenu::DestroyMenu to destroy Loaded Menu's\n"));
ASSERT_VALID(this);
ASSERT(lpszResourceName != NULL);
// Find the Menu Resource:
HINSTANCE m_hInst = AfxFindResourceHandle(lpszResourceName,RT_MENU);
HRSRC hRsrc = ::FindResource(m_hInst,lpszResourceName,RT_MENU);
if(hRsrc == NULL)return FALSE;
// Get size of resource:
DWORD dwSize = SizeofResource(NULL, hRsrc);
// Load the Menu Resource:
HGLOBAL hGlobal = LoadResource(m_hInst, hRsrc);
if(hGlobal == NULL)return FALSE;
// Attempt to create us as a menu...
if(!CMenu::CreateMenu())return FALSE;
// Get Item template Header, and calculate offset of MENUITEMTEMPLATES
MENUITEMTEMPLATEHEADER *pTpHdr=
(MENUITEMTEMPLATEHEADER*)LockResource(hGlobal);
BYTE* pTp=(BYTE*)pTpHdr +
(sizeof(MENUITEMTEMPLATEHEADER) + pTpHdr->offset);
// Variables needed during processing of Menu Item Templates:
int j=0;
BCMenuData* pData = NULL; // New OD Menu Item Data
WORD dwFlags = 0; // Flags of the Menu Item
WORD dwID = 0; // ID of the Menu Item
UINT uFlags; // Actual Flags.
wchar_t *szCaption=NULL;
int nLen = 0; // Length of caption
CTypedPtrArray<CPtrArray, BCMenu*> m_Stack; // Popup menu stack
CArray<BOOL,BOOL> m_StackEnd; // Popup menu stack
m_Stack.Add(this); // Add it to this...
m_StackEnd.Add(FALSE);
do{
// Obtain Flags and (if necessary), the ID...
memcpy(&dwFlags, pTp, sizeof(WORD));pTp+=sizeof(WORD);// Obtain Flags
if(!(dwFlags & MF_POPUP)){
memcpy(&dwID, pTp, sizeof(WORD)); // Obtain ID
pTp+=sizeof(WORD);
}
else dwID = 0;
uFlags = (UINT)dwFlags; // Remove MF_END from the flags that will
if(uFlags & MF_END) // be passed to the Append(OD)Menu functions.
uFlags -= MF_END;
// Obtain Caption (and length)
nLen = 0;
char *ch = (char*)pTp;
szCaption=new wchar_t[wcslen((wchar_t *)pTp)+1];
wcscpy(szCaption,(wchar_t *)pTp);
pTp=&pTp[(wcslen((wchar_t *)pTp)+1)*sizeof(wchar_t)];//modified SK
// Handle popup menus first....
//WideCharToMultiByte
if(dwFlags & MF_POPUP){
if(dwFlags & MF_END)m_StackEnd.SetAt(m_Stack.GetUpperBound(),TRUE);
BCMenu* pSubMenu = new BCMenu;
pSubMenu->m_unselectcheck=m_unselectcheck;
pSubMenu->m_selectcheck=m_selectcheck;
pSubMenu->checkmaps=checkmaps;
pSubMenu->checkmapsshare=TRUE;
pSubMenu->CreatePopupMenu();
// Append it to the top of the stack:
m_Stack[m_Stack.GetUpperBound()]->AppendODMenuW(szCaption,uFlags,
(UINT)pSubMenu->m_hMenu, -1);
m_Stack.Add(pSubMenu);
m_StackEnd.Add(FALSE);
m_SubMenus.Add(pSubMenu);
}
else {
m_Stack[m_Stack.GetUpperBound()]->AppendODMenuW(szCaption, uFlags,
dwID, -1);
if(dwFlags & MF_END)m_StackEnd.SetAt(m_Stack.GetUpperBound(),TRUE);
j = m_Stack.GetUpperBound();
while(j>=0 && m_StackEnd.GetAt(j)){
m_Stack[m_Stack.GetUpperBound()]->InsertSpaces();
m_Stack.RemoveAt(j);
m_StackEnd.RemoveAt(j);
--j;
}
}
delete[] szCaption;
}while(m_Stack.GetUpperBound() != -1);
for(int i=0;i<(int)GetMenuItemCount();++i){
CString str=m_MenuList[i]->GetString();
if(GetSubMenu(i)){
m_MenuList[i]->nFlags=MF_POPUP|MF_BYPOSITION;
ModifyMenu(i,MF_POPUP|MF_BYPOSITION,
(UINT)GetSubMenu(i)->m_hMenu,str);
}
else{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -