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

📄 menuex.cpp

📁 Visual C++开发使用编程200例——Windows界面编程
💻 CPP
📖 第 1 页 / 共 4 页
字号:
    // Obtain Flags and (if necessary), the ID...
    memcpy(&dwFlags, pTp, sizeof(WORD));pTp+=sizeof(WORD);// Obtain Flags
    if(!(dwFlags & MF_POPUP)) //This menu isn't a POPUP (it hasn't any child)
	{
      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); 
      CMenuEx* pSubMenu = new CMenuEx(m_bDrawGrayed,m_bShowLastArrow);
      pSubMenu->m_unselectcheck=m_unselectcheck;
      pSubMenu->m_selectcheck=m_selectcheck;
      pSubMenu->checkmaps=checkmaps;
      pSubMenu->checkmapsshare=TRUE;
      pSubMenu->CMenu::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)CMenu::GetMenuItemCount();++i)
  {
    CString str=m_MenuList[i]->GetString();

    if(CMenu::GetSubMenu(i))
	{
      m_MenuList[i]->nFlags=MF_POPUP|MF_BYPOSITION;
      ModifyMenu(i,MF_POPUP|MF_BYPOSITION,(UINT)CMenu::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);
    }
  }
  AppendLastArrow();
  PostBuiltMenu(this);
 
  return(TRUE);
}

BOOL CMenuEx::PreLoadMenu(int nResource)
{
	return(CMenuEx::PreLoadMenu(MAKEINTRESOURCE(nResource)));
}

BOOL CMenuEx::DeleteMenu(UINT nPosition, UINT nFlags)
{
	int n=m_MenuList.GetSize();
	UINT pos=nPosition;
	int i;
	if(nFlags==MF_BYCOMMAND)
	{
		for(i=0;i<n;i++)
			if (GetMenuItemID(i)==(signed)nPosition) {pos=i;break;}
		if(i==n || GetMenuItemID(i)!=(signed)nPosition) return FALSE;
	}
	CMenuExData* pData=m_MenuList.ElementAt(pos);
	delete pData;
	for(i=pos;i<n-1;i++)
		m_MenuList.SetAt(i,m_MenuList.ElementAt(i+1));
	m_MenuList.SetAt(n-1,NULL);
	m_MenuList.SetSize(n-1);
	int j=-1;
	int nSub=-1;
	n=m_SubMenus.GetSize();
	for(i=0;i<n;i++)
	{
		if (m_SubMenus.ElementAt(i)==CMenu::GetSubMenu(pos))
		 {j=i;break;}
	}
	if(j>=0)
	{
		CMenuEx* pMenu=m_SubMenus.ElementAt(j);
		delete pMenu;
		for(i=j;i<n-1;i++)
			m_SubMenus.SetAt(i,m_SubMenus.ElementAt(i+1));
		m_SubMenus.SetAt(n-1,NULL);
		m_SubMenus.SetSize(n-1);
	}
	BOOL b=CMenu::DeleteMenu(nPosition, nFlags);
	return b;
}

CMenuEx* CMenuEx::GetSubMenu(UINT iPos)
{
	CMenuEx* pMenu=(CMenuEx*) CMenu::GetSubMenu(iPos);
	if(pMenu!=NULL) ASSERT(pMenu->IsKindOf(RUNTIME_CLASS(CMenuEx)));
	return pMenu;
}

BOOL CMenuEx::AppendMenu(UINT nFlags, UINT nIDNewItem, LPCTSTR lpszNewItem, UINT nFlagsEx)
{
	nFlags|=MF_OWNERDRAW;
	BOOL bReturn;
	DeleteMenu(m_MenuList.GetSize()-1,MF_BYPOSITION);
	bReturn=AppendODMenu(lpszNewItem,nFlags,nIDNewItem,-1,nFlagsEx);
	AppendLastArrow();
	return bReturn;
}


int CMenuEx::GetFlagsEx(UINT nPos)
{
  CMenuExData* pData=m_MenuList.ElementAt(nPos);
  if (pData)
  {
	return pData->nFlagsEx;
  }
  return 0;
}

int CMenuEx::GetFlags(UINT nPos)
{
  CMenuExData* pData=m_MenuList.ElementAt(nPos);
  if (pData)
  {
	return pData->nFlags;
  }
  return 0;
}

