📄 bcgppopupmenubar.cpp
字号:
//****************************************************************************************
void CBCGPPopupMenuBar::DrawDragMarker (CDC* pDC)
{
if (m_bPaletteMode)
{
return;
}
CPen* pOldPen = (CPen*) pDC->SelectObject (&m_penDrag);
for (int i = 0; i < 2; i ++)
{
pDC->MoveTo (m_rectDrag.left, m_rectDrag.top + m_rectDrag.Height () / 2 + i - 1);
pDC->LineTo (m_rectDrag.right, m_rectDrag.top + m_rectDrag.Height () / 2 + i - 1);
pDC->MoveTo (m_rectDrag.left + i, m_rectDrag.top + i);
pDC->LineTo (m_rectDrag.left + i, m_rectDrag.bottom - i);
pDC->MoveTo (m_rectDrag.right - i - 1, m_rectDrag.top + i);
pDC->LineTo (m_rectDrag.right - i - 1, m_rectDrag.bottom - i);
}
pDC->SelectObject (pOldPen);
}
//********************************************************************************
int CBCGPPopupMenuBar::FindDropIndex (const CPoint p, CRect& rectDrag) const
{
if (m_bPaletteMode)
{
return -1;
}
const int iCursorSize = 6;
GetClientRect (&rectDrag);
if (m_Buttons.IsEmpty ())
{
rectDrag.bottom = rectDrag.top + iCursorSize;
return 0;
}
CPoint point = p;
if (point.y < 0)
{
point.y = 0;
}
int iDragButton = -1;
int iIndex = 0;
for (POSITION pos = m_Buttons.GetHeadPosition (); pos != NULL; iIndex ++)
{
CBCGPToolbarButton* pButton = (CBCGPToolbarButton*) m_Buttons.GetNext (pos);
ASSERT (pButton != NULL);
CRect rect = pButton->Rect ();
if (point.y < rect.top)
{
iDragButton = iIndex;
rectDrag.top = rect.top;
break;
}
else if (point.y <= rect.bottom)
{
rectDrag = rect;
if (point.y - rect.top > rect.bottom - point.y)
{
iDragButton = iIndex + 1;
rectDrag.top = rectDrag.bottom;
}
else
{
iDragButton = iIndex;
rectDrag.top = rect.top;
}
break;
}
}
if (iDragButton == -1)
{
rectDrag.top = rectDrag.bottom - iCursorSize;
iDragButton = iIndex;
}
rectDrag.bottom = rectDrag.top + iCursorSize;
rectDrag.OffsetRect (0, -iCursorSize / 2);
return iDragButton;
}
//***************************************************************************************
CBCGPToolbarButton* CBCGPPopupMenuBar::CreateDroppedButton (COleDataObject* pDataObject)
{
CBCGPToolbarButton* pButton = CBCGPToolbarButton::CreateFromOleData (pDataObject);
ASSERT (pButton != NULL);
CBCGPToolbarMenuButton* pMenuButton =
DYNAMIC_DOWNCAST (CBCGPToolbarMenuButton, pButton);
if (pMenuButton == NULL)
{
pMenuButton = new CBCGPToolbarMenuButton (
pButton->m_nID, NULL,
pButton->IsLocked () ? -1 : pButton->GetImage (),
pButton->m_strText,
pButton->m_bUserButton);
ASSERT (pMenuButton != NULL);
pMenuButton->m_bText = TRUE;
pMenuButton->m_bImage = !pButton->IsLocked ();
BOOL bRes = pButton->ExportToMenuButton (*pMenuButton);
delete pButton;
if (!bRes || pMenuButton->m_strText.IsEmpty ())
{
delete pMenuButton;
return NULL;
}
}
return pMenuButton;
}
//****************************************************************************************
BOOL CBCGPPopupMenuBar::ImportFromMenu (HMENU hMenu, BOOL bShowAllCommands)
{
RemoveAllButtons ();
m_bAreAllCommandsShown = TRUE;
m_HiddenItemsAccel.RemoveAll ();
if (hMenu == NULL)
{
return FALSE;
}
CMenu* pMenu = CMenu::FromHandle (hMenu);
if (pMenu == NULL)
{
return FALSE;
}
//***** MSI START *****
// We need to update the menu items first (OnUpdate*** for the target message
// window need to be invoked:
CWnd* pMsgWindow = BCGCBProGetTopLevelFrame (this);
if (pMsgWindow == NULL)
{
pMsgWindow = AfxGetMainWnd ();
}
if (GetSafeHwnd () != NULL)
{
CBCGPPopupMenu* pParentMenu = DYNAMIC_DOWNCAST (CBCGPPopupMenu, GetParent ());
if (pParentMenu != NULL && pParentMenu->GetMessageWnd () != NULL)
{
pMsgWindow = pParentMenu->GetMessageWnd ();
}
}
if (pMsgWindow != NULL)
{
WPARAM theMenu = WPARAM(hMenu);
LPARAM theItem = MAKELPARAM(m_iOffset, 0);
pMsgWindow->SendMessage(WM_INITMENUPOPUP, theMenu, theItem);
}
//***** MSI END ******
int iCount = (int) pMenu->GetMenuItemCount ();
BOOL bPrevWasSeparator = FALSE;
BOOL bFirstItem = TRUE;
int nPaletteColumns = max (1, m_bPaletteMode ?
iCount / m_bPaletteRows : 0);
for (int i = 0; i < iCount; i ++)
{
UINT uiTearOffId = 0;
HMENU hSubMenu = NULL;
CString strText;
pMenu->GetMenuString (i, strText, MF_BYPOSITION);
MENUITEMINFO mii;
mii.cbSize = sizeof(mii);
mii.cch = 0;
mii.fMask = MIIM_TYPE | MIIM_SUBMENU | MIIM_ID | MIIM_STATE;
pMenu->GetMenuItemInfo(i, &mii, TRUE);
UINT uiCmd = mii.wID;
UINT uiState = pMenu->GetMenuState (i, MF_BYPOSITION);
if (mii.fType == MFT_SEPARATOR)
{
if (!bPrevWasSeparator && !bFirstItem && i != iCount - 1 &&
!m_bPaletteMode)
{
InsertSeparator ();
bFirstItem = FALSE;
bPrevWasSeparator = TRUE;
}
}
else
{
if (mii.hSubMenu != NULL)
{
uiCmd = (UINT)-1; // force value (needed due to Windows bug)
hSubMenu = mii.hSubMenu;
ASSERT (hSubMenu != NULL);
if (g_pTearOffMenuManager != NULL)
{
uiTearOffId = g_pTearOffMenuManager->Parse (strText);
}
}
if (m_bTrackMode || bShowAllCommands ||
CBCGPMenuBar::IsShowAllCommands () ||
!CBCGPToolBar::IsCommandRarelyUsed (uiCmd) ||
m_bPaletteMode)
{
int iIndex = -1;
if (m_bPaletteMode)
{
CBCGPToolbarButton item (uiCmd,
CMD_MGR.GetCmdImage (uiCmd, FALSE),
strText);
if (i > 0 && (i % nPaletteColumns) == 0)
{
item.m_bWrap = TRUE;
}
iIndex = InsertButton (item);
}
else
{
CBCGPToolbarMenuButton item (uiCmd, hSubMenu,
-1, strText);
item.m_bText = TRUE;
item.m_bImage = FALSE;
if (CMD_MGR.GetCmdImage (uiCmd, FALSE) == -1)
{
item.m_bUserButton = TRUE;
}
iIndex = InsertButton (item);
}
if (iIndex >= 0)
{
CBCGPToolbarButton* pButton = GetButton (iIndex);
ASSERT (pButton != NULL);
pButton->m_bImage = (pButton->GetImage () >= 0);
if (g_pUserToolsManager == NULL ||
!g_pUserToolsManager->IsUserToolCmd (uiCmd))
{
if ((uiState & MF_DISABLED) || (uiState & MF_GRAYED))
{
pButton->m_nStyle |= TBBS_DISABLED;
}
}
CBCGPToolbarMenuButton* pMenuButton =
DYNAMIC_DOWNCAST (CBCGPToolbarMenuButton, pButton);
if (pMenuButton != NULL)
{
pMenuButton->SetTearOff (uiTearOffId);
}
if (uiState & MF_CHECKED)
{
pButton->m_nStyle |= TBBS_CHECKED;
}
//support for the menu with breaks:
if (mii.fType & MF_MENUBREAK)
{
pButton->m_nStyle |= TBBS_BREAK;
}
///////////////
}
bPrevWasSeparator = FALSE;
bFirstItem = FALSE;
}
else if (CBCGPToolBar::IsCommandRarelyUsed (uiCmd) &&
CBCGPToolBar::IsCommandPermitted (uiCmd))
{
m_bAreAllCommandsShown = FALSE;
int iAmpOffset = strText.Find (_T('&'));
if (iAmpOffset >= 0 && iAmpOffset < strText.GetLength () - 1)
{
TCHAR szChar[2] = {strText.GetAt (iAmpOffset + 1), '\0'};
CharUpper (szChar);
UINT uiHotKey = (UINT) (szChar [0]);
m_HiddenItemsAccel.SetAt (uiHotKey, uiCmd);
}
}
}
}
m_uiDefaultMenuCmdId = ::GetMenuDefaultItem (hMenu, FALSE, GMDI_USEDISABLED);
return TRUE;
}
//****************************************************************************************
HMENU CBCGPPopupMenuBar::ExportToMenu () const
{
CMenu menu;
menu.CreatePopupMenu ();
for (POSITION pos = m_Buttons.GetHeadPosition (); pos != NULL;)
{
CBCGPToolbarButton* pButton = (CBCGPToolbarButton*) m_Buttons.GetNext (pos);
ASSERT (pButton != NULL);
if (pButton->m_nStyle & TBBS_SEPARATOR)
{
menu.AppendMenu (MF_SEPARATOR);
continue;
}
if (!pButton->IsKindOf (RUNTIME_CLASS (CBCGPToolbarMenuButton)))
{
continue;
}
CBCGPToolbarMenuButton* pMenuButton = (CBCGPToolbarMenuButton*) pButton;
HMENU hPopupMenu = pMenuButton->CreateMenu ();
if (hPopupMenu != NULL)
{
UINT uiStyle = (MF_STRING | MF_POPUP);
//support for the menu with breaks:
if (pButton->m_nStyle & TBBS_BREAK)
{
uiStyle |= MF_MENUBREAK;
}
//////////////////////
CString strText = pMenuButton->m_strText;
if (pMenuButton->m_uiTearOffBarID != 0 && g_pTearOffMenuManager != NULL)
{
g_pTearOffMenuManager->Build (pMenuButton->m_uiTearOffBarID, strText);
}
menu.AppendMenu (uiStyle, (UINT_PTR)hPopupMenu, strText);
//--------------------------------------------------------
// This is incompatibility between Windows 95 and
// NT API! (IMHO). CMenu::AppendMenu with MF_POPUP flag
// COPIES sub-menu resource under the Win NT and
// MOVES sub-menu under Win 95/98 and 2000!
//--------------------------------------------------------
if ( globalData.bIsWindowsNT4 )
{
::DestroyMenu (hPopupMenu);
}
}
else
{
menu.AppendMenu (MF_STRING, pMenuButton->m_nID, pMenuButton->m_strText);
}
}
HMENU hMenu = menu.Detach();
::SetMenuDefaultItem (hMenu, m_uiDefaultMenuCmdId, FALSE);
return hMenu;
}
//***************************************************************************************
void CBCGPPopupMenuBar::OnChangeHot (int iHot)
{
ASSERT_VALID (this);
ASSERT (::IsWindow (GetSafeHwnd ()));
if (iHot == -1)
{
CPoint ptCursor;
::GetCursorPos (&ptCursor);
ScreenToClient (&ptCursor);
if (HitTest (ptCursor) == m_iHot)
{
m_iHighlighted = m_iHot;
return;
}
}
CBCGPToolbarMenuButton* pCurrPopupMenu = NULL;
for (POSITION pos = m_Buttons.GetHeadPosition (); pos != NULL;)
{
CBCGPToolbarButton* pButton = (CBCGPToolbarButton*) m_Buttons.GetNext (pos);
ASSERT_VALID (pButton);
CBCGPToolbarMenuButton* pMenuButton =
DYNAMIC_DOWNCAST (CBCGPToolbarMenuButton, pButton);
if (pMenuButton != NULL && pMenuButton->IsDroppedDown ())
{
pCurrPopupMenu = pMenuButton;
break;
}
}
CBCGPToolbarMenuButton* pMenuButton = NULL;
if (iHot >= 0)
{
CBCGPToolbarButton* pButton = GetButton (iHot);
if (pButton == NULL)
{
ASSERT (FALSE);
return;
}
else
{
ASSERT_VALID (pButton);
pMenuButton = DYNAMIC_DOWNCAST (CBCGPToolbarMenuButton, pButton);
}
}
if (pMenuButton != pCurrPopupMenu)
{
CBCGPPopupMenu* pParentMenu = DYNAMIC_DOWNCAST (CBCGPPopupMenu, GetParent ());
if (pCurrPopupMenu != NULL)
{
const MSG* pMsg = GetCurrentMessage ();
if (CBCGPToolBar::IsCustomizeMode () ||
(pMsg != NULL && pMsg->message == WM_KEYDOWN))
{
KillTimer (uiRemovePopupTimerEvent);
m_pDelayedClosePopupMenuButton = NULL;
pCurrPopupMenu->OnCancelMode ();
if (pParentMenu != NULL)
{
CBCGPPopupMenu::ActivatePopupMenu (
BCGCBProGetTopLevelFrame (this), pParentMenu);
}
}
else
{
m_pDelayedClosePopupMenuButton = pCurrPopupMenu;
m_pDelayedClosePopupMenuButton->m_bToBeClosed = TRUE;
SetTimer (uiRemovePopupTimerEvent,
max (0, m_uiPopupTimerDelay - 1), NULL);
InvalidateRect (pCurrPopupMenu->Rect ());
UpdateWindow ();
}
}
if (pMenuButton != NULL &&
(pMenuButton->m_nID == (UINT) -1 || pMenuButton->m_bDrawDownArrow))
{
pMenuButton->OnClick (this);
}
// Maybe, this menu will be closed by the parent menu bar timer proc.?
CBCGPPopupMenuBar* pParentBar = NULL;
if (pParentMenu != NULL && pParentMenu->GetParentPopupMenu () != NULL &&
(pParentBar = pParentMenu->GetParentPopupMenu ()->GetMenuBar ()) != NULL &&
pParentBar->m_pDelayedClosePopupMenuButton == pParentMenu->GetParentButton ())
{
pParentBar->RestoreDelayedSubMenu ();
}
}
else if (pMenuButton != NULL &&
pMenuButton == m_pDelayedClosePopupMenuButton)
{
m_pDelayedClosePopupMenuButton->m_bToBeClosed = FALSE;
m_pDelayedClosePopupMenuButton = NULL;
KillTimer (uiRemovePopupTimerEvent);
}
m_iHot = iHot;
}
//****************************************************************************************
void CBCGPPopupMenuBar::OnDestroy()
{
KillTimer (uiPopupTimerEvent);
KillTimer (uiRemovePopupTimerEvent);
m_pDelayedPopupMenuButton = NULL;
m_pDelayedClosePopupMenuButton = NULL;
for (POSITION pos = m_Buttons.GetHeadPosition (); pos != NULL;)
{
CBCGPToolbarButton* pButton = (CBCGPToolbarButton*) m_Buttons.GetNext (pos);
ASSERT_VALID (pButton);
CBCGPToolbarMenuButton* pMenuButton =
DYNAMIC_DOWNCAST (CBCGPToolbarMenuButton, pButton);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -