bcgpopupmenubar.cpp

来自「用bcg库编写的java IDE 源码」· C++ 代码 · 共 1,423 行 · 第 1/3 页

CPP
1,423
字号
			pButton->m_bUserButton);
		ASSERT (pMenuButton != NULL);

		pMenuButton->m_bText = TRUE;
		pMenuButton->m_bImage = TRUE;

		//-----------------------------------------------------
		// Text may be undefined, bring it from the tooltip :-(
		//-----------------------------------------------------
		if ((pMenuButton->m_strText.IsEmpty () || 
			pButton->IsKindOf (RUNTIME_CLASS (CBCGToolbarComboBoxButton)))
				&& pMenuButton->m_nID != 0)
		{
			CString strMessage;
			int iOffset;
			if (strMessage.LoadString (pMenuButton->m_nID) &&
				(iOffset = strMessage.Find (_T('\n'))) != -1)
			{
				pMenuButton->m_strText = strMessage.Mid (iOffset + 1);
			}
		}

		delete pButton;
		
		if (pMenuButton->m_strText.IsEmpty ())
		{
			delete pMenuButton;
			return NULL;
		}
	}

	return pMenuButton;
}
//****************************************************************************************
BOOL CBCGPopupMenuBar::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 *****
	// By Mike Harvey (MSI)
    CFrameWnd* pMainWindow = DYNAMIC_DOWNCAST (CFrameWnd, AfxGetMainWnd ());
    if (pMainWindow != NULL)
	{
		WPARAM theMenu = WPARAM(hMenu);
		LPARAM theItem = MAKELPARAM(m_iOffset, 0);
		pMainWindow->SendMessage(WM_INITMENUPOPUP, theMenu, theItem);
	}
	//***** MSI END *****

	int iCount = (int) pMenu->GetMenuItemCount ();
	BOOL bPrevWasSeparator = FALSE;
	BOOL bFirstItem = TRUE;

	for (int i = 0; i < iCount; i ++)
	{
		UINT uiCmd = pMenu->GetMenuItemID (i);
		UINT uiState = pMenu->GetMenuState (i, MF_BYPOSITION);

		HMENU hSubMenu = NULL;

		CString strText;
		pMenu->GetMenuString (i, strText, MF_BYPOSITION);

		switch (uiCmd)
		{
		case 0:
			if (!bPrevWasSeparator && !bFirstItem && i != iCount - 1)
			{
				InsertSeparator ();
				bFirstItem = FALSE;
				bPrevWasSeparator = TRUE;
			}
			break;

		case -1:
			hSubMenu = pMenu->GetSubMenu (i)->GetSafeHmenu ();
			ASSERT (hSubMenu != NULL);

		default:
			if (bShowAllCommands ||
				CBCGMenuBar::IsShowAllCommands () ||
				!CBCGToolBar::IsCommandRarelyUsed (uiCmd))
			{
				CBCGToolbarMenuButton item (uiCmd, hSubMenu,
											-1, strText);
				item.m_bText = TRUE;
				item.m_bImage = FALSE;

				if (CMD_MGR.GetCmdImage (uiCmd, FALSE) == -1)
				{
					item.m_bUserButton = TRUE;
				}

				int iIndex = InsertButton (item);
				if (iIndex >= 0)
				{
					CBCGToolbarButton* pButton = GetButton (iIndex);
					ASSERT (pButton != NULL);

					pButton->m_bImage = (pButton->GetImage () >= 0);

					if ((uiState & MF_DISABLED) || (uiState & MF_GRAYED))
					{
						pButton->m_nStyle |= TBBS_DISABLED;
					}

					if (uiState & MF_CHECKED)
					{
						pButton->m_nStyle |= TBBS_CHECKED;
					}

					/// By Guy Hachlili - support for the menu with breaks:
					if (uiState & MF_MENUBREAK)
					{
						pButton->m_nStyle |= TBBS_BREAK;
					}
					///////////////
				}

				bPrevWasSeparator = FALSE;
				bFirstItem = FALSE;
			}
			else if (CBCGToolBar::IsCommandRarelyUsed (uiCmd) &&
				CBCGToolBar::IsCommandPermitted (uiCmd))
			{
				m_bAreAllCommandsShown = FALSE;
				
				int iAmpOffset = strText.Find (_T('&'));
				if (iAmpOffset >= 0 && iAmpOffset < strText.GetLength () - 1)
				{
					UINT uHotKey = (UINT) toupper (strText.GetAt (iAmpOffset + 1));
					m_HiddenItemsAccel.SetAt (uHotKey, uiCmd);
				}
			}
		}
	}

	m_uiDefaultMenuCmdId = ::GetMenuDefaultItem (hMenu, FALSE, GMDI_USEDISABLED);
	return TRUE;
}
//****************************************************************************************
HMENU CBCGPopupMenuBar::ExportToMenu () const
{
	CMenu menu;
	menu.CreatePopupMenu ();

	for (POSITION pos = m_Buttons.GetHeadPosition (); pos != NULL;)
	{
		CBCGToolbarButton* pButton = (CBCGToolbarButton*) m_Buttons.GetNext (pos);
		ASSERT (pButton != NULL);

		if (pButton->m_nStyle & TBBS_SEPARATOR)
		{
			menu.AppendMenu (MF_SEPARATOR);
			continue;
		}

		if (!pButton->IsKindOf (RUNTIME_CLASS (CBCGToolbarMenuButton)))
		{
			continue;
		}

		CBCGToolbarMenuButton* pMenuButton = (CBCGToolbarMenuButton*) pButton;

		HMENU hPopupMenu = pMenuButton->CreateMenu ();
		if (hPopupMenu != NULL)
		{
			UINT uiStyle = (MF_STRING | MF_POPUP);
			
			/// By Guy Hachlili - support for the menu with breaks:
			if (pButton->m_nStyle & TBBS_BREAK)
			{
				uiStyle |= MF_MENUBREAK;
			}
			//////////////////////

			menu.AppendMenu (uiStyle, (UINT) hPopupMenu, pMenuButton->m_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 CBCGPopupMenuBar::OnChangeHot (int iHot)
{
	if (iHot == -1 && !CBCGToolBar::IsCustomizeMode ())
	{
		return;
	}

	CBCGToolbarMenuButton* pCurrPopupMenu = NULL;

	for (POSITION pos = m_Buttons.GetHeadPosition (); pos != NULL;)
	{
		CBCGToolbarButton* pButton = (CBCGToolbarButton*) m_Buttons.GetNext (pos);
		ASSERT_VALID (pButton);

		CBCGToolbarMenuButton* pMenuButton =
			DYNAMIC_DOWNCAST (CBCGToolbarMenuButton, pButton);

		if (pMenuButton != NULL && pMenuButton->IsDroppedDown ())
		{
			pCurrPopupMenu = pMenuButton;
			break;
		}
	}

	CBCGToolbarMenuButton* pMenuButton = NULL;
	if (iHot >= 0)
	{
		CBCGToolbarButton* pButton = GetButton (iHot);
		if (pButton == NULL)
		{
			ASSERT (FALSE);
		}
		else
		{
			ASSERT_VALID (pButton);
			pMenuButton = DYNAMIC_DOWNCAST (CBCGToolbarMenuButton, pButton);
		}
	}

	if (pMenuButton != pCurrPopupMenu)
	{
		if (pCurrPopupMenu != NULL)
		{
			pCurrPopupMenu->OnCancelMode ();

			CBCGPopupMenu* pParentMenu = DYNAMIC_DOWNCAST (CBCGPopupMenu, GetParent ());
			if (pParentMenu != NULL)
			{
				CBCGPopupMenu::ActivatePopupMenu (GetParentFrame (), pParentMenu);
			}
		}

		if (pMenuButton != NULL && 
			(pMenuButton->m_nID == (UINT) -1 || pMenuButton->m_bDrawDownArrow))
		{
			pMenuButton->OnClick (this);
		}
	}
}
//****************************************************************************************
void CBCGPopupMenuBar::OnDestroy() 
{
	KillTimer (uiPopupTimerEvent);
	m_pDelayedPopupMenuButton = NULL;

	for (POSITION pos = m_Buttons.GetHeadPosition (); pos != NULL;)
	{
		CBCGToolbarButton* pButton = (CBCGToolbarButton*) m_Buttons.GetNext (pos);
		ASSERT_VALID (pButton);

		CBCGToolbarMenuButton* pMenuButton =
			DYNAMIC_DOWNCAST (CBCGToolbarMenuButton, pButton);

		if (pMenuButton != NULL && pMenuButton->IsDroppedDown ())
		{
			CBCGPopupMenu* pMenu = pMenuButton->m_pPopupMenu;
			if (pMenu != NULL && ::IsWindow (pMenu->m_hWnd))
			{
				pMenu->SaveState ();
				pMenu->PostMessage (WM_CLOSE);
			}
		}
	}

	CBCGToolBar::OnDestroy();
}
//****************************************************************************************
BOOL CBCGPopupMenuBar::OnKey(UINT nChar)
{
	BOOL bProcessed = FALSE;

	POSITION posSel = 
		(m_iHighlighted < 0) ? NULL : m_Buttons.FindIndex (m_iHighlighted);
	CBCGToolbarButton* pOldSelButton = 
		(posSel == NULL) ? NULL : (CBCGToolbarButton*) m_Buttons.GetAt (posSel);
	CBCGToolbarButton* pNewSelButton = pOldSelButton;
	int iNewHighlight = m_iHighlighted;

	switch (nChar)
	{
	case VK_RETURN:
		{
			bProcessed = TRUE;

			// Try to cascase a popup menu and, if failed 
			CBCGToolbarMenuButton* pMenuButton = DYNAMIC_DOWNCAST (CBCGToolbarMenuButton,
							pOldSelButton);
			if (pMenuButton != NULL &&
				!pMenuButton->OpenPopupMenu ())
			{
				GetOwner()->SendMessage(WM_SETMESSAGESTRING, AFX_IDS_IDLEMESSAGE);
				OnSendCommand (pMenuButton);
			}
		}
		break;

	case VK_HOME:
		posSel = NULL;
		// Like "Before first"...

	case VK_DOWN:
		//-----------------------------
		// Find next "selecteble" item:
		//-----------------------------
		{
			bProcessed = TRUE;
			if (m_Buttons.IsEmpty ())
			{
				break;
			}

			POSITION pos = posSel;
			if (pos != NULL)
			{
				m_Buttons.GetNext (pos);
			}

			if (pos == NULL)
			{
				pos = m_Buttons.GetHeadPosition ();
				iNewHighlight = 0;
			}
			else
			{
				iNewHighlight ++;
			}

			POSITION posFound = NULL;
			while (pos != posSel)
			{
				posFound = pos;

				CBCGToolbarButton* pButton = (CBCGToolbarButton*) m_Buttons.GetNext (pos);
				ASSERT_VALID (pButton);

				if ((pButton->m_nStyle & TBBS_SEPARATOR) == 0)
				{
					break;
				}

				iNewHighlight ++;
				if (pos == NULL)
				{
					pos = m_Buttons.GetHeadPosition ();
					iNewHighlight = 0;
				}
			}

			if (posFound != NULL)
			{
				pNewSelButton = (CBCGToolbarButton*) m_Buttons.GetAt (posFound);
			}
		}
		break;

	case VK_END:
		posSel = NULL;
		// Like "After last"....

	case VK_UP:
		//---------------------------------
		// Find previous "selecteble" item:
		//---------------------------------
		{
			bProcessed = TRUE;
			if (m_Buttons.IsEmpty ())
			{
				break;
			}

			POSITION pos = posSel;
			if (pos != NULL)
			{
				m_Buttons.GetPrev (pos);
			}
			if (pos == NULL)
			{
				pos = m_Buttons.GetTailPosition ();
				iNewHighlight = m_Buttons.GetCount () - 1;
			}
			else
			{
				iNewHighlight --;
			}

			POSITION posFound = NULL;
			while (pos != posSel)
			{
				posFound = pos;

				CBCGToolbarButton* pButton = (CBCGToolbarButton*) m_Buttons.GetPrev (pos);
				ASSERT_VALID (pButton);

				if ((pButton->m_nStyle & TBBS_SEPARATOR) == 0)
				{
					break;
				}

				iNewHighlight --;
				if (pos == NULL)
				{
					pos = m_Buttons.GetTailPosition ();
					iNewHighlight = m_Buttons.GetCount () - 1;
				}
			}

			if (posFound != NULL)
			{
				pNewSelButton = (CBCGToolbarButton*) m_Buttons.GetAt (posFound);
			}
		}
		break;

	default:
		// Process acceleration key:
		if (!IsCustomizeMode ())
		{
			UINT nUpperChar = toupper (nChar);

			CBCGToolbarButton* pButton;
			if (m_AcellKeys.Lookup (nUpperChar, pButton))
			{
				ASSERT_VALID (pButton);

				pNewSelButton = pButton;

				//-------------------
				// Find button index:
				//-------------------
				int iIndex = 0;
				for (POSITION pos = m_Buttons.GetHeadPosition ();
					pos != NULL; iIndex ++)
				{
					CBCGToolbarButton* pListButton = (CBCGToolbarButton*) m_Buttons.GetNext (pos);
					ASSERT (pListButton != NULL);

					if (pListButton == pButton)
					{
						iNewHighlight = iIndex;
						break;
					}

⌨️ 快捷键说明

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