int CMenuEx::GetMenuItemID(UINT nPos)
{
  CMenuExData* pData=m_MenuList.ElementAt(nPos);
  if (pData)
  {
	return pData->nID;
  }
  return 0;
}

BOOL CMenuEx::ModifyODSeparator(UINT nPos, int nFlagsEx)
{
	if (nPos<0) return FALSE;
	CMenuExData* pData=m_MenuList.ElementAt(nPos);
	pData->nFlagsEx=nFlagsEx;
	return TRUE;
}

BOOL CMenuEx::CheckIfGrayed(CMenuEx *pMenu)
{
  int i,n;
  BOOL bGrayed;
  if(!pMenu) return TRUE;
  n=pMenu->m_MenuList.GetSize();
  for (i=0;i<n;i++)
  {
	CMenuExData* pData=pMenu->m_MenuList.ElementAt(i);
	if (pData->nFlags&MF_POPUP)
		bGrayed=CheckIfGrayed(pMenu->GetSubMenu(i));
	else 
		bGrayed=pData->nFlagsEx&MF_DRAWGRAYED;
	if(!bGrayed) return FALSE;
  }
  return TRUE;
}

int CMenuEx::FindMenuPos(CMenuExData *pData,CMenuEx* &pFather)
{
  int p;
  CMenuEx* pTmp;
  for(int i=0;i<=pFather->m_MenuList.GetUpperBound();++i)
  {
    if(pFather->m_MenuList[i]==pData) return i;
	if(pFather->m_MenuList[i]->nFlags&MF_POPUP)
	{
		pTmp=pFather->GetSubMenu(i);
		p=FindMenuPos(pData,pTmp);
		if(p>=0) 
		{
			pFather=pTmp;
			return p;
		}
	}
  }
  return -1;
}

void CMenuEx::PostBuiltMenu(CMenuEx *pMenu)
{
  CMenuEx* pSubMenu;
  for(int i=0;i<(int)pMenu->GetMenuItemCount();++i)
  {
	pSubMenu=pMenu->GetSubMenu(i);
    if(pSubMenu)
	{
	  pSubMenu->m_bShowLastArrow=m_bShowLastArrow;
	  pSubMenu->AppendLastArrow();
	  PostBuiltMenu(pSubMenu);
    }
  }
}

void CMenuEx::DrawLastArrow(CDC *pDC, int x, int y, COLORREF color)
{
  pDC->SetPixel(x,y,color);
  pDC->SetPixel(x+4,y,color);

  pDC->SetPixel(x,y+1,color);
  pDC->SetPixel(x+1,y+1,color);
  pDC->SetPixel(x+3,y+1,color);
  pDC->SetPixel(x+4,y+1,color);

  pDC->SetPixel(x+1,y+2,color);
  pDC->SetPixel(x+2,y+2,color);
  pDC->SetPixel(x+3,y+2,color);

  pDC->SetPixel(x+2,y+3,color);

  pDC->SetPixel(x,y+5,color);
  pDC->SetPixel(x+4,y+5,color);

  pDC->SetPixel(x,y+6,color);
  pDC->SetPixel(x+1,y+6,color);
  pDC->SetPixel(x+3,y+6,color);
  pDC->SetPixel(x+4,y+6,color);

  pDC->SetPixel(x+1,y+7,color);
  pDC->SetPixel(x+2,y+7,color);
  pDC->SetPixel(x+3,y+7,color);

  pDC->SetPixel(x+2,y+8,color);
}

BOOL CMenuEx::CreateMenu()
{
  BOOL m_bReturn=CMenu::CreateMenu();
  return m_bReturn;
}

BOOL CMenuEx::CreatePopupMenu()
{
  BOOL bReturn=CMenu::CreatePopupMenu();
  AppendLastArrow();
  return bReturn;
}

