www.pudn.com > vc开发的精美界面.zip > BCGPopupMenuBar.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  
//******************************************************************************* 
 
// BCGPopupMenuBar.cpp : implementation file 
// 
 
#include "stdafx.h" 
#include  
 
#pragma warning (disable : 4201) 
	#include "mmsystem.h" 
#pragma warning (default : 4201) 
 
#include "BCGPopupMenuBar.h" 
#include "BCGToolbarButton.h" 
#include "BCGToolbarMenuButton.h" 
#include "BCGPopupMenu.h" 
#include "BCGCommandManager.h" 
#include "globals.h" 
#include "BCGToolbarMenuButton.h" 
#include "bcgbarres.h" 
#include "bcglocalres.h" 
#include "BCGMenuBar.h" 
#include "BCGToolbarComboBoxButton.h" 
#include "BCGUserToolsManager.h" 
#include "BCGregistry.h" 
#include "bcgsound.h" 
 
#ifdef _DEBUG 
#define new DEBUG_NEW 
#undef THIS_FILE 
static char THIS_FILE[] = __FILE__; 
#endif 
 
static const int iVertMargin = 1; 
static const int iHorzMargin = 1; 
static const int iSeparatorHeight = 8; 
static const int iMinTabSpace = 10; 
static const int iEmptyMenuWidth = 50; 
static const int iEmptyMenuHeight = 20; 
 
static const int uiPopupTimerEvent = 1; 
 
UINT CBCGPopupMenuBar::m_uiPopupTimerDelay = (UINT) -1; 
 
///////////////////////////////////////////////////////////////////////////// 
// CBCGPopupMenuBar 
 
IMPLEMENT_SERIAL(CBCGPopupMenuBar, CBCGToolBar, 1) 
 
CBCGPopupMenuBar::CBCGPopupMenuBar() : 
	m_uiDefaultMenuCmdId (0), 
	m_pDelayedPopupMenuButton (NULL), 
	m_bFirstClick (TRUE), 
	m_iOffset (0), 
	m_xSeparatorOffsetLeft (0), 
	m_xSeparatorOffsetRight (0), 
	m_iMaxWidth (-1), 
	m_bAreAllCommandsShown (TRUE), 
	m_bInCommand (FALSE) 
{ 
	m_bMenuMode = TRUE; 
} 
 
CBCGPopupMenuBar::~CBCGPopupMenuBar() 
{ 
} 
 
 
BEGIN_MESSAGE_MAP(CBCGPopupMenuBar, CBCGToolBar) 
	//{{AFX_MSG_MAP(CBCGPopupMenuBar) 
	ON_WM_NCPAINT() 
	ON_WM_NCCALCSIZE() 
	ON_WM_DESTROY() 
	ON_WM_TIMER() 
	ON_WM_LBUTTONUP() 
	ON_WM_LBUTTONDOWN() 
	ON_WM_MOUSEMOVE() 
	ON_WM_CREATE() 
	ON_MESSAGE(WM_IDLEUPDATECMDUI, OnIdleUpdateCmdUI) 
	//}}AFX_MSG_MAP 
END_MESSAGE_MAP() 
 
///////////////////////////////////////////////////////////////////////////// 
// CBCGPopupMenuBar message handlers 
 
