?? menuex.cpp
字號:
// 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 + -