BOOL CMenuEx::ModifyFlagsEx(int nID, int nFlagsEx, BOOL byPos)
{
  int nLoc;
  CMenuExData *mdata;

  CMenuEx *psubmenu;
  if (byPos)
  {
	  nLoc=nID;
	  psubmenu=this;
  }
  else
  {
	  // Find the old CMenuExData structure:
	  psubmenu = FindMenuOption(nID,nLoc);
  }
  if(psubmenu && nLoc>=0)
	  mdata = psubmenu->m_MenuList[nLoc];
  else{
  // Create a new CMenuExData structure:
    mdata = new CMenuExData;
    m_MenuList.Add(mdata);
  }
  ASSERT(mdata);
  mdata->nFlags = MF_BYCOMMAND | MF_OWNERDRAW;
  mdata->nID = nID;
  if(nFlagsEx>=0) mdata->nFlagsEx=nFlagsEx;
  return (CMenu::ModifyMenu(nID,mdata->nFlags,nID,(LPCTSTR)mdata));
}

LRESULT CMenuEx::TrapWindowProc(UINT nMsg, WPARAM wParam, LPARAM lParam)
{
	return TRUE;
}

void CMenuEx::EnableGrayedDraw(BOOL bEnable, BOOL bForce)
{
	if (!m_bEnableArrows) return;
	if (!bForce)
		if(m_bDrawGrayed==bEnable) return;
	m_bDrawGrayed=bEnable;
	if(m_bDrawGrayed)
	{
		RemoveLastArrows(this);
	}
	else
	{
		InsertLastArrows(this);
	}
}

void CMenuEx::RemoveLastArrows(CMenuEx *pMenu)
{
	CMenuExData* pData;
	m_bShowLastArrow=FALSE;
	if(!pMenu) return;
	pMenu->m_bDrawGrayed=m_bDrawGrayed;
	pMenu->m_bDrawOnlyGray=m_bDrawOnlyGray;
	int i,m,n;
	n=((CMenu*)pMenu)->GetMenuItemCount();
	m=n-1;
	UINT fex=pMenu->GetFlagsEx(m);
	if (fex&MF_LASTARROW)
	{
		pMenu->DeleteMenu(m, MF_BYPOSITION);
		pMenu->AppendLastArrow();
	}
	else
	{
		pMenu->SetFlagsEx(m, MF_LASTARROW|MF_DRAWGRAYED|0xFFFF);
	}
	for(i=0;i<n;i++)
	{
		pData=pMenu->m_MenuList[i];
		CMenu* ptMenu=((CMenu*)pMenu)->CMenu::GetSubMenu(i);
		if (!ptMenu)
		{
			::DeleteMenu(pMenu->m_hMenu,i, MF_BYPOSITION);
			::InsertMenu(pMenu->m_hMenu,i, MF_BYPOSITION|pData->nFlags|MF_OWNERDRAW,pData->nID,(LPCTSTR) pData);
		}
		else
		{
			RemoveLastArrows((CMenuEx*)ptMenu);
			HMENU hMenu=ptMenu->m_hMenu;
			::RemoveMenu(pMenu->m_hMenu,i, MF_BYPOSITION);
			::InsertMenu(pMenu->m_hMenu,i, MF_BYPOSITION|MF_POPUP|MF_OWNERDRAW,(UINT)hMenu,(LPCTSTR) pData);
		}
	}
}

void CMenuEx::InsertLastArrows(CMenuEx *pMenu)
{
	CMenuExData* pData;
	m_bShowLastArrow=TRUE;
	if(!pMenu) return;
	int i;
	UINT pos=((CMenu*)pMenu)->GetMenuItemCount();
	pMenu->m_bDrawGrayed=m_bDrawGrayed;
	pMenu->m_bDrawOnlyGray=m_bDrawOnlyGray;
	UINT fex=pMenu->GetFlagsEx(pos-1);
	if (fex&MF_LASTARROW)
	{
		pMenu->DeleteMenu(pos-1, MF_BYPOSITION);
		pMenu->AppendLastArrow();
	}
	else
	{
		pMenu->AppendLastArrow();
	}
	for(i=(signed)pos-1;i>=0;i--)
	{
		pData=pMenu->m_MenuList[i];
		CMenu* ptMenu=((CMenu*)pMenu)->CMenu::GetSubMenu(i);
		if (!ptMenu)
		{
			::DeleteMenu(pMenu->m_hMenu,i, MF_BYPOSITION);
			::InsertMenu(pMenu->m_hMenu,i, MF_BYPOSITION|pData->nFlags|MF_OWNERDRAW,pData->nID,(LPCTSTR) pData);
		}
		else
		{
			InsertLastArrows(pMenu->GetSubMenu(i));
			HMENU hMenu=ptMenu->m_hMenu;
			::RemoveMenu(pMenu->m_hMenu,i, MF_BYPOSITION);
			::InsertMenu(pMenu->m_hMenu,i, MF_BYPOSITION|MF_POPUP|MF_OWNERDRAW,(UINT)hMenu,(LPCTSTR) pData);
		}
	}
}