BOOL CBCGPopupMenuBar::OnSendCommand (const CBCGToolbarButton* pButton) 
{ 
	ASSERT_VALID (pButton); 
 
	if ((pButton->m_nStyle & TBBS_DISABLED) != 0 || 
		pButton->m_nID < 0 || pButton->m_nID == (UINT)-1) 
	{ 
		return FALSE; 
	} 
 
	CBCGToolbarMenuButton* pMenuButton =  
		DYNAMIC_DOWNCAST (CBCGToolbarMenuButton, pButton); 
	if (pMenuButton != NULL && pMenuButton->m_pPopupMenu != NULL) 
	{ 
		return FALSE; 
	} 
 
	InvokeMenuCommand (pButton->m_nID); 
	return TRUE; 
} 
//************************************************************************************** 
void CBCGPopupMenuBar::InvokeMenuCommand (UINT uiCmdId) 
{ 
	ASSERT (uiCmdId != (UINT) -1); 
 
	GetOwner()->SendMessage(WM_SETMESSAGESTRING, AFX_IDS_IDLEMESSAGE); 
 
	//-------------------- 
	// Deactivate menubar: 
	//-------------------- 
	CBCGPopupMenu* pParentMenu = DYNAMIC_DOWNCAST (CBCGPopupMenu, GetParent ()); 
	if (pParentMenu != NULL) 
	{ 
		CBCGToolBar* pToolBar = NULL; 
		for (CBCGPopupMenu* pMenu = pParentMenu; pMenu != NULL; 
			pMenu = pMenu->GetParentPopupMenu ()) 
		{ 
			CBCGToolbarMenuButton* pParentButton = pMenu->GetParentButton (); 
			if (pParentButton == NULL) 
			{ 
				break; 
			} 
		 
			pToolBar =  
				DYNAMIC_DOWNCAST (CBCGToolBar, pParentButton->GetParentWnd ()); 
		} 
 
		if (pToolBar != NULL) 
		{ 
			pToolBar->Deactivate (); 
		} 
	} 
 
	CFrameWnd* pParentFrame = GetParentFrame (); 
	ASSERT_VALID (pParentFrame); 
 
	if (uiCmdId != 0) 
	{ 
		m_bInCommand = TRUE; 
 
		BCGPlaySystemSound (BCGSOUND_MENU_COMMAND); 
 
		//---------------------------------- 
		// Send command to the parent frame: 
		//---------------------------------- 
		AddCommandUsage (uiCmdId); 
 
		if (!pParentMenu->PostCommand (uiCmdId) && // Alex Corazzin (2) 
			(g_pUserToolsManager == NULL || 
			!g_pUserToolsManager->InvokeTool (uiCmdId))) 
		{ 
			GetOwner()->PostMessage (WM_COMMAND, uiCmdId); 
		} 
	} 
 
	m_bInCommand = FALSE; 
	pParentFrame->DestroyWindow (); 
} 
//*************************************************************** 
void CBCGPopupMenuBar::AdjustLocations () 
{ 
	if (GetSafeHwnd () == NULL || 
		!::IsWindow (m_hWnd)) 
	{ 
		return; 
	} 
 
	ASSERT_VALID(this); 
 
	if (m_xSeparatorOffsetLeft == 0) 
	{ 
		//----------------------------------------------------------- 
		// To enable MS Office 2000 look, we'll draw the separators 
		// bellow the menu text only (in the previous versions 
		// separator has been drawn on the whole menu row). Ask 
		// menu button about text area offsets: 
		//----------------------------------------------------------- 
		CBCGToolbarMenuButton::GetTextHorzOffsets ( 
			m_xSeparatorOffsetLeft, 
			m_xSeparatorOffsetRight); 
	} 
 
	CRect rectClient;	// Client area rectangle 
	GetClientRect (&rectClient); 
 
	CClientDC dc (this); 
	CFont* pOldFont = (CFont*) dc.SelectObject (&globalData.fontRegular); 
	ASSERT (pOldFont != NULL); 
 
	int y = rectClient.top + iVertMargin - m_iOffset * GetRowHeight (); 
 
	/// By Guy Hachlili - support for the menu with breaks: 
	int origy = y; 
	int x = rectClient.left; 
	int right = (m_arColumns.GetSize() == 0 || 
		CBCGToolBar::IsCustomizeMode ()) ?	 
			rectClient.Width() : 
			m_arColumns [0]; 
	int nColumn = 0; 
	///////// 
 
	CSize sizeMenuButton = GetMenuImageSize (); 
	sizeMenuButton += CSize (2 * iHorzMargin, 2 * iVertMargin); 
 
	sizeMenuButton.cy = max (sizeMenuButton.cy,  
							globalData.GetTextHeight ()); 
 
	for (POSITION pos = m_Buttons.GetHeadPosition (); pos != NULL;) 
	{ 
		CBCGToolbarButton* pButton = (CBCGToolbarButton*) m_Buttons.GetNext (pos); 
		ASSERT (pButton != NULL); 
 
		/// By Guy Hachlili - support for the menu with breaks: 
		if ((pButton->m_nStyle & TBBS_BREAK) && (y != origy) && 
			!CBCGToolBar::IsCustomizeMode ()) 
		{ 
			y = origy; 
			nColumn ++; 
			x = right + iHorzMargin; 
			right = m_arColumns [nColumn]; 
		} 
		//////////////////// 
		 
		CRect rectButton; 
		rectButton.top = y; 
 
		if (pButton->m_nStyle & TBBS_SEPARATOR) 
		{ 
			rectButton.left = x + m_xSeparatorOffsetLeft; 
			rectButton.right = right + rectClient.left - m_xSeparatorOffsetRight; 
			rectButton.bottom = rectButton.top + iSeparatorHeight; 
		} 
		else 
		{ 
			CSize sizeButton = pButton->OnCalculateSize (&dc,  
									sizeMenuButton, TRUE); 
 
			rectButton.left = x; 
			rectButton.right = right + rectClient.left; 
			rectButton.bottom = rectButton.top + sizeButton.cy; 
		} 
 
		pButton->SetRect (rectButton); 
		y += rectButton.Height (); 
	} 
 
	dc.SelectObject (pOldFont); 
 
	//-------------------------------------------------- 
	// Something may changed, rebuild acceleration keys: 
	//-------------------------------------------------- 
	RebuildAccelerationKeys (); 
} 
//*************************************************************************************** 
void CBCGPopupMenuBar::DrawSeparator (CDC* pDC, const CRect& rect, BOOL /*bHorz*/) 
{ 
	CRect rectSeparator = rect; 
 
	rectSeparator.top += rectSeparator.Height () / 2; 
	rectSeparator.bottom = rectSeparator.top + 2; 
 
	pDC->Draw3dRect (rectSeparator, globalData.clrBtnShadow, 
									globalData.clrBtnHilite); 
} 
//*************************************************************************************** 
CSize CBCGPopupMenuBar::CalcSize () 
{ 
	CSize size (0, 0); 
 
	CClientDC dc (this); 
	CFont* pOldFont = (CFont*) dc.SelectObject (&globalData.fontRegular); 
	ASSERT (pOldFont != NULL); 
 
	if (m_Buttons.IsEmpty ()) 
	{ 
		size = CSize (iEmptyMenuWidth, iEmptyMenuHeight); 
	} 
	else 
	{ 
		//////// By Guy Hachlili - support for the menu with breaks: 
		CSize column (0, 0); 
		m_arColumns.RemoveAll (); 
		////////////////////////// 
 
		CSize sizeMenuButton = GetMenuImageSize (); 
		sizeMenuButton += CSize (2 * iHorzMargin, 2 * iVertMargin); 
 
		sizeMenuButton.cy = max (sizeMenuButton.cy,  
								globalData.GetTextHeight ()); 
 
		for (POSITION pos = m_Buttons.GetHeadPosition (); pos != NULL;) 
		{ 
			CBCGToolbarButton* pButton = (CBCGToolbarButton*) m_Buttons.GetNext (pos); 
			ASSERT (pButton != NULL); 
 
			CSize sizeButton = pButton->OnCalculateSize (&dc,  
				sizeMenuButton, TRUE); 
 
			//////// By Guy Hachlili - support for the menu with breaks: 
			if ((pButton->m_nStyle & TBBS_BREAK) && 
				!CBCGToolBar::IsCustomizeMode ()) 
			{ 
				if ((column.cx != 0) && (column.cy != 0)) 
				{ 
					size.cy = max (column.cy, size.cy); 
					size.cx += column.cx + iHorzMargin; 
					m_arColumns.Add (size.cx); 
				} 
				column.cx = column.cy = 0; 
			} 
			/////////////////////////////// 
 
			int iHeight = sizeButton.cy; 
 
			if (pButton->m_nStyle & TBBS_SEPARATOR) 
			{ 
				iHeight = iSeparatorHeight; 
			} 
			else 
			{ 
				if (pButton->IsDrawText () && 
					pButton->m_strText.Find (_T('\t')) > 0) 
				{ 
					sizeButton.cx += iMinTabSpace; 
				} 
 
				pButton->m_bWholeText =  
					(m_iMaxWidth <= 0 ||  
					sizeButton.cx <= m_iMaxWidth - 2 * iHorzMargin); 
 
				column.cx = max (sizeButton.cx, column.cx); 
			} 
 
			column.cy += iHeight; 
		} 
 
		size.cy = max (column.cy, size.cy); 
		size.cx += column.cx; 
	} 
 
	size.cy += 2 * iVertMargin; 
	size.cx += 2 * iHorzMargin; 
 
	if (m_iMaxWidth > 0 && size.cx > m_iMaxWidth) 
	{ 
		size.cx = m_iMaxWidth; 
	} 
 
	m_arColumns.Add (size.cx); 
 
	dc.SelectObject (pOldFont); 
	return size; 
} 
//*************************************************************************************** 
void CBCGPopupMenuBar::OnNcPaint()  
{ 
	//-------------------------------------- 
	// Disable gripper and borders painting! 
	//-------------------------------------- 
} 
//*************************************************************************************** 
void CBCGPopupMenuBar::OnNcCalcSize(BOOL /*bCalcValidRects*/, NCCALCSIZE_PARAMS FAR* /*lpncsp*/)  
{ 
	//----------------------------------------------- 
	// Don't leave space for the gripper and borders! 
	//----------------------------------------------- 
} 
//**************************************************************************************** 
void CBCGPopupMenuBar::DrawDragMarker (CDC* pDC) 
{ 
	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 CBCGPopupMenuBar::FindDropIndex (const CPoint p, CRect& rectDrag) const 
{ 
	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 ++) 
	{ 
		CBCGToolbarButton* pButton = (CBCGToolbarButton*) 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; 
} 
//*************************************************************************************** 
CBCGToolbarButton* CBCGPopupMenuBar::CreateDroppedButton (COleDataObject* pDataObject) 
{ 
	CBCGToolbarButton* pButton = CBCGToolbarButton::CreateFromOleData (pDataObject); 
	ASSERT (pButton != NULL); 
 
	CBCGToolbarMenuButton* pMenuButton =  
		DYNAMIC_DOWNCAST (CBCGToolbarMenuButton, pButton); 
 
	if (pMenuButton == NULL) 
	{ 
		pMenuButton = new CBCGToolbarMenuButton ( 
			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 = TRUE; 
 
		BOOL bRes = pButton->ExportToMenuButton (*pMenuButton); 
		delete pButton; 
		 
		if (!bRes || 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 (g_pUserToolsManager == NULL || 
						!g_pUserToolsManager->IsUserToolCmd (uiCmd)) 
					{ 
						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; 
					} 
				} 
				 
				CBCGToolbarMenuButton* pMenuButton = 
					DYNAMIC_DOWNCAST (CBCGToolbarMenuButton, pButton); 
 
				if (pMenuButton != NULL) 
				{ 
					if (pMenuButton->OpenPopupMenu ()) 
					{ 
						if (pMenuButton->m_pPopupMenu != NULL) 
						{ 
							//-------------------------- 
							// Select a first menu item: 
							//-------------------------- 
							pMenuButton->m_pPopupMenu->SendMessage (WM_KEYDOWN, VK_HOME); 
						} 
					} 
					else 
					{ 
						// ------ By John Young:------------------- 
						// If the newly selected item is not highlighted, 
						// then make the menu go away. 
 
						if ((pButton->m_nStyle & TBBS_DISABLED) != 0) 
						{ 
							InvokeMenuCommand (0); 
							return TRUE; 
						} 
						//----------------------------------------- 
 
						bProcessed = OnSendCommand (pMenuButton); 
						if (bProcessed) 
						{ 
							return TRUE; 
						} 
					} 
				} 
			} 
			else if (CBCGMenuBar::m_bRecentlyUsedMenus && 
				!m_bAreAllCommandsShown) 
			{ 
				///--------------------------------------------------- 
				// Maybe, this accelerator is belong to "hidden' item? 
				//---------------------------------------------------- 
				UINT uiCmd = 0; 
				if (m_HiddenItemsAccel.Lookup (nUpperChar, uiCmd)) 
				{ 
					InvokeMenuCommand (uiCmd); 
					return TRUE; 
				} 
			} 
		} 
	} 
 
	if (pNewSelButton != pOldSelButton) 
	{ 
		ASSERT_VALID (pNewSelButton); 
		ASSERT (iNewHighlight >= 0 && iNewHighlight < m_Buttons.GetCount ()); 
		ASSERT (GetButton (iNewHighlight) == pNewSelButton); 
 
		//------------------------------------ 
		// Fixed by Sven Ritter (SpeedProject) 
		//------------------------------------ 
		if (IsCustomizeMode ()) 
		{ 
			m_iSelected = iNewHighlight; 
		} 
		// --- End --- 
 
		m_iHighlighted = iNewHighlight; 
 
		if (pOldSelButton != NULL) 
		{ 
			InvalidateRect (pOldSelButton->Rect ()); 
		} 
 
		InvalidateRect (pNewSelButton->Rect ()); 
		UpdateWindow (); 
 
		if (pNewSelButton->m_nID != (UINT) -1) 
		{ 
			ShowCommandMessageString (pNewSelButton->m_nID); 
		} 
	} 
 
	return bProcessed; 
} 
//************************************************************************************** 
void CBCGPopupMenuBar::OnTimer(UINT nIDEvent)  
{ 
	if (nIDEvent == uiPopupTimerEvent) 
	{ 
		KillTimer (uiPopupTimerEvent); 
 
		CBCGToolbarMenuButton* pDelayedPopupMenuButton = m_pDelayedPopupMenuButton; 
		m_pDelayedPopupMenuButton = NULL; 
 
		if (pDelayedPopupMenuButton != NULL && 
			m_iHighlighted >= 0 && 
			m_iHighlighted < m_Buttons.GetCount () && 
			GetButton (m_iHighlighted) == pDelayedPopupMenuButton) 
		{ 
			ASSERT_VALID (pDelayedPopupMenuButton); 
			pDelayedPopupMenuButton->OpenPopupMenu (this); 
		} 
	} 
} 
//************************************************************************************** 
void CBCGPopupMenuBar::StartPopupMenuTimer (CBCGToolbarMenuButton* pMenuButton) 
{ 
	if (m_pDelayedPopupMenuButton != NULL) 
	{ 
		KillTimer (uiPopupTimerEvent); 
	} 
 
	if ((m_pDelayedPopupMenuButton = pMenuButton) != NULL) 
	{ 
		SetTimer (uiPopupTimerEvent, m_uiPopupTimerDelay, NULL); 
	} 
} 
//********************************************************************************** 
void CBCGPopupMenuBar::OnLButtonDown(UINT nFlags, CPoint point)  
{ 
	m_bFirstClick = FALSE; 
 
	CRect rectClient; 
	GetClientRect (&rectClient); 
 
	if (!IsCustomizeMode () &&  
		!rectClient.PtInRect (point)) 
	{ 
		CBCGToolBar* pDestBar = FindDestBar (point); 
		if (pDestBar != NULL) 
		{ 
			CPoint ptDest = point; 
			MapWindowPoints (pDestBar, &ptDest, 1); 
 
			pDestBar->SendMessage (	WM_LBUTTONDOWN,  
									nFlags,  
									MAKELPARAM (ptDest.x, ptDest.y)); 
		} 
	} 
 
	CBCGToolBar::OnLButtonDown(nFlags, point); 
} 
//********************************************************************************** 
void CBCGPopupMenuBar::OnLButtonUp(UINT nFlags, CPoint point)  
{ 
	CRect rectClient; 
	GetClientRect (&rectClient); 
 
	if (!m_bFirstClick && 
		!IsCustomizeMode () &&  
		!rectClient.PtInRect (point)) 
	{ 
		CBCGToolBar* pDestBar = FindDestBar (point); 
		if (pDestBar != NULL) 
		{ 
			MapWindowPoints (pDestBar, &point, 1); 
			pDestBar->SendMessage (	WM_LBUTTONUP,  
									nFlags,  
									MAKELPARAM (point.x, point.y)); 
		} 
 
		CFrameWnd* pParentFrame = GetParentFrame (); 
		ASSERT_VALID (pParentFrame); 
 
		pParentFrame->DestroyWindow (); 
		return; 
	} 
 
	if (!IsCustomizeMode () && m_iHighlighted >= 0) 
	{ 
		m_iButtonCapture = m_iHighlighted; 
	} 
 
	m_bFirstClick = FALSE; 
	CBCGToolBar::OnLButtonUp (nFlags, point); 
} 
//********************************************************************************** 
BOOL CBCGPopupMenuBar::OnSetDefaultButtonText (CBCGToolbarButton* pButton) 
{ 
	ASSERT_VALID (pButton); 
 
	CBCGPopupMenu* pParentMenu = DYNAMIC_DOWNCAST (CBCGPopupMenu, GetParent ()); 
	if (pParentMenu != NULL) 
	{ 
		CBCGToolBar* pToolBar = pParentMenu->GetParentToolBar (); 
		if (pToolBar != NULL && pToolBar->OnSetDefaultButtonText (pButton)) 
		{ 
			return TRUE; 
		} 
	} 
 
	return CBCGToolBar::OnSetDefaultButtonText (pButton); 
} 
//**************************************************************************************** 
BOOL CBCGPopupMenuBar::EnableContextMenuItems (CBCGToolbarButton* pButton, CMenu* pPopup) 
{ 
	if (!CBCGToolBar::IsCustomizeMode ()) 
	{ 
		// Disable context menu 
		return FALSE; 
	} 
 
	ASSERT_VALID (pButton); 
	ASSERT_VALID (pPopup); 
 
	pPopup->EnableMenuItem (ID_BCGBARRES_TOOLBAR_IMAGE, MF_GRAYED | MF_BYCOMMAND); 
	pPopup->EnableMenuItem (ID_BCGBARRES_TOOLBAR_TEXT, MF_GRAYED | MF_BYCOMMAND); 
	pPopup->EnableMenuItem (ID_BCGBARRES_TOOLBAR_IMAGE_AND_TEXT, MF_GRAYED | MF_BYCOMMAND); 
 
	pButton->m_bText = TRUE; 
	CBCGToolBar::EnableContextMenuItems (pButton, pPopup); 
 
	return TRUE; 
} 
//**************************************************************************************** 
void CBCGPopupMenuBar::OnMouseMove(UINT nFlags, CPoint point)  
{ 
	CRect rectClient; 
	GetClientRect (&rectClient); 
 
	if (IsCustomizeMode () || 
		rectClient.PtInRect (point)) 
	{ 
		CBCGToolBar::OnMouseMove(nFlags, point); 
	} 
	else 
	{ 
		CBCGToolBar* pDestBar = FindDestBar (point); 
		if (pDestBar != NULL) 
		{ 
			MapWindowPoints (pDestBar, &point, 1); 
			pDestBar->SendMessage (	WM_MOUSEMOVE,  
									nFlags,  
									MAKELPARAM (point.x, point.y)); 
		} 
	} 
} 
//*************************************************************************************** 
CBCGToolBar* CBCGPopupMenuBar::FindDestBar (CPoint point) 
{ 
	ScreenToClient (&point); 
 
	CRect rectClient; 
 
	CBCGPopupMenu* pPopupMenu = DYNAMIC_DOWNCAST (CBCGPopupMenu, GetParent ()); 
	ASSERT_VALID (pPopupMenu); 
 
	CBCGPopupMenu* pLastPopupMenu = pPopupMenu; 
 
	//------------------------------- 
	// Go up trougth all popup menus: 
	//------------------------------- 
	while ((pPopupMenu = pPopupMenu->GetParentPopupMenu ()) != NULL) 
	{ 
		CBCGPopupMenuBar* pPopupMenuBar = pPopupMenu->GetMenuBar (); 
		ASSERT_VALID (pPopupMenuBar); 
 
		pPopupMenuBar->GetClientRect (&rectClient); 
		pPopupMenuBar->MapWindowPoints (this, &rectClient); 
 
		if (rectClient.PtInRect (point)) 
		{ 
			return pPopupMenuBar; 
		} 
 
		pLastPopupMenu = pPopupMenu; 
	} 
 
	ASSERT_VALID (pLastPopupMenu); 
 
	//-------------------- 
	// Try parent toolbar: 
	//-------------------- 
	CBCGToolBar* pToolBar = pLastPopupMenu->GetParentToolBar (); 
	if (pToolBar != NULL) 
	{ 
		pToolBar->GetClientRect (&rectClient); 
		pToolBar->MapWindowPoints (this, &rectClient); 
 
		if (rectClient.PtInRect (point)) 
		{ 
			return pToolBar; 
		} 
	} 
 
	return NULL; 
} 
//********************************************************************************************* 
DROPEFFECT CBCGPopupMenuBar::OnDragOver(COleDataObject* pDataObject, DWORD dwKeyState, CPoint point) 
{ 
	//----------------------------------------------- 
	// Disable MOVING menu item into one of submenus! 
	//----------------------------------------------- 
	if ((dwKeyState & MK_CONTROL) == 0) 
	{ 
		CBCGPopupMenu* pParentMenu = DYNAMIC_DOWNCAST (CBCGPopupMenu, GetParent ()); 
		if (pParentMenu != NULL) 
		{ 
			CBCGToolBar* pParentBar = pParentMenu->GetParentToolBar (); 
			CBCGToolbarMenuButton* pParentButton = pParentMenu->GetParentButton (); 
 
			if (pParentBar != NULL && pParentButton != NULL && 
				pParentBar->IsDragButton (pParentButton)) 
			{ 
				return DROPEFFECT_NONE; 
			} 
		} 
	} 
 
	return CBCGToolBar::OnDragOver(pDataObject, dwKeyState, point); 
} 
//***************************************************************************************** 
void CBCGPopupMenuBar::OnFillBackground (CDC* pDC) 
{ 
	ASSERT_VALID (pDC); 
 
	if (CBCGToolBar::IsCustomizeMode () || 
		!CBCGMenuBar::m_bRecentlyUsedMenus) 
	{ 
		return; 
	} 
 
	//-------------------------------------------------------------- 
	// Only menubar first-level menus may hide rarely used commands: 
	//-------------------------------------------------------------- 
	CBCGPopupMenu* pParentMenu = DYNAMIC_DOWNCAST (CBCGPopupMenu, GetParent ()); 
	if (pParentMenu == NULL || !pParentMenu->HideRarelyUsedCommands ()) 
	{ 
		return; 
	} 
 
	BOOL bFirstRarelyUsedButton = TRUE; 
	CRect rectRarelyUsed; 
 
	for (POSITION pos = m_Buttons.GetHeadPosition (); pos != NULL;) 
	{ 
		CBCGToolbarButton* pButton = (CBCGToolbarButton*) m_Buttons.GetNext (pos); 
		ASSERT (pButton != NULL); 
 
		if (pButton->m_nStyle & TBBS_SEPARATOR) 
		{ 
			if (pos != NULL && 
				CBCGToolBar::IsCommandRarelyUsed ( 
					((CBCGToolbarButton*) m_Buttons.GetAt (pos))->m_nID)) 
			{ 
				continue; 
			} 
		} 
 
		BOOL bDraw = FALSE; 
 
		if (CBCGToolBar::IsCommandRarelyUsed (pButton->m_nID)) 
		{ 
			if (bFirstRarelyUsedButton) 
			{ 
				bFirstRarelyUsedButton = FALSE; 
				rectRarelyUsed = pButton->Rect (); 
			} 
 
			if (pos == NULL)	// Last button 
			{ 
				rectRarelyUsed.bottom = pButton->Rect ().bottom; 
				bDraw = TRUE; 
			} 
		} 
		else 
		{ 
			if (!bFirstRarelyUsedButton) 
			{ 
				rectRarelyUsed.bottom = pButton->Rect ().top; 
				bDraw = TRUE; 
			} 
 
			bFirstRarelyUsedButton = TRUE; 
		} 
 
		if (bDraw) 
		{ 
			CBCGToolBarImages::FillDitheredRect (pDC, rectRarelyUsed); 
			pDC->Draw3dRect (rectRarelyUsed, globalData.clrBtnShadow, 
							globalData.clrBtnHilite); 
		} 
	} 
} 
//************************************************************************************* 
int CBCGPopupMenuBar::OnToolHitTest(CPoint point, TOOLINFO* pTI) const 
{ 
	ASSERT_VALID(this); 
 
	int nHit = ((CBCGPopupMenuBar*)this)->HitTest(point); 
	if (nHit != -1) 
	{ 
		CBCGToolbarButton* pButton =  
			DYNAMIC_DOWNCAST (CBCGToolbarButton, GetButton (nHit)); 
 
		if (pButton != NULL) 
		{ 
			if (pTI != NULL) 
			{ 
				pTI->uId = pButton->m_nID; 
				pTI->hwnd = GetSafeHwnd (); 
				pTI->rect = pButton->Rect (); 
			} 
 
			if (!pButton->OnToolHitTest (this, pTI)) 
			{ 
				nHit = pButton->m_nID; 
			} 
		} 
	} 
 
	return nHit; 
} 
//********************************************************************************** 
int CBCGPopupMenuBar::OnCreate(LPCREATESTRUCT lpCreateStruct)  
{ 
	if (CBCGToolBar::OnCreate(lpCreateStruct) == -1) 
		return -1; 
	 
	if (m_uiPopupTimerDelay == (UINT) -1)	// Not defined yet 
	{ 
		m_uiPopupTimerDelay = 500; 
		CBCGRegistry reg (FALSE, TRUE); 
 
		if (reg.Open (_T("Control Panel\\Desktop"))) 
		{ 
			CString strVal; 
 
			// By David Wang 
			if (reg.Read (_T("MenuShowDelay"), strVal)) 
			{ 
				m_uiPopupTimerDelay = (UINT) _ttol (strVal); 
 
				//------------------------ 
				// Just limit it to 5 sec: 
				//------------------------ 
				m_uiPopupTimerDelay = min (5000, m_uiPopupTimerDelay); 
			} 
		} 
	} 
	 
	return 0; 
} 
//***************************************************************** 
void CBCGPopupMenuBar::SetButtonStyle(int nIndex, UINT nStyle) 
{ 
	CBCGToolbarButton* pButton = GetButton (nIndex); 
	if (pButton == NULL) 
	{ 
		ASSERT (FALSE); 
		return; 
	} 
 
	UINT nOldStyle = pButton->m_nStyle; 
	if (nOldStyle != nStyle) 
	{ 
		// update the style and invalidate 
		pButton->m_nStyle = nStyle; 
 
		// invalidate the button only if both styles not "pressed" 
		if (!(nOldStyle & nStyle & TBBS_PRESSED)) 
		{ 
			CBCGToolbarMenuButton* pMenuButton = 
				DYNAMIC_DOWNCAST (CBCGToolbarMenuButton, GetButton (nIndex)); 
 
			BOOL bWasChecked = nOldStyle & TBBS_CHECKED; 
			BOOL bChecked = nStyle & TBBS_CHECKED; 
 
			// If checked style was changed. redraw check box (or image) area only: 
			if (pMenuButton != NULL && bWasChecked != bChecked) 
			{ 
				CRect rectImage; 
				pMenuButton->GetImageRect (rectImage); 
 
				InvalidateRect (rectImage); 
				UpdateWindow (); 
			} 
			else if ((nOldStyle ^ nStyle) != TBSTATE_PRESSED) 
			{ 
				InvalidateButton(nIndex); 
			} 
		} 
	} 
} 
// By Alex Corazzin (2) 
// --------------------------------------------------------------- 
LRESULT CBCGPopupMenuBar::OnIdleUpdateCmdUI(WPARAM wParam, LPARAM) 
{ 
	// handle delay hide/show 
	BOOL bVis = GetStyle() & WS_VISIBLE; 
	UINT swpFlags = 0; 
	if ((m_nStateFlags & delayHide) && bVis) 
	{ 
		swpFlags = SWP_HIDEWINDOW; 
	} 
	else if ((m_nStateFlags & delayShow) && !bVis) 
	{ 
		swpFlags = SWP_SHOWWINDOW; 
	} 
 
	m_nStateFlags &= ~(delayShow|delayHide); 
	if (swpFlags != 0) 
	{ 
		SetWindowPos (NULL, 0, 0, 0, 0, swpFlags| 
			SWP_NOMOVE|SWP_NOSIZE|SWP_NOZORDER|SWP_NOACTIVATE); 
	} 
	 
	// the style must be visible and if it is docked 
	// the dockbar style must also be visible 
	if ((GetStyle() & WS_VISIBLE) && 
		(m_pDockBar == NULL || (m_pDockBar->GetStyle() & WS_VISIBLE))) 
	{ 
		CFrameWnd* pTarget = GetCommandTarget (); 
		if (pTarget == NULL || !pTarget->IsFrameWnd()) 
		{ 
			pTarget = GetParentFrame(); 
		} 
 
		if (pTarget != NULL) 
		{ 
			OnUpdateCmdUI (pTarget, (BOOL)wParam); 
		} 
	} 
 
	return 0L; 
} 
// Fine aggiunta 
// --------------------------------------------------------------- 
 
CFrameWnd* CBCGPopupMenuBar::GetCommandTarget () const 
{ 
	CBCGPopupMenu* pParentMenu = DYNAMIC_DOWNCAST (CBCGPopupMenu, GetParent ()); 
	if (pParentMenu != NULL && pParentMenu->GetMessageWnd () != NULL) 
	{ 
         return pParentMenu; 
	} 
 
	return CBCGToolBar::GetCommandTarget (); 
}