www.pudn.com > vc开发的精美界面.zip > BCGContextMenuManager.cpp


//******************************************************************************* 
// COPYRIGHT NOTES 
// --------------- 
// This source code is a part of BCGControlBar library. 
// You may use, compile or redistribute it as part of your application  
// for free. You cannot redistribute it as a part of a software development  
// library without the agreement of the author. If the sources are  
// distributed along with the application, you should leave the original  
// copyright notes in the source code without any changes. 
// This code can be used WITHOUT ANY WARRANTIES on your own risk. 
//  
// For the latest updates to this library, check my site: 
// http://welcome.to/bcgsoft 
//  
// Stas Levin  
//******************************************************************************* 
 
// BCGContextMenuManager.cpp: implementation of the CBCGContextMenuManager class. 
// 
////////////////////////////////////////////////////////////////////// 
 
#include "stdafx.h" 
#include "BCGContextMenuManager.h" 
#include "BCGPopupMenu.h" 
#include "MenuHash.h" 
#include "globals.h" 
#include "RegPath.h" 
 
#ifdef _DEBUG 
#undef THIS_FILE 
static char THIS_FILE[]=__FILE__; 
#define new DEBUG_NEW 
#endif 
 
static const CString strMenusProfile = _T("BCGContextMenuManager"); 
 
CBCGContextMenuManager*	g_pContextMenuManager = NULL; 
 
////////////////////////////////////////////////////////////////////// 
// Construction/Destruction 
////////////////////////////////////////////////////////////////////// 
 
CBCGContextMenuManager::CBCGContextMenuManager() 
{ 
	ASSERT (g_pContextMenuManager == NULL); 
	g_pContextMenuManager = this; 
} 
//*********************************************************************************************** 
CBCGContextMenuManager::~CBCGContextMenuManager() 
{ 
	for (POSITION pos = m_Menus.GetStartPosition (); pos != NULL;) 
	{ 
		UINT uiResId; 
		HMENU hMenu; 
 
		m_Menus.GetNextAssoc (pos, uiResId, hMenu); 
		::DestroyMenu (hMenu); 
	} 
 
	g_pContextMenuManager = NULL; 
} 
//********************************************************************************** 
BOOL CBCGContextMenuManager::AddMenu(UINT uiMenuNameResId, UINT uiMenuResId) 
{ 
	CString strMenuName; 
	strMenuName.LoadString (uiMenuNameResId); 
 
	return AddMenu (strMenuName, uiMenuResId); 
} 
//*********************************************************************************************** 
BOOL CBCGContextMenuManager::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! 
		//------------------------------------------ 
		ASSERT (FALSE); 
		return FALSE; 
	} 
 
	HMENU hMenu = menu.Detach (); 
 
	m_Menus.SetAt (uiMenuResId, hMenu); 
	m_MenuNames.SetAt (lpszName, hMenu); 
 
	return TRUE; 
} 
//*********************************************************************************************** 
BOOL CBCGContextMenuManager::ShowPopupMenu (UINT uiMenuResId, int x, int y,  
											CWnd* pWndOwner, BOOL bOwnMessage) 
{ 
	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) != NULL; 
} 
//*********************************************************************************************** 
CBCGPopupMenu* CBCGContextMenuManager::ShowPopupMenu (HMENU hmenuPopup, int x, int y, 
											CWnd* pWndOwner, BOOL bOwnMessage) 
{ 
	ASSERT (hmenuPopup != NULL); 
 
	if (!bOwnMessage) 
	{ 
		while (pWndOwner != NULL && pWndOwner->GetStyle() & WS_CHILD) 
		{ 
			pWndOwner = pWndOwner->GetParent (); 
		} 
	} 
 
	CBCGPopupMenu* pPopupMenu = new CBCGPopupMenu; 
	if (!globalData.bIsWindowsNT4) 
	{ 
		pPopupMenu->SetAutoDestroy (FALSE); 
	} 
 
	if (!pPopupMenu->Create (pWndOwner, x, y, hmenuPopup, FALSE, bOwnMessage)) 
	{ 
		return NULL; 
	} 
 
	return pPopupMenu; 
} 
//*********************************************************************************************** 
void CBCGContextMenuManager::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 CBCGContextMenuManager::GetMenuByName (LPCTSTR lpszName) const 
{ 
	HMENU hMenu; 
	if (!m_MenuNames.Lookup (lpszName, hMenu)) 
	{ 
		return NULL; 
	} 
 
	return hMenu; 
} 
//*********************************************************************************************** 
BOOL CBCGContextMenuManager::LoadState (LPCTSTR lpszProfileName) 
{ 
	CString strProfileName = ::BCGGetRegPath (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); 
 
		CBCGPopupMenuBar bar; 
		if (!bar.ImportFromMenu (hPopupMenu)) 
		{ 
			return FALSE; 
		} 
 
		if (bar.LoadState (strProfileName, 0, uiResId)) 
		{ 
			g_menuHash.SaveMenuBar (hPopupMenu, &bar); 
		} 
	} 
 
	return TRUE; 
} 
//*********************************************************************************************** 
BOOL CBCGContextMenuManager::SaveState (LPCTSTR lpszProfileName) 
{ 
	CString strProfileName = ::BCGGetRegPath (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); 
 
		CBCGPopupMenuBar bar; 
		if (g_menuHash.LoadMenuBar (hPopupMenu, &bar)) 
		{ 
			if (!bar.SaveState (strProfileName, 0, uiResId)) 
			{ 
				return FALSE; 
			} 
		} 
	} 
 
	return TRUE; 
}