int CMenuEx::FindMenuPos(CMenuEx *pMenu, CMenuEx *&pFather)
{
  int p,n;
  CMenuEx* pTmp;
  n=((CMenu*)pFather)->GetMenuItemCount();
  for(int i=0;i<n;++i)
  {
    if(pFather->GetSubMenu(i)==pMenu) 
	{
		return i;
	}
	if(pFather->m_MenuList[i]->nFlags&MF_POPUP)
	{
		pTmp=pFather->GetSubMenu(i);
		p=FindMenuPos(pMenu,pTmp);
		if(p>=0) 
		{
			pFather=pTmp;
			return p;
		}
	}
  }
  return -1;
}

int CMenuEx::SetFlagsEx(UINT nPos,int nFlagsEx)
{
  int r;
  CMenuExData* pData=m_MenuList.ElementAt(nPos);
  if (pData)
  {
	r=pData->nFlagsEx;
	pData->nFlagsEx=nFlagsEx;
  }
  return r;
}

#ifndef ID_SHOWFULL
#define ID_SHOWFULL -1
#endif

BOOL CMenuEx::AppendLastArrow()
{
	return AppendODMenu(_T("----V----"),MF_STRING|MF_OWNERDRAW,ID_SHOWFULL,-1,MF_LASTARROW);
}

void CMenuEx::UpdateGrayedOnly(CMenuEx *pMenu, BOOL b)
{
	pMenu->m_bDrawOnlyGray=b;
	int i,n;
	n=pMenu->GetMenuItemCount();
	for(i=0;i<n;i++)
	{
		CMenuEx* ptMenu=pMenu->GetSubMenu(i);
		if (ptMenu)
		{
			UpdateGrayedOnly(ptMenu,b);
		}
	}
}

void*& CMenuEx::GetExtraDataPtr(UINT nPos)
{
  CMenuExData* pData=m_MenuList.ElementAt(nPos);
  ASSERT (pData!=NULL);
  return pData->m_pExtraData;
}

BOOL CMenuEx::InsertMenu( UINT nPosition, UINT nFlags, UINT nIDNewItem, LPCTSTR lpszNewItem, UINT nFlagsEx)
{
	nFlags|=MF_OWNERDRAW;
	BOOL bReturn;
	DeleteMenu(m_MenuList.GetSize()-1,MF_BYPOSITION);
	// Add the MF_OWNERDRAW flag if not specified:
	if (!lpszNewItem)lpszNewItem=_T("");
	if(!nIDNewItem)nFlags=MF_SEPARATOR|MF_OWNERDRAW;
  
	CMenuExData *mtdata,*mdata2, *mdata = new CMenuExData;
#ifndef UNICODE
	mdata->SetAnsiString(lpszNewItem);    //SK: modified for dynamic allocation
#else
	mdata->SetWideString(lpszNewItem);    //SK: modified for dynamic allocation
#endif
	mdata->menuIconNormal = -1;
	mdata->xoffset=-1;
	mdata->nFlags = nFlags;
	mdata->nFlagsEx=nFlagsEx;
	mdata->nID = nIDNewItem;
	mdata2=mdata;
	m_MenuList.Add(mdata);
	UINT n=m_MenuList.GetSize();
	n--;
	mtdata=m_MenuList[n];
	for (UINT i=nPosition;i<n;i++)
	{
		mdata=m_MenuList[i];
		m_MenuList[i]=mtdata;
		mtdata=mdata;
	}
	m_MenuList[n]=mtdata;
    bReturn=CMenu::InsertMenu(nPosition, nFlags, nIDNewItem, (LPCTSTR)mdata2);
	AppendLastArrow();
	return bReturn;
}

⌨️ 快捷键说明

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