📄 bcmenu.cpp
字号:
BOOL BCMenu::LoadToolbars(const UINT *arID,int n){ ASSERT(arID); BOOL returnflag=TRUE; for(int i=0;i<n;++i){ if(!LoadToolbar(arID[i]))returnflag=FALSE; } return(returnflag);}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);}// O.S.BCMenuData *BCMenu::FindMenuItem(UINT nID){ BCMenuData *pData = NULL; int i; for(i = 0; i <= m_MenuList.GetUpperBound(); i++){ if (m_MenuList[i]->nID == nID){ pData = m_MenuList[i]; break; } } if (!pData){ int loc; BCMenu *pMenu = FindMenuOption(nID, loc); ASSERT(pMenu != this); if (loc >= 0){ return pMenu->FindMenuItem(nID); } } return pData;}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,j; 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{ const wchar_t *szWide;//SK: we use const to prevent misuse of this Ptr for(j=0;j<=m_MenuList.GetUpperBound();++j){ szWide = m_MenuList[j]->GetWideString (); if(szWide && !wcscmp(lpstrText,szWide))//SK: modified for dynamic allocation return(m_MenuList[j]); } } } 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; // 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; 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; 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); } 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{ m_MenuList[i]->nFlags=MF_STRING|MF_BYPOSITION; ModifyMenu(i,MF_STRING|MF_BYPOSITION,m_MenuList[i]->nID,str); } } return(TRUE);}void BCMenu::InsertSpaces(void){ int i,j,numitems,maxlength; CString string,newstring; CSize t; 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); CWnd *pWnd = AfxGetMainWnd(); CDC *pDC = pWnd->GetDC(); CFont* pFont = pDC->SelectObject (&m_fontMenu); numitems=GetMenuItemCount(); maxlength = -1; for(i=0;i<numitems;++i){ string=m_MenuList[i]->GetString(); j=string.Find((char)9); newstring.Empty(); if(j!=-1)newstring=string.Left(j); else newstring=string; newstring+=_T(" ");//SK: modified for Unicode correctness. LPCTSTR lpstrText = (LPCTSTR)newstring; t=pDC->GetTextExtent(lpstrText,_tcslen(lpstrText)); if(t.cx>maxlength)maxlength = t.cx; } for(i=0;i<numitems;++i){ string=m_MenuList[i]->GetString(); j=string.Find((char)9); if(j!=-1){ newstring.Empty(); newstring=string.Left(j); LPCTSTR lpstrText = (LPCTSTR)(newstring); t=pDC->GetTextExtent(lpstrText,_tcslen(lpstrText)); while(t.cx<maxlength){ newstring+=_T(' ');//SK: modified for Unicode correctness LPCTSTR lpstrText = (LPCTSTR)(newstring); t=pDC->GetTextExtent(lpstrText,_tcslen(lpstrText)); } newstring+=string.Mid(j);#ifdef UNICODE m_MenuList[i]->SetWideString(newstring);//SK: modified for dynamic allocation#else m_MenuList[i]->SetAnsiString(newstring);#endif } } pDC->SelectObject (pFont); // Select old font in AfxGetMainWnd()->ReleaseDC(pDC); // Release the DC m_fontMenu.DeleteObject();}void BCMenu::LoadCheckmarkBitmap(int unselect, int select){ if(unselect>0 && select>0){ m_selectcheck=select; m_unselectcheck=unselect; if(checkmaps)checkmaps->DeleteImageList(); else checkmaps=new(CImageList); checkmaps->Create(m_iconX,m_iconY,ILC_MASK,2,1); BOOL flag1=AddBitmapToImageList(checkmaps,unselect); BOOL flag2=AddBitmapToImageList(checkmaps,select); if(!flag1||!flag2){ checkmaps->DeleteImageList(); delete checkmaps; checkmaps=NULL; } }}//--------------------------------------------------------------------------//[18.06.99 rj]BOOL BCMenu::GetMenuText(UINT id, CString& string, UINT nFlags/*= MF_BYPOSITION*/){ BOOL returnflag=FALSE; if(MF_BYPOSITION&nFlags){ UINT numMenuItems = m_MenuList.GetUpperBound(); if(id<=numMenuItems){ string=m_MenuList[id]->GetString(); returnflag=TRUE; } } else{ int uiLoc; BCMenu* pMenu = FindMenuOption(id,uiLoc); if(NULL!=pMenu) returnflag = pMenu->GetMenuText(uiLoc,string); } return(returnflag);}void BCMenu::DrawRadioDot(CDC *pDC,int x,int y,COLORREF color){ CRect rcDot(x,y,x+6,y+6); CBrush brush; CPen pen; brush.CreateSolidBrush(color); pen.CreatePen(PS_SOLID,0,color); CBrush *pOldBrush=pDC->SelectObject(&brush); CPen *pOldPen=pDC->SelectObject(&pen); pDC->Ellipse(&rcDot); pDC->SelectObject(pOldBrush); pDC->SelectObject(pOldPen); pen.DeleteObject(); brush.DeleteObject();}void BCMenu::DrawCheckMark(CDC* pDC,int x,int y,COLORREF color){ pDC->SetPixel(x,y+2,color); pDC->SetPixel(x,y+3,color); pDC->SetPixel(x,y+4,color); pDC->SetPixel(x+1,y+3,color); pDC->SetPixel(x+1,y+4,color); pDC->SetPixel(x+1,y+5,color); pDC->SetPixel(x+2,y+4,color); pDC->SetPixel(x+2,y+5,color); pDC->SetPixel(x+2,y+6,color); pDC->SetPixel(x+3,y+3,color); pDC->SetPixel(x+3,y+4,color); pDC->SetPixel(x+3,y+5,color); pDC->SetPixel(x+4,y+2,color); pDC->SetPixel(x+4,y+3,color); pDC->SetPixel(x+4,y+4,color); pDC->SetPixel(x+5,y+1,color); pDC->SetPixel(x+5,y+2,color); pDC->SetPixel(x+5,y+3,color); pDC->SetPixel(x+6,y,color); pDC->SetPixel(x+6,y+1,color); pDC->SetPixel(x+6,y+2,color);}BCMenuData *BCMenu::FindMenuList(UINT nID){ for(int i=0;i<=m_MenuList.GetUpperBound();++i){ if(m_MenuList[i]->nID==nID && !m_MenuList[i]->syncflag){ m_MenuList[i]->syncflag=1; return(m_MenuList[i]); } } return(NULL);}void BCMenu::InitializeMenuList(int value){ for(int i=0;i<=m_MenuList.GetUpperBound();++i) m_MenuList[i]->syncflag=value;}void BCMenu::DeleteMenuList(void){ for(int i=0;i<=m_MenuList.GetUpperBound();++i){ if(!m_MenuList[i]->syncflag){ delete m_MenuList[i]; } }}void BCMenu::SynchronizeMenu(void){ CTypedPtrArray<CPtrArray, BCMenuData*> temp; BCMenuData *mdata; CString string; UINT submenu,nID=0,state,j; InitializeMenuList(0); for(j=0;j<GetMenuItemCount();++j){ mdata=NULL; state=GetMenuState(j,MF_BYPOSITION); if(state&MF_POPUP){ submenu=(UINT)GetSubMenu(j)->m_hMenu; mdata=FindMenuList(submenu); GetMenuString(j,string,MF_BYPOSITION); if(!mdata)mdata=NewODMenu(j, (state&0xFF)|MF_BYPOSITION|MF_POPUP|MF_OWNERDRAW,submenu,string); else if(string.GetLength()>0)#ifdef UNICODE mdata->SetWideString(string); //SK: modified for dynamic allocation#else mdata->SetAnsiString(string);#endif } else if(state&MF_SEPARATOR){ mdata=FindMenuList(0); if(!mdata)mdata=NewODMenu(j, state|MF_BYPOSITION|MF_SEPARATOR|MF_OWNERDRAW,0,_T(""));//SK: modified for Unicode correctness else ModifyMenu(j,mdata->nFlags,nID,(LPCTSTR)mdata); } else{ nID=GetMenuItemID(j); mdata=FindMenuList(nID); GetMenuString(j,string,MF_BYPOSITION); if(!mdata)mdata=NewODMenu(j,state|MF_BYPOSITION|MF_OWNERDRAW, nID,string); else{ mdata->nFlags=state|MF_BYPOSITION|MF_OWNERDRAW; if(string.GetLength()>0)#ifdef UNICODE mdata->SetWideString(string);//SK: modified for dynamic allocation#else mdata->SetAnsiString(string);#endif ModifyMenu(j,mdata->nFlags,nID,(LPCTSTR)mdata); } } if(mdata)temp.Add(mdata); } DeleteMenuList(); m_MenuList.RemoveAll(); m_MenuList.Append(temp); temp.RemoveAll(); }void BCMenu::UpdateMenu(CMenu *pmenu){#ifdef _CPPRTTI BCMenu *psubmenu = dynamic_cast<BCMenu *>(pmenu);#else BCMenu *psubmenu = (BCMenu *)pmenu;#endif if(psubmenu)psubmenu->SynchronizeMenu();}LRESULT BCMenu::FindKeyboardShortcut(UINT nChar, UINT nFlags, CMenu *pMenu){#ifdef _CPPRTTI BCMenu *pBCMenu = dynamic_cast<BCMenu *>(pMenu);#else BCMenu *pBCMenu = (BCMenu *)pMenu;#endif if(pBCMenu && nFlags&MF_POPUP){ CString key(_T('&'),2);//SK: modified for Unicode correctness key.SetAt(1,(TCHAR)nChar); key.MakeLower(); CString menutext; int menusize = (int)pBCMenu->GetMenuItemCount();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -