⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 menuext.cpp

📁 串口收发工具
💻 CPP
📖 第 1 页 / 共 4 页
字号:
	CMenuExtData *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;
		CMenuExt *pMenu = FindMenuOption(nID, loc);
		ASSERT(pMenu != this);
		if (loc >= 0){
			return pMenu->FindMenuItem(nID);
		}
	}
	return pData;
}

CMenuExt *CMenuExt::FindMenuOption(int nId,int& nLoc)
{
	CMenuExt *pSubMenu,*pGoodMenu;

	for(int i=0;i<(int)(GetMenuItemCount());++i)
	{
#ifdef _CPPRTTI 
		pSubMenu = dynamic_cast<CMenuExt *>(GetSubMenu(i));
#else
		pSubMenu=(CMenuExt *)GetSubMenu(i);
#endif
		if(pSubMenu)
		{
			pGoodMenu= pSubMenu->FindMenuOption(nId,nLoc); //递归查找,遍历所有的弹出菜单
			// 若在下面的某个弹出菜单中找到了,可以直接逐级返回了
			if(pGoodMenu) return pGoodMenu;
		}
		else if(nId == (int)GetMenuItemID(i))
		{
			nLoc = i; //在弹出菜单中的位置
			return this; //返回当前所在的弹出菜单(CMenuExt)
		}
	}
	nLoc = -1; //没有找到

	return NULL;
}

CMenuExtData *CMenuExt::FindMenuOption(wchar_t *lpstrText)
{
	int i,j;
	CMenuExt *psubmenu;
	CMenuExtData *pmenulist;
	
	for(i=0;i<(int)(GetMenuItemCount());++i){
#ifdef _CPPRTTI 
		psubmenu=dynamic_cast<CMenuExt *>(GetSubMenu(i));
#else
		psubmenu=(CMenuExt *)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 CMenuExt::LoadMenu(UINT nID)
{
	return CMenuExt::LoadMenu(MAKEINTRESOURCE(nID));
}

BOOL CMenuExt::LoadMenu(LPCTSTR lpszResourceName)
{
	if(lpszResourceName == NULL) return FALSE;

	// 查找菜单资源
	HINSTANCE m_hInst = AfxFindResourceHandle(lpszResourceName,RT_MENU);
	HRSRC hRsrc = ::FindResource(m_hInst,lpszResourceName,RT_MENU);
	if(hRsrc == NULL) return FALSE;

	// 获得菜单资源的大小
	DWORD dwSize = SizeofResource(NULL, hRsrc);

	// 调入菜单资源
	HGLOBAL hGlobal = LoadResource(m_hInst, hRsrc);
	if(hGlobal == NULL) return FALSE;

	// 创建菜单
	if(!CMenu::CreateMenu()) return FALSE;

	// 获得菜单模板头,并计算出菜单项列表的偏移量位置
	MENUITEMTEMPLATEHEADER *pHeader = (MENUITEMTEMPLATEHEADER*)LockResource(hGlobal);
	BYTE* pMenuItemTemplate = (BYTE*)pHeader + (sizeof(MENUITEMTEMPLATEHEADER) + pHeader->offset);

	int j=0;
	CMenuExtData* pData = NULL;
	WORD dwFlags = 0;	//菜单项的标志(Flags)
	WORD dwID  = 0;		//菜单项的ID
	UINT uFlags;
	wchar_t *szCaption = NULL;
	int nLen = 0; //菜单文本串长度
	CTypedPtrArray<CPtrArray, CMenuExt*> m_Stack; //弹出菜单堆栈
	CArray<BOOL,BOOL> m_StackEnd; //弹出菜单堆栈
	m_Stack.Add(this);
	m_StackEnd.Add(FALSE);

	// 下面的循环在不断的处理每个MENUITEMTEMPLATE
	do{
		memcpy(&dwFlags, pMenuItemTemplate, sizeof(WORD)); //取得mtOption
		pMenuItemTemplate += sizeof(WORD);
		if(!(dwFlags & MF_POPUP))
		{
			memcpy(&dwID, pMenuItemTemplate, sizeof(WORD)); //取得mtID
			pMenuItemTemplate += sizeof(WORD);
		}
		else dwID = 0;

		uFlags = (UINT)dwFlags;
		/* 屏蔽掉MF_END.因为结束标志放在了单独的一个m_StackEnd,
		所以没有必要AppendODMenuW一个带有MF_END标志的菜单项.
		可以参照下文的:
			if(dwFlags & MF_END) m_StackEnd.SetAt(m_Stack.GetUpperBound(),TRUE);
		*/
		if(uFlags & MF_END) uFlags -= MF_END;

		// 获得文本串
		nLen = 0;
		char *ch = (char*)pMenuItemTemplate;
		szCaption = new wchar_t[wcslen((wchar_t *)pMenuItemTemplate)+1];
		wcscpy(szCaption,(wchar_t *)pMenuItemTemplate);
		pMenuItemTemplate = &pMenuItemTemplate[(wcslen((wchar_t *)pMenuItemTemplate)+1) * sizeof(wchar_t)];

		if(dwFlags & MF_POPUP) //弹出菜单
		{
			if(dwFlags & MF_END)
				m_StackEnd.SetAt(m_Stack.GetUpperBound(),TRUE);
			CMenuExt* pSubMenu = new CMenuExt;
			pSubMenu->m_unselectcheck = m_unselectcheck;
			pSubMenu->m_selectcheck = m_selectcheck;
			pSubMenu->checkmaps = checkmaps;
			pSubMenu->checkmapsshare = TRUE;
			pSubMenu->CreatePopupMenu();

			// 添加到堆栈的顶部
			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);
			// 菜单结束项需要在m_Stack列表中记录下来
			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;
			// 弹出菜单记录的是m_hMenu
			ModifyMenu(i,MF_POPUP|MF_BYPOSITION,(UINT)GetSubMenu(i)->m_hMenu,str);
		}
		else
		{
			m_MenuList[i]->nFlags = MF_STRING|MF_BYPOSITION;
			// 普通菜单项记录的是nID
			ModifyMenu(i,MF_STRING|MF_BYPOSITION,m_MenuList[i]->nID,str);
		}
	}

	return TRUE;
}

void CMenuExt::InsertSpaces()
{
	int i,j,numitems,maxlength;
	CString string,newstring;
	CSize textSize;
	CFont fontMenu;
	LOGFONT logfont;

	// 获取系统指定的菜单字体信息
	ZeroMemory(&logfont,sizeof(LOGFONT));
	NONCLIENTMETRICS nm;
	nm.cbSize = sizeof(NONCLIENTMETRICS);
	SystemParametersInfo(SPI_GETNONCLIENTMETRICS,nm.cbSize,&nm,0);
	logfont = nm.lfMenuFont;
	fontMenu.CreateFontIndirect (&logfont);

	CWnd *pWnd = AfxGetMainWnd();  
	CDC *pDC = pWnd->GetDC();
	CFont *pFont = pDC->SelectObject(&fontMenu);

	numitems = GetMenuItemCount();
	maxlength = -1;
	for(i=0;i<numitems;++i)
	{
		string = m_MenuList[i]->GetString();
		j = string.Find((char)9); //菜单文本中的"\t"
		newstring.Empty();
		if(j!=-1) newstring = string.Left(j);
		else newstring = string;
		newstring += _T(" ");
		LPCTSTR lpstrText = (LPCTSTR)newstring;
		textSize = pDC->GetTextExtent(lpstrText,_tcslen(lpstrText));
		if(textSize.cx > maxlength) maxlength = textSize.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);
			textSize = pDC->GetTextExtent(lpstrText,_tcslen(lpstrText));
			while(textSize.cx < maxlength)
			{
				newstring += _T(' ');
				LPCTSTR lpstrText = (LPCTSTR)(newstring);
				textSize = pDC->GetTextExtent(lpstrText,_tcslen(lpstrText));
			}
			newstring += string.Mid(j);
#ifdef UNICODE		
			m_MenuList[i]->SetWideString(newstring);
#else
			m_MenuList[i]->SetAnsiString(newstring);
#endif
		}
	}
	pDC->SelectObject (pFont);
	AfxGetMainWnd()->ReleaseDC(pDC);
	fontMenu.DeleteObject();
}

