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

📄 bcgpcontextmenumanager.cpp

📁 远程网络监视程序的源码
💻 CPP
字号:
//*******************************************************************************
// COPYRIGHT NOTES
// ---------------
// This is a part of the BCGControlBar Library
// Copyright (C) 1998-2000 BCGSoft Ltd.
// All rights reserved.
//
// This source code can be used, distributed or modified
// only under terms and conditions 
// of the accompanying license agreement.
//*******************************************************************************

// BCGPContextMenuManager.cpp: implementation of the CBCGPContextMenuManager class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "BCGPContextMenuManager.h"
#include "BCGPTearOffManager.h"
#include "BCGPPopupMenu.h"
#include "MenuHash.h"
#include "BCGGlobals.h"
#include "RegPath.h"
#include "BCGPDialog.h"
#include "BCGPPropertyPage.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

static const CString strMenusProfile = _T("BCGContextMenuManager");

CBCGPContextMenuManager*	g_pContextMenuManager = NULL;

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CBCGPContextMenuManager::CBCGPContextMenuManager()
{
	ASSERT (g_pContextMenuManager == NULL);
	g_pContextMenuManager = this;
	m_nLastCommandID = 0;
	m_bTrackMode = FALSE;
}
//***********************************************************************************************
CBCGPContextMenuManager::~CBCGPContextMenuManager()
{
	for (POSITION pos = m_Menus.GetStartPosition (); pos != NULL;)
	{
		UINT uiResId;
		HMENU hMenu;

		m_Menus.GetNextAssoc (pos, uiResId, hMenu);
		::DestroyMenu (hMenu);
	}

	g_pContextMenuManager = NULL;
}
//**********************************************************************************
BOOL CBCGPContextMenuManager::AddMenu(UINT uiMenuNameResId, UINT uiMenuResId)
{
	CString strMenuName;
	strMenuName.LoadString (uiMenuNameResId);

	return AddMenu (strMenuName, uiMenuResId);
}
//***********************************************************************************************
BOOL CBCGPContextMenuManager::AddMenu(LPCTSTR lpszName, UINT uiMenuResId)
{
	ASSERT (lpszName != NULL);

	CMenu menu;
	if (!menu.LoadMenu (uiMenuResId))
	{
		ASSERT (FALSE);
		return FALSE;
	}

	HMENU hExMenu;
	if (m_Menus.Lookup (uiMenuResId, hExMenu))
	{
		//------------------------------------------
		// Menu with the same name is already exist!
		//------------------------------------------
		return FALSE;
	}

	HMENU hMenu = menu.Detach ();

	if (g_pTearOffMenuManager != NULL)
	{
		g_pTearOffMenuManager->SetupTearOffMenus (hMenu);
	}

	m_Menus.SetAt (uiMenuResId, hMenu);
	m_MenuNames.SetAt (lpszName, hMenu);

	return TRUE;
}
//***********************************************************************************************
BOOL CBCGPContextMenuManager::ShowPopupMenu (UINT uiMenuResId, int x, int y, 
											CWnd* pWndOwner, BOOL bOwnMessage,
											BOOL bRightAlign)
{
	HMENU hMenu;
	if (!m_Menus.Lookup (uiMenuResId, hMenu) || hMenu == NULL)
	{
		return FALSE;
	}

	if (x == -1 && y == -1 &&	// Undefined position
		pWndOwner != NULL)
	{
		CRect rectParent;
		pWndOwner->GetClientRect (&rectParent);
		pWndOwner->ClientToScreen (&rectParent);

		x = rectParent.left + 5;
		y = rectParent.top + 5;
	}

	HMENU hmenuPopup = ::GetSubMenu (hMenu, 0);
	if (hmenuPopup == NULL)
	{
		#ifdef _DEBUG

		MENUITEMINFO info;
		memset (&info, 0, sizeof (MENUITEMINFO));

		if (!::GetMenuItemInfo (hMenu, 0, TRUE, &info))
		{
			TRACE (_T ("Invalid menu: %d\n"), uiMenuResId);
		}
		else
		{
			ASSERT (info.hSubMenu == NULL);
			TRACE (_T ("Menu %d, first option '%s' doesn't contain popup menu!\n"), 
					uiMenuResId, info.dwTypeData);
		}

		#endif // _DEBUG
		return FALSE;
	}

	return ShowPopupMenu (hmenuPopup, x, y, pWndOwner, bOwnMessage,
		TRUE, bRightAlign) != NULL;
}
//***********************************************************************************************
CBCGPPopupMenu* CBCGPContextMenuManager::ShowPopupMenu (HMENU hmenuPopup, int x, int y,
											CWnd* pWndOwner, BOOL bOwnMessage,
											BOOL bAutoDestroy,
											BOOL bRightAlign)
{
	if (pWndOwner != NULL &&
		pWndOwner->IsKindOf (RUNTIME_CLASS (CBCGPDialog)) && !bOwnMessage)
	{
		// BCGDialog should own menu messages
		ASSERT (FALSE);
		return NULL;
	}

	if (pWndOwner != NULL &&
		pWndOwner->IsKindOf (RUNTIME_CLASS (CBCGPPropertyPage)) && !bOwnMessage)
	{
		// CBCGPropertyPage should own menu messages
		ASSERT (FALSE);
		return NULL;
	}

	ASSERT (hmenuPopup != NULL);
	if (g_pTearOffMenuManager != NULL)
	{
		g_pTearOffMenuManager->SetupTearOffMenus (hmenuPopup);
	}

	if (m_bTrackMode)
	{
		bOwnMessage = TRUE;
	}

	if (!bOwnMessage)
	{
		while (pWndOwner != NULL && pWndOwner->GetStyle() & WS_CHILD)
		{
			pWndOwner = pWndOwner->GetParent ();
		}
	}

	CBCGPPopupMenu* pPopupMenu = new CBCGPPopupMenu;
	if (!globalData.bIsWindowsNT4 || 
		bAutoDestroy)
	{
		pPopupMenu->SetAutoDestroy (FALSE);
	}

	pPopupMenu->m_bTrackMode = m_bTrackMode;
	pPopupMenu->SetRightAlign (bRightAlign);

	CBCGPPopupMenu* pMenuActive = CBCGPPopupMenu::GetActiveMenu ();
	if (pMenuActive != NULL)
	{
		pMenuActive->SendMessage (WM_CLOSE);
	}

	if (!pPopupMenu->Create (pWndOwner, x, y, hmenuPopup, FALSE, bOwnMessage))
	{
		return NULL;
	}

	return pPopupMenu;
}
//***********************************************************************************************
UINT CBCGPContextMenuManager::TrackPopupMenu (HMENU hmenuPopup, int x, int y,
											 CWnd* pWndOwner, BOOL bRightAlign)
{
	m_nLastCommandID = 0;

	CWinApp* pApp = AfxGetApp ();
	if (pApp == NULL)
	{
		ASSERT (FALSE);
		return 0;
	}

	m_bTrackMode = TRUE;

	CBCGPPopupMenu* pMenu = ShowPopupMenu (hmenuPopup, x, y, pWndOwner,
		FALSE, TRUE, bRightAlign);

	CBCGPDialog* pParentDlg = NULL;
	if (pWndOwner != NULL && pWndOwner->GetParent () != NULL)
	{
		pParentDlg = DYNAMIC_DOWNCAST (CBCGPDialog, pWndOwner->GetParent ());
		if (pParentDlg != NULL)
		{
			pParentDlg->SetActiveMenu (pMenu);
		}
	}

	CBCGPPropertyPage* pParentPropPage = NULL;
	if (pWndOwner != NULL && pWndOwner->GetParent () != NULL)
	{
		pParentPropPage = DYNAMIC_DOWNCAST (CBCGPPropertyPage, pWndOwner->GetParent ());
		if (pParentPropPage != NULL)
		{
			pParentPropPage->SetActiveMenu (pMenu);
		}
	}

	m_bTrackMode = FALSE;

	if (pMenu != NULL && pApp != NULL)
	{
		ASSERT_VALID (pMenu);

		HWND hwndMenu = pMenu->GetSafeHwnd ();
		while (::IsWindow (hwndMenu))
		{
			MSG msg;
			while (::PeekMessage (&msg, NULL, 0, 0, PM_REMOVE))
			{
				if (!::IsWindow (hwndMenu))
				{
					break;
				}

				if (::IsWindow (hwndMenu) &&
					!pApp->PreTranslateMessage (&msg))
				{
					::TranslateMessage (&msg);
					::DispatchMessage (&msg);
				}

				pApp->OnIdle (0);
			}

			if (!::IsWindow (hwndMenu))
			{
				break;
			}

			WaitMessage ();
		}
	}

	if (pParentDlg != NULL)
	{
		pParentDlg->SetActiveMenu (NULL);
	}

	if (pParentPropPage != NULL)
	{
		pParentPropPage->SetActiveMenu (NULL);
	}

	return m_nLastCommandID;
}
//***********************************************************************************************
void CBCGPContextMenuManager::GetMenuNames (CStringList& listOfNames) const
{
	listOfNames.RemoveAll ();

	for (POSITION pos = m_MenuNames.GetStartPosition (); pos != NULL;)
	{
		CString strName;
		HMENU hMenu;

		m_MenuNames.GetNextAssoc (pos, strName, hMenu);
		listOfNames.AddTail (strName);
	}
}
//***********************************************************************************************
HMENU CBCGPContextMenuManager::GetMenuByName (LPCTSTR lpszName, UINT* puiOrigResID) const
{
	HMENU hMenu;
	if (!m_MenuNames.Lookup (lpszName, hMenu))
	{
		return NULL;
	}

	if (puiOrigResID != NULL)
	{
		*puiOrigResID = 0;

		for (POSITION pos = m_Menus.GetStartPosition (); pos != NULL;)
		{
			UINT uiResId;
			HMENU hMenuMap;

			m_Menus.GetNextAssoc (pos, uiResId, hMenuMap);
			if (hMenuMap == hMenu)
			{
				*puiOrigResID = uiResId;
				break;
			}
		}
	}

	return hMenu;
}
//***********************************************************************************************
BOOL CBCGPContextMenuManager::LoadState (LPCTSTR lpszProfileName)
{
	CString strProfileName = ::BCGPGetRegPath (strMenusProfile, lpszProfileName);

	for (POSITION pos = m_Menus.GetStartPosition (); pos != NULL;)
	{
		UINT uiResId;
		HMENU hMenu;

		m_Menus.GetNextAssoc (pos, uiResId, hMenu);
		ASSERT (hMenu != NULL);

		HMENU hPopupMenu = ::GetSubMenu (hMenu, 0);
		ASSERT (hPopupMenu != NULL);

		CBCGPPopupMenuBar* pBar = new CBCGPPopupMenuBar;
		if (pBar->Create (CWnd::FromHandle (GetDesktopWindow ())))
		{
			if (!pBar->ImportFromMenu (hPopupMenu))
			{
				pBar->DestroyWindow ();
				delete pBar;
				return FALSE;
			}

			if (pBar->LoadState (strProfileName, 0, uiResId))
			{
				g_menuHash.SaveMenuBar (hPopupMenu, pBar);
			}

			pBar->DestroyWindow ();
		}
		delete pBar;
	}

	return TRUE;
}
//***********************************************************************************************
BOOL CBCGPContextMenuManager::SaveState (LPCTSTR lpszProfileName)
{
	CString strProfileName = ::BCGPGetRegPath (strMenusProfile, lpszProfileName);

	for (POSITION pos = m_Menus.GetStartPosition (); pos != NULL;)
	{
		UINT uiResId;
		HMENU hMenu;

		m_Menus.GetNextAssoc (pos, uiResId, hMenu);
		ASSERT (hMenu != NULL);

		HMENU hPopupMenu = ::GetSubMenu (hMenu, 0);
		ASSERT (hPopupMenu != NULL);

		CBCGPPopupMenuBar* pBar = new CBCGPPopupMenuBar;
		if (pBar->Create (CWnd::FromHandle (GetDesktopWindow ())))
		{
			if (g_menuHash.LoadMenuBar (hPopupMenu, pBar))
			{
				if (!pBar->SaveState (strProfileName, 0, uiResId))
				{
					pBar->DestroyWindow ();
					delete pBar;
					return FALSE;
				}
			}
		
			pBar->DestroyWindow ();
		}
		delete pBar;
	}

	return TRUE;
}
//***********************************************************************************************
BOOL CBCGPContextMenuManager::ResetState ()
{
	for (POSITION pos = m_Menus.GetStartPosition (); pos != NULL;)
	{
		UINT uiResId;
		HMENU hMenu;

		m_Menus.GetNextAssoc (pos, uiResId, hMenu);
		ASSERT (hMenu != NULL);

		HMENU hPopupMenu = ::GetSubMenu (hMenu, 0);
		ASSERT (hPopupMenu != NULL);

		g_menuHash.RemoveMenu (hPopupMenu);
	}

	return TRUE;
}
//********************************************************************************
HMENU CBCGPContextMenuManager::GetMenuById (UINT nMenuResId) const
{
   HMENU hMenu = NULL ;
   return m_Menus.Lookup (nMenuResId, hMenu) ? hMenu : NULL;
}

⌨️ 快捷键说明

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