void CMenuExt::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;
		}
	}
}

BOOL CMenuExt::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;
		CMenuExt* pMenu = FindMenuOption(id,uiLoc);
		if(NULL!=pMenu) returnflag = pMenu->GetMenuText(uiLoc,string);
	}
	return(returnflag);
}


void CMenuExt::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 CMenuExt::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);
}

CMenuExtData *CMenuExt::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 CMenuExt::InitializeMenuList(int value)
{
	for(int i=0;i<=m_MenuList.GetUpperBound();++i)
		m_MenuList[i]->syncflag = value;
}

void CMenuExt::DeleteMenuList(void)
{
	for(int i=0;i<=m_MenuList.GetUpperBound();++i)
	{
		if(!m_MenuList[i]->syncflag)
		{
			delete m_MenuList[i];
		}
	}
}

void CMenuExt::SynchronizeMenu()
{
	CTypedPtrArray<CPtrArray, CMenuExtData*> temp;
	CMenuExtData *mdata = NULL;
	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);
#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(""));
			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);
#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 CMenuExt::UpdateMenu(CMenu *pmenu)
{
#ifdef _CPPRTTI 
	CMenuExt *psubmenu = dynamic_cast<CMenuExt *>(pmenu);
#else
	CMenuExt *psubmenu = (CMenuExt *)pmenu;
#endif
	if(psubmenu)psubmenu->SynchronizeMenu();
}

LRESULT CMenuExt::FindKeyboardShortcut(UINT nChar, UINT nFlags, CMenu *pMenu)
{
	CMenuExt *pMenuExt = (CMenuExt *)pMenu;
	if(pMenuExt && nFlags&MF_POPUP)
	{
		CString key(_T('&'),2); //为了Unicode正确
		key.SetAt(1,(TCHAR)nChar);
		key.MakeLower();
		CString MenuText;
		int MenuSize = (int)pMenuExt->GetMenuItemCount();
		if(MenuSize != pMenuExt->m_MenuList.GetUpperBound()+1)
			pMenuExt->SynchronizeMenu(); //同步菜单项
		for(int i=0;i<MenuSize;++i)
		{
			if(pMenuExt->GetMenuText(i,MenuText))
			{
				MenuText.MakeLower();
				if(MenuText.Find(key) >= 0) return MAKELRESULT(i,2);
			}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -