// Windows Template Library - WTL version 8.0
// Copyright (C) Microsoft Corporation. All rights reserved.
//
// This file is a part of the Windows Template Library.
// The use and distribution terms for this software are covered by the
// Microsoft Permissive License (Ms-PL) which can be found in the file
// Ms-PL.txt at the root of this distribution.

#ifndef __ATLCTRLW_H__
#define __ATLCTRLW_H__

#pragma once

#ifndef __cplusplus
	#error ATL requires C++ compilation (use a .cpp suffix)
#endif

#ifdef _WIN32_WCE
	#error atlctrlw.h is not supported on Windows CE
#endif

#ifndef __ATLAPP_H__
	#error atlctrlw.h requires atlapp.h to be included first
#endif

#ifndef __ATLCTRLS_H__
	#error atlctrlw.h requires atlctrls.h to be included first
#endif

#if (_WIN32_IE < 0x0400)
	#error atlctrlw.h requires _WIN32_IE >= 0x0400
#endif

// Define _WTL_CMDBAR_VISTA_MENUS as 0 to exclude Vista menus support
#if !defined(_WTL_CMDBAR_VISTA_MENUS) && (WINVER >= 0x0500) && (_WIN32_WINNT >= 0x0501) && (_WIN32_IE >= 0x0501)
  #define _WTL_CMDBAR_VISTA_MENUS 1
#endif

#if _WTL_CMDBAR_VISTA_MENUS
  #if !((_WIN32_WINNT >= 0x0501) && (_WIN32_IE >= 0x0501))
	#error _WTL_CMDBAR_VISTA_MENUS requires (_WIN32_WINNT >= 0x0501) && (_WIN32_IE >= 0x0501)
  #endif
#endif


///////////////////////////////////////////////////////////////////////////////
// Classes in this file:
//
// CCommandBarCtrlImpl<T, TBase, TWinTraits>
// CCommandBarCtrl
// CMDICommandBarCtrlImpl<T, TBase, TWinTraits>
// CMDICommandBarCtrl


namespace WTL
{

///////////////////////////////////////////////////////////////////////////////
// Command Bars

// Window Styles:
#define CBRWS_TOP		CCS_TOP
#define CBRWS_BOTTOM		CCS_BOTTOM
#define CBRWS_NORESIZE		CCS_NORESIZE
#define CBRWS_NOPARENTALIGN	CCS_NOPARENTALIGN
#define CBRWS_NODIVIDER		CCS_NODIVIDER

// Extended styles
#define CBR_EX_TRANSPARENT	0x00000001L
#define CBR_EX_SHAREMENU	0x00000002L
#define CBR_EX_ALTFOCUSMODE	0x00000004L
#define CBR_EX_TRACKALWAYS	0x00000008L
#define CBR_EX_NOVISTAMENUS	0x00000010L

// standard command bar styles
#define ATL_SIMPLE_CMDBAR_PANE_STYLE \
	(WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | CBRWS_NODIVIDER | CBRWS_NORESIZE | CBRWS_NOPARENTALIGN)

// Messages - support chevrons for frame windows
#define CBRM_GETCMDBAR			(WM_USER + 301) // returns command bar HWND
#define CBRM_GETMENU			(WM_USER + 302) // returns loaded or attached menu
#define CBRM_TRACKPOPUPMENU		(WM_USER + 303) // displays a popup menu

typedef struct tagCBRPOPUPMENU
{
	int cbSize;
	HMENU hMenu;         // popup menu do display
	UINT uFlags;         // TPM_* flags for ::TrackPopupMenuEx
	int x;
	int y;
	LPTPMPARAMS lptpm;   // ptr to TPMPARAMS for ::TrackPopupMenuEx
} CBRPOPUPMENU, *LPCBRPOPUPMENU;

// helper class
template <class T>
class CSimpleStack : public ATL::CSimpleArray< T >
{
public:
	BOOL Push(T t)
	{
#ifdef _CMDBAR_EXTRA_TRACE
		ATLTRACE2(atlTraceUI, 0, _T("CmdBar - STACK-PUSH (%8.8X) size = %i\n"), t, GetSize());
#endif
		return Add(t);
	}

	T Pop()
	{
		int nLast = GetSize() - 1;
		if(nLast < 0)
			return NULL;   // must be able to convert to NULL
		T t = m_aT[nLast];
#ifdef _CMDBAR_EXTRA_TRACE
		ATLTRACE2(atlTraceUI, 0, _T("CmdBar - STACK-POP (%8.8X) size = %i\n"), t, GetSize());
#endif
		if(!RemoveAt(nLast))
			return NULL;
		return t;
	}

	T GetCurrent()
	{
		int nLast = GetSize() - 1;
		if(nLast < 0)
			return NULL;   // must be able to convert to NULL
		return m_aT[nLast];
	}
};


///////////////////////////////////////////////////////////////////////////////
// CCommandBarCtrlBase - base class for the Command Bar implementation

class CCommandBarCtrlBase : public CToolBarCtrl
{
public:
	struct _MsgHookData
	{
		HHOOK hMsgHook;
		DWORD dwUsage;

		_MsgHookData() : hMsgHook(NULL), dwUsage(0)
		{ }
	};

	typedef ATL::CSimpleMap<DWORD, _MsgHookData*>   CMsgHookMap;
	static CMsgHookMap* s_pmapMsgHook;

	static HHOOK s_hCreateHook;
	static bool s_bW2K;  // For animation flag
	static CCommandBarCtrlBase* s_pCurrentBar;
	static bool s_bStaticInit;

	CSimpleStack<HWND> m_stackMenuWnd;
	CSimpleStack<HMENU> m_stackMenuHandle;

	HWND m_hWndHook;
	DWORD m_dwMagic;


	CCommandBarCtrlBase() : m_hWndHook(NULL), m_dwMagic(1314)
	{
		// init static variables
		if(!s_bStaticInit)
		{
			CStaticDataInitCriticalSectionLock lock;
			if(FAILED(lock.Lock()))
			{
				ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to lock critical section in CCommandBarCtrlBase::CCommandBarCtrlBase.\n"));
				ATLASSERT(FALSE);
				return;
			}

			if(!s_bStaticInit)
			{
				// Just in case...
				AtlInitCommonControls(ICC_COOL_CLASSES | ICC_BAR_CLASSES);
				// Animation on Win2000 only
				s_bW2K = !AtlIsOldWindows();
				// done
				s_bStaticInit = true;
			}

			lock.Unlock();
		}
	}

	bool IsCommandBarBase() const { return m_dwMagic == 1314; }
};

__declspec(selectany) CCommandBarCtrlBase::CMsgHookMap* CCommandBarCtrlBase::s_pmapMsgHook = NULL;
__declspec(selectany) HHOOK CCommandBarCtrlBase::s_hCreateHook = NULL;
__declspec(selectany) CCommandBarCtrlBase* CCommandBarCtrlBase::s_pCurrentBar = NULL;
__declspec(selectany) bool CCommandBarCtrlBase::s_bW2K = false;
__declspec(selectany) bool CCommandBarCtrlBase::s_bStaticInit = false;


///////////////////////////////////////////////////////////////////////////////
// CCommandBarCtrl - ATL implementation of Command Bars

template <class T, class TBase = CCommandBarCtrlBase, class TWinTraits = ATL::CControlWinTraits>
class ATL_NO_VTABLE CCommandBarCtrlImpl : public ATL::CWindowImpl< T, TBase, TWinTraits >
{
public:
	DECLARE_WND_SUPERCLASS(NULL, TBase::GetWndClassName())

// Declarations
	struct _MenuItemData	// menu item data
	{
		DWORD dwMagic;
		LPTSTR lpstrText;
		UINT fType;
		UINT fState;
		int iButton;

		_MenuItemData() { dwMagic = 0x1313; }
		bool IsCmdBarMenuItem() { return (dwMagic == 0x1313); }
	};

	struct _ToolBarData	// toolbar resource data
	{
		WORD wVersion;
		WORD wWidth;
		WORD wHeight;
		WORD wItemCount;
		//WORD aItems[wItemCount]

		WORD* items()
			{ return (WORD*)(this+1); }
	};

// Constants
	enum _CmdBarDrawConstants
	{
		s_kcxGap = 1,
		s_kcxTextMargin = 2,
		s_kcxButtonMargin = 3,
		s_kcyButtonMargin = 3
	};

	enum
	{
		_nMaxMenuItemTextLength = 100,
		_chChevronShortcut = _T('/')
	};

#ifndef DT_HIDEPREFIX
	enum { DT_HIDEPREFIX = 0x00100000 };
#endif // !DT_HIDEPREFIX

// Data members
	HMENU m_hMenu;
	HIMAGELIST m_hImageList;
	ATL::CSimpleValArray<WORD> m_arrCommand;

	DWORD m_dwExtendedStyle;   // Command Bar specific extended styles

	ATL::CContainedWindow m_wndParent;

	bool m_bMenuActive:1;
	bool m_bAttachedMenu:1;
	bool m_bImagesVisible:1;
	bool m_bPopupItem:1;
	bool m_bContextMenu:1;
	bool m_bEscapePressed:1;
	bool m_bSkipMsg:1;
	bool m_bParentActive:1;
	bool m_bFlatMenus:1;
	bool m_bUseKeyboardCues:1;
	bool m_bShowKeyboardCues:1;
	bool m_bAllowKeyboardCues:1;
	bool m_bKeyboardInput:1;
	bool m_bAlphaImages:1;
	bool m_bLayoutRTL:1;
	bool m_bSkipPostDown:1;
	bool m_bVistaMenus:1;

	int m_nPopBtn;
	int m_nNextPopBtn;

	SIZE m_szBitmap;
	SIZE m_szButton;

	COLORREF m_clrMask;
	CFont m_fontMenu;   // used internally, only to measure text

	UINT m_uSysKey;

	HWND m_hWndFocus;   // Alternate focus mode

	int m_cxExtraSpacing;

#if _WTL_CMDBAR_VISTA_MENUS
	ATL::CSimpleValArray<HBITMAP> m_arrVistaBitmap;   // Bitmaps for Vista menus
#endif // _WTL_CMDBAR_VISTA_MENUS

// Constructor/destructor
	CCommandBarCtrlImpl() : 
			m_hMenu(NULL), 
			m_hImageList(NULL), 
			m_wndParent(this, 1), 
			m_bMenuActive(false), 
			m_bAttachedMenu(false), 
			m_nPopBtn(-1), 
			m_nNextPopBtn(-1), 
			m_bPopupItem(false),
			m_bImagesVisible(true),
			m_bSkipMsg(false),
			m_uSysKey(0),
			m_hWndFocus(NULL),
			m_bContextMenu(false),
			m_bEscapePressed(false),
			m_clrMask(RGB(192, 192, 192)),
			m_dwExtendedStyle(CBR_EX_TRANSPARENT | CBR_EX_SHAREMENU | CBR_EX_TRACKALWAYS),
			m_bParentActive(true),
			m_bFlatMenus(false),
			m_bUseKeyboardCues(false),
			m_bShowKeyboardCues(false),
			m_bAllowKeyboardCues(true),
			m_bKeyboardInput(false),
			m_cxExtraSpacing(0),
			m_bAlphaImages(false),
			m_bLayoutRTL(false),
			m_bSkipPostDown(false),
			m_bVistaMenus(false)
	{
		SetImageSize(16, 15);   // default
 	}

	~CCommandBarCtrlImpl()
	{
		if(m_wndParent.IsWindow())
/*scary!*/			m_wndParent.UnsubclassWindow();

		if(m_hMenu != NULL && (m_dwExtendedStyle & CBR_EX_SHAREMENU) == 0)
			::DestroyMenu(m_hMenu);

		if(m_hImageList != NULL)
			::ImageList_Destroy(m_hImageList);
	}

// Attributes
	DWORD GetCommandBarExtendedStyle() const
	{
		return m_dwExtendedStyle;
	}

	DWORD SetCommandBarExtendedStyle(DWORD dwExtendedStyle, DWORD dwMask = 0)
	{
		DWORD dwPrevStyle = m_dwExtendedStyle;
		if(dwMask == 0)
			m_dwExtendedStyle = dwExtendedStyle;
		else
			m_dwExtendedStyle = (m_dwExtendedStyle & ~dwMask) | (dwExtendedStyle & dwMask);
		return dwPrevStyle;
	}

	CMenuHandle GetMenu() const
	{
		ATLASSERT(::IsWindow(m_hWnd));
		return m_hMenu;
	}

	COLORREF GetImageMaskColor() const
	{
		return m_clrMask;
	}

	COLORREF SetImageMaskColor(COLORREF clrMask)
	{
		COLORREF clrOld = m_clrMask;
		m_clrMask = clrMask;
		return clrOld;
	}

	bool GetImagesVisible() const
	{
		return m_bImagesVisible;
	}

	bool SetImagesVisible(bool bVisible)
	{
		bool bOld = m_bImagesVisible;
		m_bImagesVisible = bVisible;
		return bOld;
	}

	void GetImageSize(SIZE& size) const
	{
		size = m_szBitmap;
	}

	bool SetImageSize(SIZE& size)
	{
		return SetImageSize(size.cx, size.cy);
	}

	bool SetImageSize(int cx, int cy)
	{
		if(m_hImageList != NULL)
		{
			if(::ImageList_GetImageCount(m_hImageList) == 0)   // empty
			{
				::ImageList_Destroy(m_hImageList);
				m_hImageList = NULL;
			}
			else
			{
				return false;   // can't set, image list exists
			}
		}

		if(cx == 0 || cy == 0)
			return false;

		m_szBitmap.cx = cx;
		m_szBitmap.cy = cy;
		m_szButton.cx = m_szBitmap.cx + 2 * s_kcxButtonMargin;
		m_szButton.cy = m_szBitmap.cy + 2 * s_kcyButtonMargin;

		return true;
	}

	bool GetAlphaImages() const
	{
		return m_bAlphaImages;
	}

	bool SetAlphaImages(bool bAlphaImages)
	{
		if(m_hImageList != NULL)
		{
			if(::ImageList_GetImageCount(m_hImageList) == 0)   // empty
			{
				::ImageList_Destroy(m_hImageList);
				m_hImageList = NULL;
			}
			else
			{
				return false;   // can't set, image list exists
			}
		}

		m_bAlphaImages = bAlphaImages;
		return true;
	}

	HWND GetCmdBar() const
	{
		ATLASSERT(::IsWindow(m_hWnd));
		return (HWND)::SendMessage(m_hWnd, CBRM_GETCMDBAR, 0, 0L);
	}

// Methods
	HWND Create(HWND hWndParent, RECT& rcPos, LPCTSTR szWindowName = NULL,
			DWORD dwStyle = 0, DWORD dwExStyle = 0,
			UINT nID = 0, LPVOID lpCreateParam = NULL)
	{
		// These styles are required for command bars
		dwStyle |= TBSTYLE_LIST | TBSTYLE_FLAT;
#if (_MSC_VER >= 1300)
		return ATL::CWindowImpl< T, TBase, TWinTraits >::Create(hWndParent, rcPos, szWindowName, dwStyle, dwExStyle, nID, lpCreateParam);
#else // !(_MSC_VER >= 1300)
		typedef ATL::CWindowImpl< T, TBase, TWinTraits >   _baseClass;
		return _baseClass::Create(hWndParent, rcPos, szWindowName, dwStyle, dwExStyle, nID, lpCreateParam);
#endif // !(_MSC_VER >= 1300)
	}

	BOOL AttachToWindow(HWND hWnd)
	{
		ATLASSERT(m_hWnd == NULL);
		ATLASSERT(::IsWindow(hWnd));
		BOOL bRet = SubclassWindow(hWnd);
		if(bRet)
		{
			m_bAttachedMenu = true;
			T* pT = static_cast<T*>(this);
			pT->GetSystemSettings();
		}
		return bRet;
	}

	BOOL LoadMenu(ATL::_U_STRINGorID menu)
	{
		ATLASSERT(::IsWindow(m_hWnd));

		if(m_bAttachedMenu)   // doesn't work in this mode
			return FALSE;
		if(menu.m_lpstr == NULL)
			return FALSE;

		HMENU hMenu = ::LoadMenu(ModuleHelper::GetResourceInstance(), menu.m_lpstr);
		if(hMenu == NULL)
			return FALSE;

		return AttachMenu(hMenu);
	}

	BOOL AttachMenu(HMENU hMenu)
	{
		ATLASSERT(::IsWindow(m_hWnd));
		ATLASSERT(hMenu == NULL || ::IsMenu(hMenu));
		if(hMenu != NULL && !::IsMenu(hMenu))
			return FALSE;

#if _WTL_CMDBAR_VISTA_MENUS
		// remove Vista bitmaps if used
		if(m_bVistaMenus && (m_hMenu != NULL))
		{
			T* pT = static_cast<T*>(this);
			pT->_RemoveVistaBitmapsFromMenu();
		}
#endif // _WTL_CMDBAR_VISTA_MENUS

		// destroy old menu, if needed, and set new one
		if(m_hMenu != NULL && (m_dwExtendedStyle & CBR_EX_SHAREMENU) == 0)
			::DestroyMenu(m_hMenu);

		m_hMenu = hMenu;

		if(m_bAttachedMenu)   // Nothing else in this mode
			return TRUE;

		// Build buttons according to menu
		SetRedraw(FALSE);

		// Clear all buttons
		int nCount = GetButtonCount();
		for(int i = 0; i < nCount; i++)
			ATLVERIFY(DeleteButton(0) != FALSE);

		// Add buttons for each menu item
		if(m_hMenu != NULL)
		{
			int nItems = ::GetMenuItemCount(m_hMenu);

			T* pT = static_cast<T*>(this);
			pT;   // avoid level 4 warning
			TCHAR szString[pT->_nMaxMenuItemTextLength];
			for(int i = 0; i < nItems; i++)
			{
				CMenuItemInfo mii;
				mii.fMask = MIIM_TYPE | MIIM_STATE | MIIM_SUBMENU;
				mii.fType = MFT_STRING;
				mii.dwTypeData = szString;
				mii.cch = pT->_nMaxMenuItemTextLength;
				BOOL bRet = ::GetMenuItemInfo(m_hMenu, i, TRUE, &mii);
				ATLASSERT(bRet);
				// If we have more than the buffer, we assume we have bitmaps bits
				if(lstrlen(szString) > pT->_nMaxMenuItemTextLength - 1)
				{
					mii.fType = MFT_BITMAP;
					::SetMenuItemInfo(m_hMenu, i, TRUE, &mii);
					szString[0] = 0;
				}

				// NOTE: Command Bar currently supports only drop-down menu items
				ATLASSERT(mii.hSubMenu != NULL);

				TBBUTTON btn = { 0 };
				btn.iBitmap = 0;
				btn.idCommand = i;
				btn.fsState = (BYTE)(((mii.fState & MFS_DISABLED) == 0) ? TBSTATE_ENABLED : 0);
				btn.fsStyle = TBSTYLE_BUTTON | TBSTYLE_AUTOSIZE | TBSTYLE_DROPDOWN;
				btn.dwData = 0;
				btn.iString = 0;

				bRet = InsertButton(-1, &btn);
				ATLASSERT(bRet);

				TBBUTTONINFO bi = { 0 };
				bi.cbSize = sizeof(TBBUTTONINFO);
				bi.dwMask = TBIF_TEXT;
				bi.pszText = szString;

				bRet = SetButtonInfo(i, &bi);
				ATLASSERT(bRet);
			}
		}

		SetRedraw(TRUE);
		Invalidate();
		UpdateWindow();

		return TRUE;
	}

	BOOL LoadImages(ATL::_U_STRINGorID image)
	{
		return _LoadImagesHelper(image, false);
	}

	BOOL LoadMappedImages(UINT nIDImage, UINT nFlags = 0, LPCOLORMAP lpColorMap = NULL, int nMapSize = 0)
	{
		return _LoadImagesHelper(nIDImage, true, nFlags , lpColorMap, nMapSize);
	}

	BOOL _LoadImagesHelper(ATL::_U_STRINGorID image, bool bMapped, UINT nFlags = 0, LPCOLORMAP lpColorMap = NULL, int nMapSize = 0)
	{
		ATLASSERT(::IsWindow(m_hWnd));
		HINSTANCE hInstance = ModuleHelper::GetResourceInstance();

		HRSRC hRsrc = ::FindResource(hInstance, image.m_lpstr, (LPTSTR)RT_TOOLBAR);
		if(hRsrc == NULL)
			return FALSE;

		HGLOBAL hGlobal = ::LoadResource(hInstance, hRsrc);
		if(hGlobal == NULL)
			return FALSE;

		_ToolBarData* pData = (_ToolBarData*)::LockResource(hGlobal);
		if(pData == NULL)
			return FALSE;
		ATLASSERT(pData->wVersion == 1);

		WORD* pItems = pData->items();
		int nItems = pData->wItemCount;

		// Set internal data
		SetImageSize(pData->wWidth, pData->wHeight);

		// Create image list if needed
		if(m_hImageList == NULL)
		{
			// Check if the bitmap is 32-bit (alpha channel) bitmap (valid for Windows XP only)
			T* pT = static_cast<T*>(this);
			m_bAlphaImages = AtlIsAlphaBitmapResource(image);

			if(!pT->CreateInternalImageList(pData->wItemCount))
				return FALSE;
		}

#if _WTL_CMDBAR_VISTA_MENUS
		int nOldImageCount = ::ImageList_GetImageCount(m_hImageList);
#endif // _WTL_CMDBAR_VISTA_MENUS

		// Add bitmap to our image list
		CBitmap bmp;
		if(bMapped)
		{
			ATLASSERT(HIWORD(PtrToUlong(image.m_lpstr)) == 0);   // if mapped, must be a numeric ID
			int nIDImage = (int)(short)LOWORD(PtrToUlong(image.m_lpstr));
			bmp.LoadMappedBitmap(nIDImage, (WORD)nFlags, lpColorMap, nMapSize);
		}
		else
		{
			if(m_bAlphaImages)
				bmp = (HBITMAP)::LoadImage(ModuleHelper::GetResourceInstance(), image.m_lpstr, IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION | LR_DEFAULTSIZE);
			else
				bmp.LoadBitmap(image.m_lpstr);
		}
		ATLASSERT(bmp.m_hBitmap != NULL);
		if(bmp.m_hBitmap == NULL)
			return FALSE;
		if(::ImageList_AddMasked(m_hImageList, bmp, m_clrMask) == -1)
			return FALSE;

		// Fill the array with command IDs
		for(int i = 0; i < nItems; i++)
		{
			if(pItems[i] != 0)
				m_arrCommand.Add(pItems[i]);
		}

		int nImageCount = ::ImageList_GetImageCount(m_hImageList);
		ATLASSERT(nImageCount == m_arrCommand.GetSize());
		if(nImageCount != m_arrCommand.GetSize())
			return FALSE;

#if _WTL_CMDBAR_VISTA_MENUS
		if(RunTimeHelper::IsVista())
		{
			T* pT = static_cast<T*>(this);
			pT->_AddVistaBitmapsFromImageList(nOldImageCount, nImageCount - nOldImageCount);
			ATLASSERT(nImageCount == m_arrVistaBitmap.GetSize());
		}
#endif // _WTL_CMDBAR_VISTA_MENUS

		return TRUE;
	}

	BOOL AddBitmap(ATL::_U_STRINGorID bitmap, int nCommandID)
	{
		ATLASSERT(::IsWindow(m_hWnd));
		CBitmap bmp;
		bmp.LoadBitmap(bitmap.m_lpstr);
		if(bmp.m_hBitmap == NULL)
			return FALSE;
		return AddBitmap(bmp, nCommandID);
	}

	BOOL AddBitmap(HBITMAP hBitmap, UINT nCommandID)
	{
		ATLASSERT(::IsWindow(m_hWnd));
		T* pT = static_cast<T*>(this);
		// Create image list if it doesn't exist
		if(m_hImageList == NULL)
		{
			if(!pT->CreateInternalImageList(1))
				return FALSE;
		}
		// check bitmap size
		CBitmapHandle bmp = hBitmap;
		SIZE size = { 0, 0 };
		bmp.GetSize(size);
		if(size.cx != m_szBitmap.cx || size.cy != m_szBitmap.cy)
		{
			ATLASSERT(FALSE);   // must match size!
			return FALSE;
		}
		// add bitmap
		int nRet = ::ImageList_AddMasked(m_hImageList, hBitmap, m_clrMask);
		if(nRet == -1)
			return FALSE;
		BOOL bRet = m_arrCommand.Add((WORD)nCommandID);
		ATLASSERT(::ImageList_GetImageCount(m_hImageList) == m_arrCommand.GetSize());
#if _WTL_CMDBAR_VISTA_MENUS
		if(RunTimeHelper::IsVista())
		{
			pT->_AddVistaBitmapFromImageList(m_arrCommand.GetSize() - 1);
			ATLASSERT(m_arrVistaBitmap.GetSize() == m_arrCommand.GetSize());
		}
#endif // _WTL_CMDBAR_VISTA_MENUS
		return bRet;
	}

	BOOL AddIcon(ATL::_U_STRINGorID icon, UINT nCommandID)
	{
		ATLASSERT(::IsWindow(m_hWnd));
		HICON hIcon = ::LoadIcon(ModuleHelper::GetResourceInstance(), icon.m_lpstr);
		if(hIcon == NULL)
			return FALSE;
		return AddIcon(hIcon, nCommandID);
	}

	BOOL AddIcon(HICON hIcon, UINT nCommandID)
	{
		ATLASSERT(::IsWindow(m_hWnd));
		T* pT = static_cast<T*>(this);
		// create image list if it doesn't exist
		if(m_hImageList == NULL)
		{
			if(!pT->CreateInternalImageList(1))
				return FALSE;
		}

		int nRet = ::ImageList_AddIcon(m_hImageList, hIcon);
		if(nRet == -1)
			return FALSE;
		BOOL bRet = m_arrCommand.Add((WORD)nCommandID);
		ATLASSERT(::ImageList_GetImageCount(m_hImageList) == m_arrCommand.GetSize());
#if _WTL_CMDBAR_VISTA_MENUS
		if(RunTimeHelper::IsVista())
		{
			pT->_AddVistaBitmapFromImageList(m_arrCommand.GetSize() - 1);
			ATLASSERT(m_arrVistaBitmap.GetSize() == m_arrCommand.GetSize());
		}
#endif // _WTL_CMDBAR_VISTA_MENUS
		return bRet;
	}

	BOOL ReplaceBitmap(ATL::_U_STRINGorID bitmap, int nCommandID)
	{
		ATLASSERT(::IsWindow(m_hWnd));
		CBitmap bmp;
		bmp.LoadBitmap(bitmap.m_lpstr);
		if(bmp.m_hBitmap == NULL)
			return FALSE;
		return ReplaceBitmap(bmp, nCommandID);
	}

	BOOL ReplaceBitmap(HBITMAP hBitmap, UINT nCommandID)
	{
		ATLASSERT(::IsWindow(m_hWnd));
		BOOL bRet = FALSE;
		for(int i = 0; i < m_arrCommand.GetSize(); i++)
		{
			if(m_arrCommand[i] == nCommandID)
			{
				bRet = ::ImageList_Remove(m_hImageList, i);
				if(bRet)
				{
					m_arrCommand.RemoveAt(i);
#if _WTL_CMDBAR_VISTA_MENUS
					if(RunTimeHelper::IsVista())
					{
						if(m_arrVistaBitmap[i] != NULL)
							::DeleteObject(m_arrVistaBitmap[i]);
						m_arrVistaBitmap.RemoveAt(i);
					}
#endif // _WTL_CMDBAR_VISTA_MENUS
				}
				break;
			}
		}
		if(bRet)
			bRet = AddBitmap(hBitmap, nCommandID);
		return bRet;
	}

	BOOL ReplaceIcon(ATL::_U_STRINGorID icon, UINT nCommandID)
	{
		ATLASSERT(::IsWindow(m_hWnd));
		HICON hIcon = ::LoadIcon(ModuleHelper::GetResourceInstance(), icon.m_lpstr);
		if(hIcon == NULL)
			return FALSE;
		return ReplaceIcon(hIcon, nCommandID);
	}

	BOOL ReplaceIcon(HICON hIcon, UINT nCommandID)
	{
		ATLASSERT(::IsWindow(m_hWnd));
		BOOL bRet = FALSE;
		for(int i = 0; i < m_arrCommand.GetSize(); i++)
		{
			if(m_arrCommand[i] == nCommandID)
			{
				bRet = (::ImageList_ReplaceIcon(m_hImageList, i, hIcon) != -1);
#if _WTL_CMDBAR_VISTA_MENUS
				if(RunTimeHelper::IsVista() && bRet != FALSE)
				{
					T* pT = static_cast<T*>(this);
					pT->_ReplaceVistaBitmapFromImageList(i);
				}
#endif // _WTL_CMDBAR_VISTA_MENUS
				break;
			}
		}
		return bRet;
	}

	BOOL RemoveImage(int nCommandID)
	{
		ATLASSERT(::IsWindow(m_hWnd));

		BOOL bRet = FALSE;
		for(int i = 0; i < m_arrCommand.GetSize(); i++)
		{
			if(m_arrCommand[i] == nCommandID)
			{
				bRet = ::ImageList_Remove(m_hImageList, i);
				if(bRet)
				{
					m_arrCommand.RemoveAt(i);
#if _WTL_CMDBAR_VISTA_MENUS
					if(RunTimeHelper::IsVista())
					{
						if(m_arrVistaBitmap[i] != NULL)
							::DeleteObject(m_arrVistaBitmap[i]);
						m_arrVistaBitmap.RemoveAt(i);
					}
#endif // _WTL_CMDBAR_VISTA_MENUS
				}
				break;
			}
		}
		return bRet;
	}

	BOOL RemoveAllImages()
	{
		ATLASSERT(::IsWindow(m_hWnd));

		ATLTRACE2(atlTraceUI, 0, _T("CmdBar - Removing all images\n"));
		BOOL bRet = ::ImageList_RemoveAll(m_hImageList);
		if(bRet)
		{
			m_arrCommand.RemoveAll();
#if _WTL_CMDBAR_VISTA_MENUS
			for(int i = 0; i < m_arrVistaBitmap.GetSize(); i++)
			{
				if(m_arrVistaBitmap[i] != NULL)
					::DeleteObject(m_arrVistaBitmap[i]);
			}
			m_arrVistaBitmap.RemoveAll();
#endif // _WTL_CMDBAR_VISTA_MENUS
		}
		return bRet;
	}

	BOOL TrackPopupMenu(HMENU hMenu, UINT uFlags, int x, int y, LPTPMPARAMS lpParams = NULL)
	{
		ATLASSERT(::IsWindow(m_hWnd));
		ATLASSERT(::IsMenu(hMenu));
		if(!::IsMenu(hMenu))
			return FALSE;
		m_bContextMenu = true;
		if(m_bUseKeyboardCues)
			m_bShowKeyboardCues = m_bKeyboardInput;
		T* pT = static_cast<T*>(this);
		return pT->DoTrackPopupMenu(hMenu, uFlags, x, y, lpParams);
	}

	BOOL SetMDIClient(HWND /*hWndMDIClient*/)
	{
		// Use CMDICommandBarCtrl for MDI support
		ATLASSERT(FALSE);
		return FALSE;
	}

// Message map and handlers
	BEGIN_MSG_MAP(CCommandBarCtrlImpl)
		MESSAGE_HANDLER(WM_CREATE, OnCreate)
		MESSAGE_HANDLER(WM_DESTROY, OnDestroy)
		MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBackground)
		MESSAGE_HANDLER(WM_INITMENU, OnInitMenu)
		MESSAGE_HANDLER(WM_INITMENUPOPUP, OnInitMenuPopup)
		MESSAGE_HANDLER(WM_MENUSELECT, OnMenuSelect)
		MESSAGE_HANDLER(GetAutoPopupMessage(), OnInternalAutoPopup)
		MESSAGE_HANDLER(GetGetBarMessage(), OnInternalGetBar)
		MESSAGE_HANDLER(WM_SETTINGCHANGE, OnSettingChange)
		MESSAGE_HANDLER(WM_MENUCHAR, OnMenuChar)

		MESSAGE_HANDLER(WM_KEYDOWN, OnKeyDown)
		MESSAGE_HANDLER(WM_KEYUP, OnKeyUp)
		MESSAGE_HANDLER(WM_CHAR, OnChar)
		MESSAGE_HANDLER(WM_SYSKEYDOWN, OnSysKeyDown)
		MESSAGE_HANDLER(WM_SYSKEYUP, OnSysKeyUp)
		MESSAGE_HANDLER(WM_SYSCHAR, OnSysChar)
// public API handlers - these stay to support chevrons in atlframe.h
		MESSAGE_HANDLER(CBRM_GETMENU, OnAPIGetMenu)
		MESSAGE_HANDLER(CBRM_TRACKPOPUPMENU, OnAPITrackPopupMenu)
		MESSAGE_HANDLER(CBRM_GETCMDBAR, OnAPIGetCmdBar)

		MESSAGE_HANDLER(WM_DRAWITEM, OnDrawItem)
		MESSAGE_HANDLER(WM_MEASUREITEM, OnMeasureItem)

		MESSAGE_HANDLER(WM_FORWARDMSG, OnForwardMsg)
	ALT_MSG_MAP(1)   // Parent window messages
		NOTIFY_CODE_HANDLER(TBN_HOTITEMCHANGE, OnParentHotItemChange)
		NOTIFY_CODE_HANDLER(TBN_DROPDOWN, OnParentDropDown)
		MESSAGE_HANDLER(WM_INITMENUPOPUP, OnParentInitMenuPopup)
		MESSAGE_HANDLER(GetGetBarMessage(), OnParentInternalGetBar)
		MESSAGE_HANDLER(WM_SYSCOMMAND, OnParentSysCommand)
		MESSAGE_HANDLER(CBRM_GETMENU, OnParentAPIGetMenu)
		MESSAGE_HANDLER(WM_MENUCHAR, OnParentMenuChar)
		MESSAGE_HANDLER(CBRM_TRACKPOPUPMENU, OnParentAPITrackPopupMenu)
		MESSAGE_HANDLER(CBRM_GETCMDBAR, OnParentAPIGetCmdBar)
		MESSAGE_HANDLER(WM_SETTINGCHANGE, OnParentSettingChange)

		MESSAGE_HANDLER(WM_DRAWITEM, OnParentDrawItem)
		MESSAGE_HANDLER(WM_MEASUREITEM, OnParentMeasureItem)

		MESSAGE_HANDLER(WM_ACTIVATE, OnParentActivate)
		NOTIFY_CODE_HANDLER(NM_CUSTOMDRAW, OnParentCustomDraw)
	ALT_MSG_MAP(2)   // MDI client window messages
		// Use CMDICommandBarCtrl for MDI support
	ALT_MSG_MAP(3)   // Message hook messages
		MESSAGE_HANDLER(WM_MOUSEMOVE, OnHookMouseMove)
		MESSAGE_HANDLER(WM_SYSKEYDOWN, OnHookSysKeyDown)
		MESSAGE_HANDLER(WM_SYSKEYUP, OnHookSysKeyUp)
		MESSAGE_HANDLER(WM_SYSCHAR, OnHookSysChar)
		MESSAGE_HANDLER(WM_KEYDOWN, OnHookKeyDown)
		MESSAGE_HANDLER(WM_NEXTMENU, OnHookNextMenu)
		MESSAGE_HANDLER(WM_CHAR, OnHookChar)
	END_MSG_MAP()

	LRESULT OnForwardMsg(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& /*bHandled*/)
	{
		LPMSG pMsg = (LPMSG)lParam;
		if(pMsg->message >= WM_MOUSEFIRST && pMsg->message <= WM_MOUSELAST)
			m_bKeyboardInput = false;
		else if(pMsg->message >= WM_KEYFIRST && pMsg->message <= WM_KEYLAST)
			m_bKeyboardInput = true;
		LRESULT lRet = 0;
		ProcessWindowMessage(pMsg->hwnd, pMsg->message, pMsg->wParam, pMsg->lParam, lRet, 3);
		return lRet;
	}

	LRESULT OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/)
	{
		// Let the toolbar initialize itself
		LRESULT lRet = DefWindowProc(uMsg, wParam, lParam);
		// get and use system settings
		T* pT = static_cast<T*>(this);
		pT->GetSystemSettings();
		// Parent init
		ATL::CWindow wndParent = GetParent();
		ATL::CWindow wndTopLevelParent = wndParent.GetTopLevelParent();
		m_wndParent.SubclassWindow(wndTopLevelParent);
		// Toolbar Init
		SetButtonStructSize();
		SetImageList(NULL);

		// Create message hook if needed
		CWindowCreateCriticalSectionLock lock;
		if(FAILED(lock.Lock()))
		{
			ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to lock critical section in CCommandBarCtrlImpl::OnCreate.\n"));
			ATLASSERT(FALSE);
			return -1;
		}

		if(s_pmapMsgHook == NULL)
		{
			ATLTRY(s_pmapMsgHook = new CMsgHookMap);
			ATLASSERT(s_pmapMsgHook != NULL);
		}

		if(s_pmapMsgHook != NULL)
		{
			DWORD dwThreadID = ::GetCurrentThreadId();
			_MsgHookData* pData = s_pmapMsgHook->Lookup(dwThreadID);
			if(pData == NULL)
			{
				ATLTRY(pData = new _MsgHookData);
				ATLASSERT(pData != NULL);
				HHOOK hMsgHook = ::SetWindowsHookEx(WH_GETMESSAGE, MessageHookProc, ModuleHelper::GetModuleInstance(), dwThreadID);
				ATLASSERT(hMsgHook != NULL);
				if(pData != NULL && hMsgHook != NULL)
				{
					pData->hMsgHook = hMsgHook;
					pData->dwUsage = 1;
					BOOL bRet = s_pmapMsgHook->Add(dwThreadID, pData);
					bRet;
					ATLASSERT(bRet);
				}
			}
			else
			{
				(pData->dwUsage)++;
			}
		}
		lock.Unlock();

		// Get layout
#if (WINVER >= 0x0500)
		m_bLayoutRTL = ((GetExStyle() & WS_EX_LAYOUTRTL) != 0);
#endif // (WINVER >= 0x0500)

		return lRet;
	}

	LRESULT OnDestroy(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/)
	{
		LRESULT lRet = DefWindowProc(uMsg, wParam, lParam);

#if _WTL_CMDBAR_VISTA_MENUS
		if(m_bVistaMenus && (m_hMenu != NULL))
		{
			T* pT = static_cast<T*>(this);
			pT->_RemoveVistaBitmapsFromMenu();
		}

		for(int i = 0; i < m_arrVistaBitmap.GetSize(); i++)
		{
			if(m_arrVistaBitmap[i] != NULL)
				::DeleteObject(m_arrVistaBitmap[i]);
		}
#endif // _WTL_CMDBAR_VISTA_MENUS

		if(m_bAttachedMenu)   // nothing to do in this mode
			return lRet;

		CWindowCreateCriticalSectionLock lock;
		if(FAILED(lock.Lock()))
		{
			ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to lock critical section in CCommandBarCtrlImpl::OnDestroy.\n"));
			ATLASSERT(FALSE);
			return lRet;
		}

		if(s_pmapMsgHook != NULL)
		{
			DWORD dwThreadID = ::GetCurrentThreadId();
			_MsgHookData* pData = s_pmapMsgHook->Lookup(dwThreadID);
			if(pData != NULL)
			{
				(pData->dwUsage)--;
				if(pData->dwUsage == 0)
				{
					BOOL bRet = ::UnhookWindowsHookEx(pData->hMsgHook);
					ATLASSERT(bRet);
					bRet = s_pmapMsgHook->Remove(dwThreadID);
					ATLASSERT(bRet);
					if(bRet)
						delete pData;
				}

				if(s_pmapMsgHook->GetSize() == 0)
				{
					delete s_pmapMsgHook;
					s_pmapMsgHook = NULL;
				}
			}
		}

		lock.Unlock();

		return lRet;
	}

	LRESULT OnKeyDown(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
	{
#ifdef _CMDBAR_EXTRA_TRACE
		ATLTRACE2(atlTraceUI, 0, _T("CmdBar - OnKeyDown\n"));
#endif
		bHandled = FALSE;
		// Simulate Alt+Space for the parent
		if(wParam == VK_SPACE)
		{
			m_wndParent.PostMessage(WM_SYSKEYDOWN, wParam, lParam | (1 << 29));
			bHandled = TRUE;
		}
#if (_WIN32_IE >= 0x0500)
		else if(wParam == VK_LEFT || wParam == VK_RIGHT)
		{
			WPARAM wpNext = m_bLayoutRTL ? VK_LEFT : VK_RIGHT;

			if(!m_bMenuActive)
			{
				T* pT = static_cast<T*>(this);
				int nBtn = GetHotItem();
				int nNextBtn = (wParam == wpNext) ? pT->GetNextMenuItem(nBtn) : pT->GetPreviousMenuItem(nBtn);
				if(nNextBtn == -2)
				{
					SetHotItem(-1);
					if(pT->DisplayChevronMenu())
						bHandled = TRUE;
				}
			}
		}
#endif // (_WIN32_IE >= 0x0500)
		return 0;
	}

	LRESULT OnKeyUp(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled)
	{
#ifdef _CMDBAR_EXTRA_TRACE
		ATLTRACE2(atlTraceUI, 0, _T("CmdBar - OnKeyUp\n"));
#endif
		if(wParam != VK_SPACE)
			bHandled = FALSE;
		return 0;
	}

	LRESULT OnChar(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled)
	{
#ifdef _CMDBAR_EXTRA_TRACE
		ATLTRACE2(atlTraceUI, 0, _T("CmdBar - OnChar\n"));
#endif
		if(wParam != VK_SPACE)
			bHandled = FALSE;
		else
			return 0;
		// Security
		if(!m_wndParent.IsWindowEnabled() || ::GetFocus() != m_hWnd)
			return 0;

		// Handle mnemonic press when we have focus
		int nBtn = 0;
		if(wParam != VK_RETURN && !MapAccelerator((TCHAR)LOWORD(wParam), nBtn))
		{
#if (_WIN32_IE >= 0x0500)
			if((TCHAR)LOWORD(wParam) != _chChevronShortcut)
#endif // (_WIN32_IE >= 0x0500)
				::MessageBeep(0);
		}
		else
		{
#if (_WIN32_IE >= 0x0500)
			RECT rcClient = { 0 };
			GetClientRect(&rcClient);
			RECT rcBtn = { 0 };
			GetItemRect(nBtn, &rcBtn);
			TBBUTTON tbb = { 0 };
			GetButton(nBtn, &tbb);
			if((tbb.fsState & TBSTATE_ENABLED) != 0 && (tbb.fsState & TBSTATE_HIDDEN) == 0 && rcBtn.right <= rcClient.right)
			{
#endif // (_WIN32_IE >= 0x0500)
				PostMessage(WM_KEYDOWN, VK_DOWN, 0L);
				if(wParam != VK_RETURN)
					SetHotItem(nBtn);
#if (_WIN32_IE >= 0x0500)
			}
			else
			{
				::MessageBeep(0);
				bHandled = TRUE;
			}
#endif // (_WIN32_IE >= 0x0500)
		}
		return 0;
	}

	LRESULT OnSysKeyDown(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
	{
#ifdef _CMDBAR_EXTRA_TRACE
		ATLTRACE2(atlTraceUI, 0, _T("CmdBar - OnSysKeyDown\n"));
#endif
		bHandled = FALSE;
		return 0;
	}

	LRESULT OnSysKeyUp(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
	{
#ifdef _CMDBAR_EXTRA_TRACE
		ATLTRACE2(atlTraceUI, 0, _T("CmdBar - OnSysKeyUp\n"));
#endif
		bHandled = FALSE;
		return 0;
	}

	LRESULT OnSysChar(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
	{
#ifdef _CMDBAR_EXTRA_TRACE
		ATLTRACE2(atlTraceUI, 0, _T("CmdBar - OnSysChar\n"));
#endif
		bHandled = FALSE;
		return 0;
	}

	LRESULT OnEraseBackground(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled)
	{
		if(m_bAttachedMenu || (m_dwExtendedStyle & CBR_EX_TRANSPARENT))
		{
			bHandled = FALSE;
			return 0;
		}

		CDCHandle dc = (HDC)wParam;
		RECT rect = { 0 };
		GetClientRect(&rect);
		dc.FillRect(&rect, COLOR_MENU);

		return 1;   // don't do the default erase
	}

	LRESULT OnInitMenu(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
	{
		int nIndex = GetHotItem();
		SendMessage(WM_MENUSELECT, MAKEWPARAM(nIndex, MF_POPUP|MF_HILITE), (LPARAM)m_hMenu);
		bHandled = FALSE;
		return 1;
	}

	LRESULT OnInitMenuPopup(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
	{
		if((BOOL)HIWORD(lParam))   // System menu, do nothing
		{
			bHandled = FALSE;
			return 1;
		}

		if(!(m_bAttachedMenu || m_bMenuActive))   // Not attached or ours, do nothing
		{
			bHandled = FALSE;
			return 1;
		}

#ifdef _CMDBAR_EXTRA_TRACE
		ATLTRACE2(atlTraceUI, 0, _T("CmdBar - OnInitMenuPopup\n"));
#endif
		// forward to the parent or subclassed window, so it can handle update UI
		LRESULT lRet = 0;
		if(m_bAttachedMenu)
			lRet = DefWindowProc(uMsg, wParam, (lParam || m_bContextMenu) ? lParam : GetHotItem());
		else
			lRet = m_wndParent.DefWindowProc(uMsg, wParam, (lParam || m_bContextMenu) ? lParam : GetHotItem());

#if _WTL_CMDBAR_VISTA_MENUS
		// If Vista menus are active, just set bitmaps and return
		if(m_bVistaMenus)
		{
			CMenuHandle menu = (HMENU)wParam;
			ATLASSERT(menu.m_hMenu != NULL);

			for(int i = 0; i < menu.GetMenuItemCount(); i++)
			{
				WORD nID = (WORD)menu.GetMenuItemID(i);
				int nIndex = m_arrCommand.Find(nID);

				CMenuItemInfo mii;
				mii.fMask = MIIM_BITMAP;
				mii.hbmpItem = (m_bImagesVisible && (nIndex != -1)) ? m_arrVistaBitmap[nIndex] : NULL;
				menu.SetMenuItemInfo(i, TRUE, &mii);
			}

			return lRet;
		}
#endif // _WTL_CMDBAR_VISTA_MENUS

		// Convert menu items to ownerdraw, add our data
		if(m_bImagesVisible)
		{
			CMenuHandle menuPopup = (HMENU)wParam;
			ATLASSERT(menuPopup.m_hMenu != NULL);

			T* pT = static_cast<T*>(this);
			pT;   // avoid level 4 warning
			TCHAR szString[pT->_nMaxMenuItemTextLength];
			BOOL bRet = FALSE;
			for(int i = 0; i < menuPopup.GetMenuItemCount(); i++)
			{
				CMenuItemInfo mii;
				mii.cch = pT->_nMaxMenuItemTextLength;
				mii.fMask = MIIM_CHECKMARKS | MIIM_DATA | MIIM_ID | MIIM_STATE | MIIM_SUBMENU | MIIM_TYPE;
				mii.dwTypeData = szString;
				bRet = menuPopup.GetMenuItemInfo(i, TRUE, &mii);
				ATLASSERT(bRet);

				if(!(mii.fType & MFT_OWNERDRAW))   // Not already an ownerdraw item
				{
					mii.fMask = MIIM_DATA | MIIM_TYPE | MIIM_STATE;
					_MenuItemData* pMI = NULL;
					ATLTRY(pMI = new _MenuItemData);
					ATLASSERT(pMI != NULL);
					if(pMI != NULL)
					{
						pMI->fType = mii.fType;
						pMI->fState = mii.fState;
						mii.fType |= MFT_OWNERDRAW;
						pMI->iButton = -1;
						for(int j = 0; j < m_arrCommand.GetSize(); j++)
						{
							if(m_arrCommand[j] == mii.wID)
							{
								pMI->iButton = j;
								break;
							}
						}
						int cchLen = lstrlen(szString) + 1;
						pMI->lpstrText = NULL;
						ATLTRY(pMI->lpstrText = new TCHAR[cchLen]);
						ATLASSERT(pMI->lpstrText != NULL);
						if(pMI->lpstrText != NULL)
							SecureHelper::strcpy_x(pMI->lpstrText, cchLen, szString);
						mii.dwItemData = (ULONG_PTR)pMI;
						bRet = menuPopup.SetMenuItemInfo(i, TRUE, &mii);
						ATLASSERT(bRet);
					}
				}
			}

			// Add it to the list
			m_stackMenuHandle.Push(menuPopup.m_hMenu);
		}

		return lRet;
	}

	LRESULT OnMenuSelect(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
	{
		if(!m_bAttachedMenu)   // Not attached, do nothing, forward to parent
		{
			m_bPopupItem = (lParam != NULL) && ((HMENU)lParam != m_hMenu) && (HIWORD(wParam) & MF_POPUP);
			if(m_wndParent.IsWindow())
				m_wndParent.SendMessage(uMsg, wParam, lParam);
			bHandled = FALSE;
			return 1;
		}

		// Check if a menu is closing, do a cleanup
		if(HIWORD(wParam) == 0xFFFF && lParam == NULL)   // Menu closing
		{
#ifdef _CMDBAR_EXTRA_TRACE
			ATLTRACE2(atlTraceUI, 0, _T("CmdBar - OnMenuSelect - CLOSING!!!!\n"));
#endif
			ATLASSERT(m_stackMenuWnd.GetSize() == 0);
			// Restore the menu items to the previous state for all menus that were converted
			if(m_bImagesVisible)
			{
				HMENU hMenu = NULL;
				while((hMenu = m_stackMenuHandle.Pop()) != NULL)
				{
					CMenuHandle menuPopup = hMenu;
					ATLASSERT(menuPopup.m_hMenu != NULL);
					// Restore state and delete menu item data
					BOOL bRet = FALSE;
					for(int i = 0; i < menuPopup.GetMenuItemCount(); i++)
					{
						CMenuItemInfo mii;
						mii.fMask = MIIM_DATA | MIIM_TYPE;
						bRet = menuPopup.GetMenuItemInfo(i, TRUE, &mii);
						ATLASSERT(bRet);

						_MenuItemData* pMI = (_MenuItemData*)mii.dwItemData;
						if(pMI != NULL && pMI->IsCmdBarMenuItem())
						{
							mii.fMask = MIIM_DATA | MIIM_TYPE | MIIM_STATE;
							mii.fType = pMI->fType;
							mii.dwTypeData = pMI->lpstrText;
							mii.cch = lstrlen(pMI->lpstrText);
							mii.dwItemData = NULL;

							bRet = menuPopup.SetMenuItemInfo(i, TRUE, &mii);
							ATLASSERT(bRet);

							delete [] pMI->lpstrText;
							pMI->dwMagic = 0x6666;
							delete pMI;
						}
					}
				}
			}
		}

		bHandled = FALSE;
		return 1;
	}

	LRESULT OnInternalAutoPopup(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& /*bHandled*/)
	{
		int nIndex = (int)wParam;
		T* pT = static_cast<T*>(this);
		pT->DoPopupMenu(nIndex, false);
		return 0;
	}

	LRESULT OnInternalGetBar(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& /*bHandled*/)
	{
		// Let's make sure we're not embedded in another process
		if((LPVOID)wParam != NULL)
			*((DWORD*)wParam) = GetCurrentProcessId();
		if(IsWindowVisible())
			return (LRESULT)static_cast<CCommandBarCtrlBase*>(this);
		else
			return NULL;
	}

	LRESULT OnSettingChange(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& /*bHandled*/)
	{
#ifndef SPI_GETKEYBOARDCUES
		const UINT SPI_SETKEYBOARDCUES = 0x100B;
#endif // !SPI_GETKEYBOARDCUES
#ifndef SPI_GETFLATMENU
		const UINT SPI_SETFLATMENU = 0x1023;
#endif // !SPI_GETFLATMENU

		if(wParam == SPI_SETNONCLIENTMETRICS || wParam == SPI_SETKEYBOARDCUES || wParam == SPI_SETFLATMENU)
		{
			T* pT = static_cast<T*>(this);
			pT->GetSystemSettings();
		}

		return 0;
	}

	LRESULT OnWindowPosChanging(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/)
	{
		LRESULT lRet = DefWindowProc(uMsg, wParam, lParam);

		LPWINDOWPOS lpWP = (LPWINDOWPOS)lParam;
		int cyMin = ::GetSystemMetrics(SM_CYMENU);
		if(lpWP->cy < cyMin)
		lpWP->cy = cyMin;

		return lRet;
	}

	LRESULT OnMenuChar(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
	{
#ifdef _CMDBAR_EXTRA_TRACE
		ATLTRACE2(atlTraceUI, 0, _T("CmdBar - OnMenuChar\n"));
#endif
		bHandled = TRUE;
		T* pT = static_cast<T*>(this);

		LRESULT lRet;
		if(m_bMenuActive && LOWORD(wParam) != 0x0D)
			lRet = 0;
		else
			lRet = MAKELRESULT(1, 1);

		if(m_bMenuActive && HIWORD(wParam) == MF_POPUP)
		{
			// Convert character to lower/uppercase and possibly Unicode, using current keyboard layout
			TCHAR ch = (TCHAR)LOWORD(wParam);
			CMenuHandle menu = (HMENU)lParam;
			int nCount = ::GetMenuItemCount(menu);
			int nRetCode = MNC_EXECUTE;
			BOOL bRet = FALSE;
			TCHAR szString[pT->_nMaxMenuItemTextLength];
			WORD wMnem = 0;
			bool bFound = false;
			for(int i = 0; i < nCount; i++)
			{
				CMenuItemInfo mii;
				mii.cch = pT->_nMaxMenuItemTextLength;
				mii.fMask = MIIM_CHECKMARKS | MIIM_DATA | MIIM_ID | MIIM_STATE | MIIM_SUBMENU | MIIM_TYPE;
				mii.dwTypeData = szString;
				bRet = menu.GetMenuItemInfo(i, TRUE, &mii);
				if(!bRet || (mii.fType & MFT_SEPARATOR))
					continue;
				_MenuItemData* pmd = (_MenuItemData*)mii.dwItemData;
				if(pmd != NULL && pmd->IsCmdBarMenuItem())
				{
					LPTSTR p = pmd->lpstrText;

					if(p != NULL)
					{
						while(*p && *p != _T('&'))
							p = ::CharNext(p);
						if(p != NULL && *p)
						{
							DWORD dwP = MAKELONG(*(++p), 0);
							DWORD dwC = MAKELONG(ch, 0);
							if(::CharLower((LPTSTR)ULongToPtr(dwP)) == ::CharLower((LPTSTR)ULongToPtr(dwC)))
							{
								if(!bFound)
								{
									wMnem = (WORD)i;
									bFound = true;
								}
								else
								{
									nRetCode = MNC_SELECT;
									break;
								}
							}
						}
					}
				}
			}
			if(bFound)
			{
				if(nRetCode == MNC_EXECUTE)
				{
					PostMessage(TB_SETHOTITEM, (WPARAM)-1, 0L);
					pT->GiveFocusBack();
				}
				bHandled = TRUE;
				lRet = MAKELRESULT(wMnem, nRetCode);
			}
		} 
		else if(!m_bMenuActive)
		{
			int nBtn = 0;
			if(!MapAccelerator((TCHAR)LOWORD(wParam), nBtn))
			{
				bHandled = FALSE;
				PostMessage(TB_SETHOTITEM, (WPARAM)-1, 0L);
				pT->GiveFocusBack();

#if (_WIN32_IE >= 0x0500)
				// check if we should display chevron menu
				if((TCHAR)LOWORD(wParam) == pT->_chChevronShortcut)
				{
					if(pT->DisplayChevronMenu())
						bHandled = TRUE;
				}
#endif // (_WIN32_IE >= 0x0500)
			}
			else if(m_wndParent.IsWindowEnabled())
			{
#if (_WIN32_IE >= 0x0500)
				RECT rcClient = { 0 };
				GetClientRect(&rcClient);
				RECT rcBtn = { 0 };
				GetItemRect(nBtn, &rcBtn);
				TBBUTTON tbb = { 0 };
				GetButton(nBtn, &tbb);
				if((tbb.fsState & TBSTATE_ENABLED) != 0 && (tbb.fsState & TBSTATE_HIDDEN) == 0 && rcBtn.right <= rcClient.right)
				{
#endif // (_WIN32_IE >= 0x0500)
					if(m_bUseKeyboardCues && !m_bShowKeyboardCues)
					{
						m_bAllowKeyboardCues = true;
						ShowKeyboardCues(true);
					}
					pT->TakeFocus();
					PostMessage(WM_KEYDOWN, VK_DOWN, 0L);
					SetHotItem(nBtn);
#if (_WIN32_IE >= 0x0500)
				}
				else
				{
					::MessageBeep(0);
				}
#endif // (_WIN32_IE >= 0x0500)
			}
		}

		return lRet;
	}

	LRESULT OnDrawItem(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& bHandled)
	{
		LPDRAWITEMSTRUCT lpDrawItemStruct = (LPDRAWITEMSTRUCT)lParam;
		_MenuItemData* pmd = (_MenuItemData*)lpDrawItemStruct->itemData;
		if(lpDrawItemStruct->CtlType == ODT_MENU && pmd != NULL && pmd->IsCmdBarMenuItem())
		{
			T* pT = static_cast<T*>(this);
			pT->DrawItem(lpDrawItemStruct);
		}
		else
		{
			bHandled = FALSE;
		}
		return (LRESULT)TRUE;
	}

	LRESULT OnMeasureItem(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& bHandled)
	{
		LPMEASUREITEMSTRUCT lpMeasureItemStruct = (LPMEASUREITEMSTRUCT)lParam;
		_MenuItemData* pmd = (_MenuItemData*)lpMeasureItemStruct->itemData;
		if(lpMeasureItemStruct->CtlType == ODT_MENU && pmd != NULL && pmd->IsCmdBarMenuItem())
		{
			T* pT = static_cast<T*>(this);
			pT->MeasureItem(lpMeasureItemStruct);
		}
		else
		{
			bHandled = FALSE;
		}
		return (LRESULT)TRUE;
	}

// API message handlers
	LRESULT OnAPIGetMenu(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
	{
		return (LRESULT)m_hMenu;
	}

	LRESULT OnAPITrackPopupMenu(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& /*bHandled*/)
	{
		if(lParam == NULL)
			return FALSE;
		LPCBRPOPUPMENU lpCBRPopupMenu = (LPCBRPOPUPMENU)lParam;
		if(lpCBRPopupMenu->cbSize != sizeof(CBRPOPUPMENU))
			return FALSE;

		T* pT = static_cast<T*>(this);
		return pT->TrackPopupMenu(lpCBRPopupMenu->hMenu, lpCBRPopupMenu->uFlags, lpCBRPopupMenu->x, lpCBRPopupMenu->y, lpCBRPopupMenu->lptpm);
	}

	LRESULT OnAPIGetCmdBar(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
	{
		return (LRESULT)m_hWnd;
	}

// Parent window message handlers
	LRESULT OnParentHotItemChange(int /*idCtrl*/, LPNMHDR pnmh, BOOL& bHandled)
	{
		LPNMTBHOTITEM lpNMHT = (LPNMTBHOTITEM)pnmh;

		// Check if this comes from us
		if(pnmh->hwndFrom != m_hWnd)
		{
			bHandled = FALSE;
			return 0;
		}

		bool bBlockTracking = false;
		if((m_dwExtendedStyle & CBR_EX_TRACKALWAYS) == 0)
		{
			DWORD dwProcessID;
			::GetWindowThreadProcessId(::GetActiveWindow(), &dwProcessID);
			bBlockTracking = (::GetCurrentProcessId() != dwProcessID);
		}

		if((!m_wndParent.IsWindowEnabled() || bBlockTracking) && (lpNMHT->dwFlags & HICF_MOUSE))
		{
			return 1;
		}
		else
		{
#ifndef HICF_LMOUSE
			const DWORD HICF_LMOUSE = 0x00000080;   // left mouse button selected
#endif
			bHandled = FALSE;

			// Send WM_MENUSELECT to the app if it needs to display a status text
			if(!(lpNMHT->dwFlags & HICF_MOUSE)
				&& !(lpNMHT->dwFlags & HICF_ACCELERATOR)
				&& !(lpNMHT->dwFlags & HICF_LMOUSE))
			{
				if(lpNMHT->dwFlags & HICF_ENTERING)
					m_wndParent.SendMessage(WM_MENUSELECT, 0, (LPARAM)m_hMenu);
				if(lpNMHT->dwFlags & HICF_LEAVING)
					m_wndParent.SendMessage(WM_MENUSELECT, MAKEWPARAM(0, 0xFFFF), NULL);
			}

			return 0;
		}
	}

	LRESULT OnParentDropDown(int /*idCtrl*/, LPNMHDR pnmh, BOOL& bHandled)
	{
		// Check if this comes from us
		if(pnmh->hwndFrom != m_hWnd)
		{
			bHandled = FALSE;
			return 1;
		}

		T* pT = static_cast<T*>(this);
		if(::GetFocus() != m_hWnd)
			pT->TakeFocus();
		LPNMTOOLBAR pNMToolBar = (LPNMTOOLBAR)pnmh;
		int nIndex = CommandToIndex(pNMToolBar->iItem);
		m_bContextMenu = false;
		m_bEscapePressed = false;
		pT->DoPopupMenu(nIndex, true);

		return TBDDRET_DEFAULT;
	}

	LRESULT OnParentInitMenuPopup(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
	{
		return OnInitMenuPopup(uMsg, wParam, lParam, bHandled);
	}

	LRESULT OnParentInternalGetBar(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
	{
		return OnInternalGetBar(uMsg, wParam, lParam, bHandled);
	}

	LRESULT OnParentSysCommand(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled)
	{
		bHandled = FALSE;
		if((m_uSysKey == VK_MENU 
			|| (m_uSysKey == VK_F10 && !(::GetKeyState(VK_SHIFT) & 0x80))
			|| m_uSysKey == VK_SPACE) 
			&& wParam == SC_KEYMENU)
		{
			T* pT = static_cast<T*>(this);
			if(::GetFocus() == m_hWnd)
			{
				pT->GiveFocusBack();   // exit menu "loop"
				PostMessage(TB_SETHOTITEM, (WPARAM)-1, 0L);
			}
			else if(m_uSysKey != VK_SPACE && !m_bSkipMsg)
			{
				if(m_bUseKeyboardCues && !m_bShowKeyboardCues && m_bAllowKeyboardCues)
					ShowKeyboardCues(true);

				pT->TakeFocus();      // enter menu "loop"
				bHandled = TRUE;
			}
			else if(m_uSysKey != VK_SPACE)
			{
				bHandled = TRUE;
			}
		}
		m_bSkipMsg = false;
		return 0;
	}

	LRESULT OnParentAPIGetMenu(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
	{
		return OnAPIGetMenu(uMsg, wParam, lParam, bHandled);
	}

	LRESULT OnParentMenuChar(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
	{
		return OnMenuChar(uMsg, wParam, lParam, bHandled);
	}

	LRESULT OnParentAPITrackPopupMenu(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
	{
		return OnAPITrackPopupMenu(uMsg, wParam, lParam, bHandled);
	}

	LRESULT OnParentAPIGetCmdBar(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
	{
		return OnAPIGetCmdBar(uMsg, wParam, lParam, bHandled);
	}

	LRESULT OnParentSettingChange(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
	{
		OnSettingChange(uMsg, wParam, lParam, bHandled);
		bHandled = FALSE;
		return 1;
	}

	LRESULT OnParentDrawItem(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
	{
		return OnDrawItem(uMsg, wParam, lParam, bHandled);
	}

	LRESULT OnParentMeasureItem(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
	{
		return OnMeasureItem(uMsg, wParam, lParam, bHandled);
	}

	LRESULT OnParentActivate(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled)
	{
		m_bParentActive = (LOWORD(wParam) != WA_INACTIVE);
		if(!m_bParentActive && m_bUseKeyboardCues && m_bShowKeyboardCues)
		{
			ShowKeyboardCues(false);   // this will repaint our window
		}
		else
		{
			Invalidate();
			UpdateWindow();
		}
		bHandled = FALSE;
		return 1;
	}

	LRESULT OnParentCustomDraw(int /*idCtrl*/, LPNMHDR pnmh, BOOL& bHandled)
	{
		LRESULT lRet = CDRF_DODEFAULT;
		bHandled = FALSE;
		if(pnmh->hwndFrom == m_hWnd)
		{
			LPNMTBCUSTOMDRAW lpTBCustomDraw = (LPNMTBCUSTOMDRAW)pnmh;
			if(lpTBCustomDraw->nmcd.dwDrawStage == CDDS_PREPAINT)
			{
				lRet = CDRF_NOTIFYITEMDRAW;
				bHandled = TRUE;
			}
			else if(lpTBCustomDraw->nmcd.dwDrawStage == CDDS_ITEMPREPAINT)
			{
				if(m_bFlatMenus)
				{
#ifndef COLOR_MENUHILIGHT
					const int COLOR_MENUHILIGHT = 29;
#endif // !COLOR_MENUHILIGHT
					bool bDisabled = ((lpTBCustomDraw->nmcd.uItemState & CDIS_DISABLED) == CDIS_DISABLED);
					if(!bDisabled && ((lpTBCustomDraw->nmcd.uItemState & CDIS_HOT) == CDIS_HOT || 
						(lpTBCustomDraw->nmcd.uItemState & CDIS_SELECTED) == CDIS_SELECTED))
					{
						::FillRect(lpTBCustomDraw->nmcd.hdc, &lpTBCustomDraw->nmcd.rc, ::GetSysColorBrush(COLOR_MENUHILIGHT));
						::FrameRect(lpTBCustomDraw->nmcd.hdc, &lpTBCustomDraw->nmcd.rc, ::GetSysColorBrush(COLOR_HIGHLIGHT));
						lpTBCustomDraw->clrText = ::GetSysColor(m_bParentActive ? COLOR_HIGHLIGHTTEXT : COLOR_GRAYTEXT);
					}
					else if(bDisabled || !m_bParentActive)
					{
						lpTBCustomDraw->clrText = ::GetSysColor(COLOR_GRAYTEXT);
					}
					CDCHandle dc = lpTBCustomDraw->nmcd.hdc;
					dc.SetTextColor(lpTBCustomDraw->clrText);
					dc.SetBkMode(lpTBCustomDraw->nStringBkMode);
					HFONT hFont = GetFont();
					HFONT hFontOld = NULL;
					if(hFont != NULL)
						hFontOld = dc.SelectFont(hFont);
					const int cchText = 200;
					TCHAR szText[cchText] = { 0 };
					TBBUTTONINFO tbbi = { 0 };
					tbbi.cbSize = sizeof(TBBUTTONINFO);
					tbbi.dwMask = TBIF_TEXT;
					tbbi.pszText = szText;
					tbbi.cchText = cchText;
					GetButtonInfo((int)lpTBCustomDraw->nmcd.dwItemSpec, &tbbi);
					dc.DrawText(szText, -1, &lpTBCustomDraw->nmcd.rc, DT_SINGLELINE | DT_CENTER | DT_VCENTER | (m_bShowKeyboardCues ? 0 : DT_HIDEPREFIX));
					if(hFont != NULL)
						dc.SelectFont(hFontOld);
					lRet = CDRF_SKIPDEFAULT;
					bHandled = TRUE;
				}
				else if(!m_bParentActive)
				{
					lpTBCustomDraw->clrText = ::GetSysColor(COLOR_GRAYTEXT);
					bHandled = TRUE;
				}
			}
		}
		return lRet;
	}

// Message hook handlers
	LRESULT OnHookMouseMove(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
	{
		static POINT s_point = { -1, -1 };
		DWORD dwPoint = ::GetMessagePos();
		POINT point = { GET_X_LPARAM(dwPoint), GET_Y_LPARAM(dwPoint) };

		bHandled = FALSE;
		if(m_bMenuActive)
		{
			if(::WindowFromPoint(point) == m_hWnd)
			{
				ScreenToClient(&point);
				int nHit = HitTest(&point);

				if((point.x != s_point.x || point.y != s_point.y) && nHit >= 0 && nHit < ::GetMenuItemCount(m_hMenu) && nHit != m_nPopBtn && m_nPopBtn != -1)
				{
					TBBUTTON tbb = { 0 };
					GetButton(nHit, &tbb);
					if((tbb.fsState & TBSTATE_ENABLED) != 0)
					{
						m_nNextPopBtn = nHit | 0xFFFF0000;
						HWND hWndMenu = m_stackMenuWnd.GetCurrent();
						ATLASSERT(hWndMenu != NULL);

						// this one is needed to close a menu if mouse button was down
						::PostMessage(hWndMenu, WM_LBUTTONUP, 0, MAKELPARAM(point.x, point.y));
						// this one closes a popup menu
						::PostMessage(hWndMenu, WM_KEYDOWN, VK_ESCAPE, 0L);

						bHandled = TRUE;
					}
				}
			}
		}
		else
		{
			ScreenToClient(&point);
		}

		s_point = point;
		return 0;
	}

	LRESULT OnHookSysKeyDown(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled)
	{
		bHandled = FALSE;
#ifdef _CMDBAR_EXTRA_TRACE
		ATLTRACE2(atlTraceUI, 0, _T("CmdBar - Hook WM_SYSKEYDOWN (0x%2.2X)\n"), wParam);
#endif

		if(wParam == VK_MENU && m_bParentActive && m_bUseKeyboardCues && !m_bShowKeyboardCues && m_bAllowKeyboardCues)
			ShowKeyboardCues(true);

		if(wParam != VK_SPACE && !m_bMenuActive && ::GetFocus() == m_hWnd)
		{
			m_bAllowKeyboardCues = false;
			PostMessage(TB_SETHOTITEM, (WPARAM)-1, 0L);
			T* pT = static_cast<T*>(this);
			pT->GiveFocusBack();
			m_bSkipMsg = true;
		}
		else
		{
			if(wParam == VK_SPACE && m_bUseKeyboardCues && m_bShowKeyboardCues)
			{
				m_bAllowKeyboardCues = true;
				ShowKeyboardCues(false);
			}
			m_uSysKey = (UINT)wParam;
		}
		return 0;
	}

	LRESULT OnHookSysKeyUp(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled)
	{
		if(!m_bAllowKeyboardCues)
			m_bAllowKeyboardCues = true;
		bHandled = FALSE;
		wParam;
#ifdef _CMDBAR_EXTRA_TRACE
		ATLTRACE2(atlTraceUI, 0, _T("CmdBar - Hook WM_SYSKEYUP (0x%2.2X)\n"), wParam);
#endif
		return 0;
	}

	LRESULT OnHookSysChar(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled)
	{
		bHandled = FALSE;
#ifdef _CMDBAR_EXTRA_TRACE
		ATLTRACE2(atlTraceUI, 0, _T("CmdBar - Hook WM_SYSCHAR (0x%2.2X)\n"), wParam);
#endif

		if(!m_bMenuActive && m_hWndHook != m_hWnd && wParam != VK_SPACE)
			bHandled = TRUE;
		return 0;
	}

	LRESULT OnHookKeyDown(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled)
	{
#ifdef _CMDBAR_EXTRA_TRACE
		ATLTRACE2(atlTraceUI, 0, _T("CmdBar - Hook WM_KEYDOWN (0x%2.2X)\n"), wParam);
#endif
		bHandled = FALSE;
		T* pT = static_cast<T*>(this);

		if(wParam == VK_ESCAPE && m_stackMenuWnd.GetSize() <= 1)
		{
			if(m_bMenuActive && !m_bContextMenu)
			{
				int nHot = GetHotItem();
				if(nHot == -1)
					nHot = m_nPopBtn;
				if(nHot == -1)
					nHot = 0;
				SetHotItem(nHot);
				bHandled = TRUE;
				pT->TakeFocus();
				m_bEscapePressed = true; // To keep focus
				m_bSkipPostDown = false;
			}
			else if(::GetFocus() == m_hWnd && m_wndParent.IsWindow())
			{
				SetHotItem(-1);
				pT->GiveFocusBack();
				bHandled = TRUE;
			}
		}
		else if(wParam == VK_RETURN || wParam == VK_UP || wParam == VK_DOWN)
		{
			if(!m_bMenuActive && ::GetFocus() == m_hWnd && m_wndParent.IsWindow())
			{
				int nHot = GetHotItem();
				if(nHot != -1)
				{
					if(wParam != VK_RETURN)
					{
						if(!m_bSkipPostDown)
						{
// IE4 only: WM_KEYDOWN doesn't generate TBN_DROPDOWN, we need to simulate a mouse click
#if (_WIN32_IE < 0x0500)
							DWORD dwMajor = 0, dwMinor = 0;
							ATL::AtlGetCommCtrlVersion(&dwMajor, &dwMinor);
							if(dwMajor <= 4 || (dwMajor == 5 && dwMinor < 80))
							{
								RECT rect;
								GetItemRect(nHot, &rect);
								PostMessage(WM_LBUTTONDOWN, MK_LBUTTON, MAKELPARAM(rect.left, rect.top));
							}
#endif // (_WIN32_IE < 0x0500)
							PostMessage(WM_KEYDOWN, VK_DOWN, 0L);
							m_bSkipPostDown = true;
						}
						else
						{
							ATLTRACE2(atlTraceUI, 0, _T("CmdBar - skipping posting another VK_DOWN\n"));
							m_bSkipPostDown = false;
						}
					}
				}
				else
				{
					ATLTRACE2(atlTraceUI, 0, _T("CmdBar - Can't find hot button\n"));
				}
			}
			if(wParam == VK_RETURN && m_bMenuActive)
			{
				PostMessage(TB_SETHOTITEM, (WPARAM)-1, 0L);
				m_nNextPopBtn = -1;
				pT->GiveFocusBack();
			}
		}
		else if(wParam == VK_LEFT || wParam == VK_RIGHT)
		{
			WPARAM wpNext = m_bLayoutRTL ? VK_LEFT : VK_RIGHT;
			WPARAM wpPrev = m_bLayoutRTL ? VK_RIGHT : VK_LEFT;

			if(m_bMenuActive && !m_bContextMenu && !(wParam == wpNext && m_bPopupItem))
			{
				bool bAction = false;
				if(wParam == wpPrev && s_pCurrentBar->m_stackMenuWnd.GetSize() == 1)
				{
					m_nNextPopBtn = pT->GetPreviousMenuItem(m_nPopBtn);
					if(m_nNextPopBtn != -1)
						bAction = true;
				}
				else if(wParam == wpNext)
				{
					m_nNextPopBtn = pT->GetNextMenuItem(m_nPopBtn);
					if(m_nNextPopBtn != -1)
						bAction = true;
				}
				HWND hWndMenu = m_stackMenuWnd.GetCurrent();
				ATLASSERT(hWndMenu != NULL);

				// Close the popup menu
				if(bAction)
				{
					::PostMessage(hWndMenu, WM_KEYDOWN, VK_ESCAPE, 0L);
					if(wParam == wpNext)
					{
						int cItem = m_stackMenuWnd.GetSize() - 1;
						while(cItem >= 0)
						{
							hWndMenu = m_stackMenuWnd[cItem];
							if(hWndMenu != NULL)
								::PostMessage(hWndMenu, WM_KEYDOWN, VK_ESCAPE, 0L);
							cItem--;
						}
					}
#if (_WIN32_IE >= 0x0500)
					if(m_nNextPopBtn == -2)
					{
						m_nNextPopBtn = -1;
						pT->DisplayChevronMenu();
					}
#endif // (_WIN32_IE >= 0x0500)
					bHandled = TRUE;
				}
			}
		}
		return 0;
	}

	LRESULT OnHookNextMenu(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
	{
#ifdef _CMDBAR_EXTRA_TRACE
		ATLTRACE2(atlTraceUI, 0, _T("CmdBar - Hook WM_NEXTMENU\n"));
#endif
		bHandled = FALSE;
		return 1;
	}

 	LRESULT OnHookChar(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled)
	{
#ifdef _CMDBAR_EXTRA_TRACE
		ATLTRACE2(atlTraceUI, 0, _T("CmdBar - Hook WM_CHAR (0x%2.2X)\n"), wParam);
#endif
		bHandled = (wParam == VK_ESCAPE);
		return 0;
	}

// Implementation - ownerdraw overrideables and helpers
	void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
	{
		T* pT = static_cast<T*>(this);
		if(m_bFlatMenus)
			pT->DrawItemFlat(lpDrawItemStruct);
		else
			pT->DrawItem3D(lpDrawItemStruct);

	}

	void DrawItem3D(LPDRAWITEMSTRUCT lpDrawItemStruct)
	{
		_MenuItemData* pmd = (_MenuItemData*)lpDrawItemStruct->itemData;
		CDCHandle dc = lpDrawItemStruct->hDC;
		const RECT& rcItem = lpDrawItemStruct->rcItem;
		T* pT = static_cast<T*>(this);

		if(pmd->fType & MFT_SEPARATOR)
		{
			// draw separator
			RECT rc = rcItem;
			rc.top += (rc.bottom - rc.top) / 2;      // vertical center
			dc.DrawEdge(&rc, EDGE_ETCHED, BF_TOP);   // draw separator line
		}
		else		// not a separator
		{
			BOOL bDisabled = lpDrawItemStruct->itemState & ODS_GRAYED;
			BOOL bSelected = lpDrawItemStruct->itemState & ODS_SELECTED;
			BOOL bChecked = lpDrawItemStruct->itemState & ODS_CHECKED;
			BOOL bHasImage = FALSE;

			if(LOWORD(lpDrawItemStruct->itemID) == (WORD)-1)
				bSelected = FALSE;
			RECT rcButn = { rcItem.left, rcItem.top, rcItem.left + m_szButton.cx, rcItem.top + m_szButton.cy };   // button rect
			::OffsetRect(&rcButn, 0, ((rcItem.bottom - rcItem.top) - (rcButn.bottom - rcButn.top)) / 2);          // center vertically

			int iButton = pmd->iButton;
			if(iButton >= 0)
			{
				bHasImage = TRUE;

				// calc drawing point
				SIZE sz = { rcButn.right - rcButn.left - m_szBitmap.cx, rcButn.bottom - rcButn.top - m_szBitmap.cy };
				sz.cx /= 2;
				sz.cy /= 2;
				POINT point = { rcButn.left + sz.cx, rcButn.top + sz.cy };

				// fill background depending on state
				if(!bChecked || (bSelected && !bDisabled))
				{
					if(!bDisabled)
						dc.FillRect(&rcButn, (bChecked && !bSelected) ? COLOR_3DLIGHT : COLOR_MENU);
					else
						dc.FillRect(&rcButn, COLOR_MENU);
				}
				else
				{
					COLORREF crTxt = dc.SetTextColor(::GetSysColor(COLOR_BTNFACE));
					COLORREF crBk = dc.SetBkColor(::GetSysColor(COLOR_BTNHILIGHT));
					CBrush hbr(CDCHandle::GetHalftoneBrush());
					dc.SetBrushOrg(rcButn.left, rcButn.top);
					dc.FillRect(&rcButn, hbr);
					dc.SetTextColor(crTxt);
					dc.SetBkColor(crBk);
				}

				// draw disabled or normal
				if(!bDisabled)
				{
					// draw pushed-in or popped-out edge
					if(bSelected || bChecked)
					{
						RECT rc2 = rcButn;
						dc.DrawEdge(&rc2, bChecked ? BDR_SUNKENOUTER : BDR_RAISEDINNER, BF_RECT);
					}
					// draw the image
					::ImageList_Draw(m_hImageList, iButton, dc, point.x, point.y, ILD_TRANSPARENT);
				}
				else
				{
					HBRUSH hBrushBackground = bChecked ? NULL : ::GetSysColorBrush(COLOR_MENU);
					pT->DrawBitmapDisabled(dc, iButton, point, hBrushBackground);
				}
			}
			else
			{
				// no image - look for custom checked/unchecked bitmaps
				CMenuItemInfo info;
				info.fMask = MIIM_CHECKMARKS | MIIM_TYPE;
				::GetMenuItemInfo((HMENU)lpDrawItemStruct->hwndItem, lpDrawItemStruct->itemID, MF_BYCOMMAND, &info);
				if(bChecked || info.hbmpUnchecked != NULL)
				{
					BOOL bRadio = ((info.fType & MFT_RADIOCHECK) != 0);
					bHasImage = pT->DrawCheckmark(dc, rcButn, bSelected, bDisabled, bRadio, bChecked ? info.hbmpChecked : info.hbmpUnchecked);
				}
			}

			// draw item text
			int cxButn = m_szButton.cx;
			COLORREF colorBG = ::GetSysColor(bSelected ? COLOR_HIGHLIGHT : COLOR_MENU);
			if(bSelected || lpDrawItemStruct->itemAction == ODA_SELECT)
			{
				RECT rcBG = rcItem;
				if(bHasImage)
					rcBG.left += cxButn + s_kcxGap;
				dc.FillRect(&rcBG, bSelected ? COLOR_HIGHLIGHT : COLOR_MENU);
			}

			// calc text rectangle and colors
			RECT rcText = rcItem;
			rcText.left += cxButn + s_kcxGap + s_kcxTextMargin;
			rcText.right -= cxButn;
			dc.SetBkMode(TRANSPARENT);
			COLORREF colorText = ::GetSysColor(bDisabled ?  (bSelected ? COLOR_GRAYTEXT : COLOR_3DSHADOW) : (bSelected ? COLOR_HIGHLIGHTTEXT : COLOR_MENUTEXT));

			// font already selected by Windows
			if(bDisabled && (!bSelected || colorText == colorBG))
			{
				// disabled - draw shadow text shifted down and right 1 pixel (unles selected)
				RECT rcDisabled = rcText;
				::OffsetRect(&rcDisabled, 1, 1);
				pT->DrawMenuText(dc, rcDisabled, pmd->lpstrText, ::GetSysColor(COLOR_3DHILIGHT));
			}
			pT->DrawMenuText(dc, rcText, pmd->lpstrText, colorText); // finally!
		}
	}

	void DrawItemFlat(LPDRAWITEMSTRUCT lpDrawItemStruct)
	{
		_MenuItemData* pmd = (_MenuItemData*)lpDrawItemStruct->itemData;
		CDCHandle dc = lpDrawItemStruct->hDC;
		const RECT& rcItem = lpDrawItemStruct->rcItem;
		T* pT = static_cast<T*>(this);

#ifndef COLOR_MENUHILIGHT
		const int COLOR_MENUHILIGHT = 29;
#endif // !COLOR_MENUHILIGHT

		BOOL bDisabled = lpDrawItemStruct->itemState & ODS_GRAYED;
		BOOL bSelected = lpDrawItemStruct->itemState & ODS_SELECTED;
		BOOL bChecked = lpDrawItemStruct->itemState & ODS_CHECKED;

		// paint background
		if(bSelected || lpDrawItemStruct->itemAction == ODA_SELECT)
		{
			if(bSelected)
			{
				dc.FillRect(&rcItem, ::GetSysColorBrush(COLOR_MENUHILIGHT));
				dc.FrameRect(&rcItem, ::GetSysColorBrush(COLOR_HIGHLIGHT));
			}
			else
			{
				dc.FillRect(&rcItem, ::GetSysColorBrush(COLOR_MENU));
			}
		}

		if(pmd->fType & MFT_SEPARATOR)
		{
			// draw separator
			RECT rc = rcItem;
			rc.top += (rc.bottom - rc.top) / 2;      // vertical center
			dc.DrawEdge(&rc, EDGE_ETCHED, BF_TOP);   // draw separator line
		}
		else		// not a separator
		{
			if(LOWORD(lpDrawItemStruct->itemID) == (WORD)-1)
				bSelected = FALSE;
			RECT rcButn = { rcItem.left, rcItem.top, rcItem.left + m_szButton.cx, rcItem.top + m_szButton.cy };   // button rect
			::OffsetRect(&rcButn, 0, ((rcItem.bottom - rcItem.top) - (rcButn.bottom - rcButn.top)) / 2);          // center vertically

			// draw background and border for checked items
			if(bChecked)
			{
				RECT rcCheck = rcButn;
				::InflateRect(&rcCheck, -1, -1);
				if(bSelected)
					dc.FillRect(&rcCheck, ::GetSysColorBrush(COLOR_MENU));
				dc.FrameRect(&rcCheck, ::GetSysColorBrush(COLOR_HIGHLIGHT));
			}

			int iButton = pmd->iButton;
			if(iButton >= 0)
			{
				// calc drawing point
				SIZE sz = { rcButn.right - rcButn.left - m_szBitmap.cx, rcButn.bottom - rcButn.top - m_szBitmap.cy };
				sz.cx /= 2;
				sz.cy /= 2;
				POINT point = { rcButn.left + sz.cx, rcButn.top + sz.cy };

				// draw disabled or normal
				if(!bDisabled)
				{
					::ImageList_Draw(m_hImageList, iButton, dc, point.x, point.y, ILD_TRANSPARENT);
				}
				else
				{
					HBRUSH hBrushBackground = ::GetSysColorBrush((bSelected && !(bDisabled && bChecked)) ? COLOR_MENUHILIGHT : COLOR_MENU);
					HBRUSH hBrushDisabledImage = ::GetSysColorBrush(COLOR_3DSHADOW);
					pT->DrawBitmapDisabled(dc, iButton, point, hBrushBackground, hBrushBackground, hBrushDisabledImage);
				}
			}
			else
			{
				// no image - look for custom checked/unchecked bitmaps
				CMenuItemInfo info;
				info.fMask = MIIM_CHECKMARKS | MIIM_TYPE;
				::GetMenuItemInfo((HMENU)lpDrawItemStruct->hwndItem, lpDrawItemStruct->itemID, MF_BYCOMMAND, &info);
				if(bChecked || info.hbmpUnchecked != NULL)
				{
					BOOL bRadio = ((info.fType & MFT_RADIOCHECK) != 0);
					pT->DrawCheckmark(dc, rcButn, bSelected, bDisabled, bRadio, bChecked ? info.hbmpChecked : info.hbmpUnchecked);
				}
			}

			// draw item text
			int cxButn = m_szButton.cx;
			// calc text rectangle and colors
			RECT rcText = rcItem;
			rcText.left += cxButn + s_kcxGap + s_kcxTextMargin;
			rcText.right -= cxButn;
			dc.SetBkMode(TRANSPARENT);
			COLORREF colorText = ::GetSysColor(bDisabled ?  (bSelected ? COLOR_GRAYTEXT : COLOR_3DSHADOW) : (bSelected ? COLOR_HIGHLIGHTTEXT : COLOR_MENUTEXT));

			pT->DrawMenuText(dc, rcText, pmd->lpstrText, colorText); // finally!
		}
	}

	void DrawMenuText(CDCHandle& dc, RECT& rc, LPCTSTR lpstrText, COLORREF color)
	{
		int nTab = -1;
		for(int i = 0; i < lstrlen(lpstrText); i++)
		{
			if(lpstrText[i] == _T('\t'))
			{
				nTab = i;
				break;
			}
		}
		dc.SetTextColor(color);
		dc.DrawText(lpstrText, nTab, &rc, DT_SINGLELINE | DT_LEFT | DT_VCENTER | (m_bShowKeyboardCues ? 0 : DT_HIDEPREFIX));
		if(nTab != -1)
			dc.DrawText(&lpstrText[nTab + 1], -1, &rc, DT_SINGLELINE | DT_RIGHT | DT_VCENTER | (m_bShowKeyboardCues ? 0 : DT_HIDEPREFIX));
	}

	void DrawBitmapDisabled(CDCHandle& dc, int nImage, POINT point,
			HBRUSH hBrushBackground = ::GetSysColorBrush(COLOR_3DFACE),
			HBRUSH hBrush3DEffect = ::GetSysColorBrush(COLOR_3DHILIGHT),
			HBRUSH hBrushDisabledImage = ::GetSysColorBrush(COLOR_3DSHADOW))
	{
#if (_WIN32_WINNT >= 0x0501) && (_WIN32_IE >= 0x0501)
		if(m_bAlphaImages)
		{
			IMAGELISTDRAWPARAMS ildp = { 0 };
			ildp.cbSize = sizeof(IMAGELISTDRAWPARAMS);
			ildp.himl = m_hImageList;
			ildp.i = nImage;
			ildp.hdcDst = dc;
			ildp.x = point.x;
			ildp.y = point.y;
			ildp.cx = 0;
			ildp.cy = 0;
			ildp.xBitmap = 0;
			ildp.yBitmap = 0;
			ildp.fStyle = ILD_TRANSPARENT;
			ildp.fState = ILS_SATURATE;
			ildp.Frame = 0;
			::ImageList_DrawIndirect(&ildp);
		}
		else
#endif // (_WIN32_WINNT >= 0x0501) && (_WIN32_IE >= 0x0501)
		{
			// create memory DC
			CDC dcMem;
			dcMem.CreateCompatibleDC(dc);
			// create mono or color bitmap
			CBitmap bmp;
			bmp.CreateCompatibleBitmap(dc, m_szBitmap.cx, m_szBitmap.cy);
			ATLASSERT(bmp.m_hBitmap != NULL);
			// draw image into memory DC--fill BG white first
			HBITMAP hBmpOld = dcMem.SelectBitmap(bmp);
			dcMem.PatBlt(0, 0, m_szBitmap.cx, m_szBitmap.cy, WHITENESS);
			// If white is the text color, we can't use the normal painting since
			// it would blend with the WHITENESS, but the mask is OK
			UINT uDrawStyle = (::GetSysColor(COLOR_BTNTEXT) == RGB(255, 255, 255)) ? ILD_MASK : ILD_NORMAL;
			::ImageList_Draw(m_hImageList, nImage, dcMem, 0, 0, uDrawStyle);
			dc.DitherBlt(point.x, point.y, m_szBitmap.cx, m_szBitmap.cy, dcMem, NULL, 0, 0, hBrushBackground, hBrush3DEffect, hBrushDisabledImage);
			dcMem.SelectBitmap(hBmpOld);   // restore
		}
	}

	// old name
	BOOL Draw3DCheckmark(CDCHandle& dc, const RECT& rc, BOOL bSelected, BOOL bDisabled, BOOL bRadio, HBITMAP hBmpCheck)
	{
		return DrawCheckmark(dc, rc, bSelected, bDisabled, bRadio, hBmpCheck);
	}

	BOOL DrawCheckmark(CDCHandle& dc, const RECT& rc, BOOL bSelected, BOOL bDisabled, BOOL bRadio, HBITMAP hBmpCheck)
	{
		// get checkmark bitmap, if none, use Windows standard
		SIZE size = { 0, 0 };
		CBitmapHandle bmp = hBmpCheck;
		if(hBmpCheck != NULL)
		{
			bmp.GetSize(size);
		}
		else
		{
			size.cx = ::GetSystemMetrics(SM_CXMENUCHECK); 
			size.cy = ::GetSystemMetrics(SM_CYMENUCHECK); 
			bmp.CreateCompatibleBitmap(dc, size.cx, size.cy);
			ATLASSERT(bmp.m_hBitmap != NULL);
		}
		// center bitmap in caller's rectangle
		RECT rcDest = rc;
		if((rc.right - rc.left) > size.cx)
		{
			rcDest.left = rc.left + (rc.right - rc.left - size.cx) / 2;
			rcDest.right = rcDest.left + size.cx;
		}
		if((rc.bottom - rc.top) > size.cy)
		{
			rcDest.top = rc.top + (rc.bottom - rc.top - size.cy) / 2;
			rcDest.bottom = rcDest.top + size.cy;
		}
		// paint background
		if(!m_bFlatMenus)
		{
			if(bSelected && !bDisabled)
			{
				dc.FillRect(&rcDest, COLOR_MENU);
			}
			else
			{
				COLORREF clrTextOld = dc.SetTextColor(::GetSysColor(COLOR_BTNFACE));
				COLORREF clrBkOld = dc.SetBkColor(::GetSysColor(COLOR_BTNHILIGHT));
				CBrush hbr(CDCHandle::GetHalftoneBrush());
				dc.SetBrushOrg(rcDest.left, rcDest.top);
				dc.FillRect(&rcDest, hbr);
				dc.SetTextColor(clrTextOld);
				dc.SetBkColor(clrBkOld);
			}
		}

		// create source image
		CDC dcSource;
		dcSource.CreateCompatibleDC(dc);
		HBITMAP hBmpOld = dcSource.SelectBitmap(bmp);
		// set colors
		const COLORREF clrBlack = RGB(0, 0, 0);
		const COLORREF clrWhite = RGB(255, 255, 255);
		COLORREF clrTextOld = dc.SetTextColor(clrBlack);
		COLORREF clrBkOld = dc.SetBkColor(clrWhite);
		// create mask
		CDC dcMask;
		dcMask.CreateCompatibleDC(dc);
		CBitmap bmpMask;
		bmpMask.CreateBitmap(size.cx, size.cy, 1, 1, NULL);
		HBITMAP hBmpOld1 = dcMask.SelectBitmap(bmpMask);

		// draw the checkmark transparently
		int cx = rcDest.right - rcDest.left;
		int cy = rcDest.bottom - rcDest.top;
		if(hBmpCheck != NULL)
		{
			// build mask based on transparent color	
			dcSource.SetBkColor(m_clrMask);
			dcMask.SetBkColor(clrBlack);
			dcMask.SetTextColor(clrWhite);
			dcMask.BitBlt(0, 0, size.cx, size.cy, dcSource, 0, 0, SRCCOPY);
			// draw bitmap using the mask
			dc.BitBlt(rcDest.left, rcDest.top, cx, cy, dcSource, 0, 0, SRCINVERT);
			dc.BitBlt(rcDest.left, rcDest.top, cx, cy, dcMask, 0, 0, SRCAND);
			dc.BitBlt(rcDest.left, rcDest.top, cx, cy, dcSource, 0, 0, SRCINVERT);
		}
		else
		{
			const DWORD ROP_DSno = 0x00BB0226L;
			const DWORD ROP_DSa = 0x008800C6L;
			const DWORD ROP_DSo = 0x00EE0086L;
			const DWORD ROP_DSna = 0x00220326L;

			// draw mask
			RECT rcSource = { 0, 0, __min(size.cx, rc.right - rc.left), __min(size.cy, rc.bottom - rc.top) };
			dcMask.DrawFrameControl(&rcSource, DFC_MENU, bRadio ? DFCS_MENUBULLET : DFCS_MENUCHECK);

			// draw shadow if disabled
			if(!m_bFlatMenus && bDisabled)
			{
				// offset by one pixel
				int x = rcDest.left + 1;
				int y = rcDest.top + 1;
				// paint source bitmap
				const int nColor = COLOR_3DHILIGHT;
				dcSource.FillRect(&rcSource, nColor);
				// draw checkmark - special case black and white colors
				COLORREF clrCheck = ::GetSysColor(nColor);
				if(clrCheck == clrWhite)
				{
					dc.BitBlt(x, y, cx, cy, dcMask,  0, 0,   ROP_DSno);
					dc.BitBlt(x, y, cx, cy, dcSource, 0, 0, ROP_DSa);
				}
				else
				{
					if(clrCheck != clrBlack)
					{
						ATLASSERT(dcSource.GetTextColor() == clrBlack);
						ATLASSERT(dcSource.GetBkColor() == clrWhite);
						dcSource.BitBlt(0, 0, size.cx, size.cy, dcMask, 0, 0, ROP_DSna);
					}
					dc.BitBlt(x, y, cx, cy, dcMask,  0,  0,  ROP_DSa);
					dc.BitBlt(x, y, cx, cy, dcSource, 0, 0, ROP_DSo);
				}
			}

			// paint source bitmap
			const int nColor = bDisabled ? COLOR_BTNSHADOW : COLOR_MENUTEXT;
			dcSource.FillRect(&rcSource, nColor);
			// draw checkmark - special case black and white colors
			COLORREF clrCheck = ::GetSysColor(nColor);
			if(clrCheck == clrWhite)
			{
				dc.BitBlt(rcDest.left, rcDest.top, cx, cy, dcMask,  0, 0,   ROP_DSno);
				dc.BitBlt(rcDest.left, rcDest.top, cx, cy, dcSource, 0, 0, ROP_DSa);
			}
			else
			{
				if(clrCheck != clrBlack)
				{
					ATLASSERT(dcSource.GetTextColor() == clrBlack);
					ATLASSERT(dcSource.GetBkColor() == clrWhite);
					dcSource.BitBlt(0, 0, size.cx, size.cy, dcMask, 0, 0, ROP_DSna);
				}
				dc.BitBlt(rcDest.left, rcDest.top, cx, cy, dcMask,  0,  0,  ROP_DSa);
				dc.BitBlt(rcDest.left, rcDest.top, cx, cy, dcSource, 0, 0, ROP_DSo);
			}
		}
		// restore all
		dc.SetTextColor(clrTextOld);
		dc.SetBkColor(clrBkOld);
		dcSource.SelectBitmap(hBmpOld);
		dcMask.SelectBitmap(hBmpOld1);
		if(hBmpCheck == NULL)
			bmp.DeleteObject();
		// draw pushed-in hilight
		if(!m_bFlatMenus && !bDisabled)
		{
			if(rc.right - rc.left > size.cx)
				::InflateRect(&rcDest, 1,1);   // inflate checkmark by one pixel all around
			dc.DrawEdge(&rcDest, BDR_SUNKENOUTER, BF_RECT);
		}

		return TRUE;
	}

	void MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct)
	{
		_MenuItemData* pmd = (_MenuItemData*)lpMeasureItemStruct->itemData;

		if(pmd->fType & MFT_SEPARATOR)   // separator - use half system height and zero width
		{
			lpMeasureItemStruct->itemHeight = ::GetSystemMetrics(SM_CYMENU) / 2;
			lpMeasureItemStruct->itemWidth  = 0;
		}
		else
		{
			// compute size of text - use DrawText with DT_CALCRECT
			CWindowDC dc(NULL);
			CFont fontBold;
			HFONT hOldFont = NULL;
			if(pmd->fState & MFS_DEFAULT)
			{
				// need bold version of font
				LOGFONT lf = { 0 };
				m_fontMenu.GetLogFont(lf);
				lf.lfWeight += 200;
				fontBold.CreateFontIndirect(&lf);
				ATLASSERT(fontBold.m_hFont != NULL);
				hOldFont = dc.SelectFont(fontBold);
			}
			else
			{
				hOldFont = dc.SelectFont(m_fontMenu);
			}

			RECT rcText = { 0, 0, 0, 0 };
			dc.DrawText(pmd->lpstrText, -1, &rcText, DT_SINGLELINE | DT_LEFT | DT_VCENTER | DT_CALCRECT);
			int cx = rcText.right - rcText.left;
			dc.SelectFont(hOldFont);

			LOGFONT lf = { 0 };
			m_fontMenu.GetLogFont(lf);
			int cy = lf.lfHeight;
			if(cy < 0)
				cy = -cy;
			const int cyMargin = 8;
			cy += cyMargin;

			// height of item is the bigger of these two
			lpMeasureItemStruct->itemHeight = __max(cy, (int)m_szButton.cy);

			// width is width of text plus a bunch of stuff
			cx += 2 * s_kcxTextMargin;   // L/R margin for readability
			cx += s_kcxGap;              // space between button and menu text
			cx += 2 * m_szButton.cx;     // button width (L=button; R=empty margin)
			cx += m_cxExtraSpacing;      // extra between item text and accelerator keys

			// Windows adds 1 to returned value
			cx -= ::GetSystemMetrics(SM_CXMENUCHECK) - 1;
			lpMeasureItemStruct->itemWidth = cx;   // done deal
		}
	}

// Implementation - Hook procs
	static LRESULT CALLBACK CreateHookProc(int nCode, WPARAM wParam, LPARAM lParam)
	{
		const int cchClassName = 7;
		TCHAR szClassName[cchClassName] = { 0 };

		if(nCode == HCBT_CREATEWND)
		{
			HWND hWndMenu = (HWND)wParam;
#ifdef _CMDBAR_EXTRA_TRACE
			ATLTRACE2(atlTraceUI, 0, _T("CmdBar - HCBT_CREATEWND (HWND = %8.8X)\n"), hWndMenu);
#endif

			::GetClassName(hWndMenu, szClassName, cchClassName);
			if(!lstrcmp(_T("#32768"), szClassName))
				s_pCurrentBar->m_stackMenuWnd.Push(hWndMenu);
		}
		else if(nCode == HCBT_DESTROYWND)
		{
			HWND hWndMenu = (HWND)wParam;
#ifdef _CMDBAR_EXTRA_TRACE
			ATLTRACE2(atlTraceUI, 0, _T("CmdBar - HCBT_DESTROYWND (HWND = %8.8X)\n"), hWndMenu);
#endif

			::GetClassName(hWndMenu, szClassName, cchClassName);
			if(!lstrcmp(_T("#32768"), szClassName))
			{
				ATLASSERT(hWndMenu == s_pCurrentBar->m_stackMenuWnd.GetCurrent());
				s_pCurrentBar->m_stackMenuWnd.Pop();
			}
		}

		return ::CallNextHookEx(s_hCreateHook, nCode, wParam, lParam);
	}

	static LRESULT CALLBACK MessageHookProc(int nCode, WPARAM wParam, LPARAM lParam)
	{
		LPMSG pMsg = (LPMSG)lParam;

		if(nCode == HC_ACTION && wParam == PM_REMOVE && pMsg->message != GetGetBarMessage() && pMsg->message != WM_FORWARDMSG)
		{
			CCommandBarCtrlBase* pCmdBar = NULL;
			HWND hWnd = pMsg->hwnd;
			DWORD dwPID = 0;
			while(pCmdBar == NULL && hWnd != NULL)
			{
				pCmdBar = (CCommandBarCtrlBase*)::SendMessage(hWnd, GetGetBarMessage(), (WPARAM)&dwPID, 0L);
				hWnd = ::GetParent(hWnd);
			}

			if(pCmdBar != NULL && dwPID == GetCurrentProcessId())
			{
				pCmdBar->m_hWndHook = pMsg->hwnd;
				ATLASSERT(pCmdBar->IsCommandBarBase());

				if(::IsWindow(pCmdBar->m_hWnd))
					pCmdBar->SendMessage(WM_FORWARDMSG, 0, (LPARAM)pMsg);
				else
					ATLTRACE2(atlTraceUI, 0, _T("CmdBar - Hook skipping message, can't find command bar!\n"));
			}
		}

		LRESULT lRet = 0;
		ATLASSERT(s_pmapMsgHook != NULL);
		if(s_pmapMsgHook != NULL)
		{
			DWORD dwThreadID = ::GetCurrentThreadId();
			_MsgHookData* pData = s_pmapMsgHook->Lookup(dwThreadID);
			if(pData != NULL)
			{
				lRet = ::CallNextHookEx(pData->hMsgHook, nCode, wParam, lParam);
			}
		}
		return lRet;
	}

// Implementation
	void DoPopupMenu(int nIndex, bool bAnimate)
	{
#ifdef _CMDBAR_EXTRA_TRACE
		ATLTRACE2(atlTraceUI, 0, _T("CmdBar - DoPopupMenu, bAnimate = %s\n"), bAnimate ? "true" : "false");
#endif

		// Menu animation flags
#ifndef TPM_VERPOSANIMATION
		const UINT TPM_VERPOSANIMATION = 0x1000L;
#endif
#ifndef TPM_NOANIMATION
		const UINT TPM_NOANIMATION = 0x4000L;
#endif
		T* pT = static_cast<T*>(this);

		// get popup menu and it's position
		RECT rect = { 0 };
		GetItemRect(nIndex, &rect);
		POINT pt = { rect.left, rect.bottom };
		MapWindowPoints(NULL, &pt, 1);
		MapWindowPoints(NULL, &rect);
		TPMPARAMS TPMParams = { 0 };
		TPMParams.cbSize = sizeof(TPMPARAMS);
		TPMParams.rcExclude = rect;
		HMENU hMenuPopup = ::GetSubMenu(m_hMenu, nIndex);
		ATLASSERT(hMenuPopup != NULL);

		// get button ID
		TBBUTTON tbb = { 0 };
		GetButton(nIndex, &tbb);
		int nCmdID = tbb.idCommand;

		m_nPopBtn = nIndex;   // remember current button's index

		// press button and display popup menu
		PressButton(nCmdID, TRUE);
		SetHotItem(nCmdID);
		pT->DoTrackPopupMenu(hMenuPopup, TPM_LEFTBUTTON | TPM_VERTICAL | TPM_LEFTALIGN | TPM_TOPALIGN |
			(s_bW2K ? (bAnimate ? TPM_VERPOSANIMATION : TPM_NOANIMATION) : 0), pt.x, pt.y, &TPMParams);
		PressButton(nCmdID, FALSE);
		if(::GetFocus() != m_hWnd)
			SetHotItem(-1);

		m_nPopBtn = -1;   // restore

		// eat next message if click is on the same button
		MSG msg = { 0 };
		if(::PeekMessage(&msg, m_hWnd, WM_LBUTTONDOWN, WM_LBUTTONDOWN, PM_NOREMOVE) && ::PtInRect(&rect, msg.pt))
			::PeekMessage(&msg, m_hWnd, WM_LBUTTONDOWN, WM_LBUTTONDOWN, PM_REMOVE);

		// check if another popup menu should be displayed
		if(m_nNextPopBtn != -1)
		{
			PostMessage(GetAutoPopupMessage(), m_nNextPopBtn & 0xFFFF);
			if(!(m_nNextPopBtn & 0xFFFF0000) && !m_bPopupItem)
				PostMessage(WM_KEYDOWN, VK_DOWN, 0);
			m_nNextPopBtn = -1;
		}
		else
		{
			m_bContextMenu = false;
			// If user didn't hit escape, give focus back
			if(!m_bEscapePressed)
			{
				if(m_bUseKeyboardCues && m_bShowKeyboardCues)
					m_bAllowKeyboardCues = false;
				pT->GiveFocusBack();
			}
			else
			{
				SetHotItem(nCmdID);
				SetAnchorHighlight(TRUE);
			}
		}
	}

	BOOL DoTrackPopupMenu(HMENU hMenu, UINT uFlags, int x, int y, LPTPMPARAMS lpParams = NULL)
	{
		CMenuHandle menuPopup = hMenu;

		CWindowCreateCriticalSectionLock lock;
		if(FAILED(lock.Lock()))
		{
			ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to lock critical section in CCommandBarCtrlImpl::DoTrackPopupMenu.\n"));
			ATLASSERT(FALSE);
			return FALSE;
		}

		ATLASSERT(s_hCreateHook == NULL);

		s_pCurrentBar = static_cast<CCommandBarCtrlBase*>(this);

		s_hCreateHook = ::SetWindowsHookEx(WH_CBT, CreateHookProc, ModuleHelper::GetModuleInstance(), GetCurrentThreadId());
		ATLASSERT(s_hCreateHook != NULL);

		m_bPopupItem = false;
		m_bMenuActive = true;

		BOOL bTrackRet = menuPopup.TrackPopupMenuEx(uFlags, x, y, m_hWnd, lpParams);
		m_bMenuActive = false;

		::UnhookWindowsHookEx(s_hCreateHook);

		s_hCreateHook = NULL;
		s_pCurrentBar = NULL;

		lock.Unlock();

		// cleanup - convert menus back to original state
#ifdef _CMDBAR_EXTRA_TRACE
		ATLTRACE2(atlTraceUI, 0, _T("CmdBar - TrackPopupMenu - cleanup\n"));
#endif

		ATLASSERT(m_stackMenuWnd.GetSize() == 0);

		UpdateWindow();
		ATL::CWindow wndTL = GetTopLevelParent();
		wndTL.UpdateWindow();

		// restore the menu items to the previous state for all menus that were converted
		if(m_bImagesVisible)
		{
			HMENU hMenuSav = NULL;
			while((hMenuSav = m_stackMenuHandle.Pop()) != NULL)
			{
				menuPopup = hMenuSav;
				BOOL bRet = FALSE;
				// restore state and delete menu item data
				for(int i = 0; i < menuPopup.GetMenuItemCount(); i++)
				{
					CMenuItemInfo mii;
					mii.fMask = MIIM_DATA | MIIM_TYPE | MIIM_ID;
					bRet = menuPopup.GetMenuItemInfo(i, TRUE, &mii);
					ATLASSERT(bRet);

					_MenuItemData* pMI = (_MenuItemData*)mii.dwItemData;
					if(pMI != NULL && pMI->IsCmdBarMenuItem())
					{
						mii.fMask = MIIM_DATA | MIIM_TYPE | MIIM_STATE;
						mii.fType = pMI->fType;
						mii.fState = pMI->fState;
						mii.dwTypeData = pMI->lpstrText;
						mii.cch = lstrlen(pMI->lpstrText);
						mii.dwItemData = NULL;

						bRet = menuPopup.SetMenuItemInfo(i, TRUE, &mii);
						// this one triggers WM_MEASUREITEM
						menuPopup.ModifyMenu(i, MF_BYPOSITION | mii.fType | mii.fState, mii.wID, pMI->lpstrText);
						ATLASSERT(bRet);

						delete [] pMI->lpstrText;
						delete pMI;
					}
				}
			}
		}
		return bTrackRet;
	}

	int GetPreviousMenuItem(int nBtn) const
	{
		if(nBtn == -1)
			return -1;
#if (_WIN32_IE >= 0x0500)
		RECT rcClient;
		GetClientRect(&rcClient);
#endif // (_WIN32_IE >= 0x0500)
		int nNextBtn;
		for(nNextBtn = nBtn - 1; nNextBtn != nBtn; nNextBtn--)
		{
			if(nNextBtn < 0)
				nNextBtn = ::GetMenuItemCount(m_hMenu) - 1;
			TBBUTTON tbb = { 0 };
			GetButton(nNextBtn, &tbb);
#if (_WIN32_IE >= 0x0500)
			RECT rcBtn;
			GetItemRect(nNextBtn, &rcBtn);
			if(rcBtn.right > rcClient.right)
			{
				nNextBtn = -2;   // chevron
				break;
			}
#endif // (_WIN32_IE >= 0x0500)
			if((tbb.fsState & TBSTATE_ENABLED) != 0 && (tbb.fsState & TBSTATE_HIDDEN) == 0)
				break;
		}
		return (nNextBtn != nBtn) ? nNextBtn : -1;
	}

	int GetNextMenuItem(int nBtn) const
	{
		if(nBtn == -1)
			return -1;
#if (_WIN32_IE >= 0x0500)
		RECT rcClient = { 0 };
		GetClientRect(&rcClient);
#endif // (_WIN32_IE >= 0x0500)
		int nNextBtn = 0;
		int nCount = ::GetMenuItemCount(m_hMenu);
		for(nNextBtn = nBtn + 1; nNextBtn != nBtn; nNextBtn++)
		{
			if(nNextBtn >= nCount)
				nNextBtn = 0;
			TBBUTTON tbb = { 0 };
			GetButton(nNextBtn, &tbb);
#if (_WIN32_IE >= 0x0500)
			RECT rcBtn = { 0 };
			GetItemRect(nNextBtn, &rcBtn);
			if(rcBtn.right > rcClient.right)
			{
				nNextBtn = -2;   // chevron
				break;
			}
#endif // (_WIN32_IE >= 0x0500)
			if((tbb.fsState & TBSTATE_ENABLED) != 0 && (tbb.fsState & TBSTATE_HIDDEN) == 0)
				break;
		}
		return (nNextBtn != nBtn) ? nNextBtn : -1;
	}

#if (_WIN32_IE >= 0x0500)
	bool DisplayChevronMenu()
	{
		// assume we are in a rebar
		HWND hWndReBar = GetParent();
		int nCount = (int)::SendMessage(hWndReBar, RB_GETBANDCOUNT, 0, 0L);
		bool bRet = false;
		for(int i = 0; i < nCount; i++)
		{
			REBARBANDINFO rbbi = { RunTimeHelper::SizeOf_REBARBANDINFO(), RBBIM_CHILD | RBBIM_STYLE };
			BOOL bRetBandInfo = (BOOL)::SendMessage(hWndReBar, RB_GETBANDINFO, i, (LPARAM)&rbbi);
			if(bRetBandInfo && rbbi.hwndChild == m_hWnd)
			{
				if((rbbi.fStyle & RBBS_USECHEVRON) != 0)
				{
					::PostMessage(hWndReBar, RB_PUSHCHEVRON, i, 0L);
					PostMessage(WM_KEYDOWN, VK_DOWN, 0L);
					bRet = true;
				}
				break;
			}
		}
		return bRet;
	}
#endif // (_WIN32_IE >= 0x0500)

	void GetSystemSettings()
	{
		// refresh our font
		NONCLIENTMETRICS info = { RunTimeHelper::SizeOf_NONCLIENTMETRICS() };
		BOOL bRet = ::SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(info), &info, 0);
		ATLASSERT(bRet);
		if(bRet)
		{
			LOGFONT logfont = { 0 };
			if(m_fontMenu.m_hFont != NULL)
				m_fontMenu.GetLogFont(logfont);
			if(logfont.lfHeight != info.lfMenuFont.lfHeight ||
			   logfont.lfWidth != info.lfMenuFont.lfWidth ||
			   logfont.lfEscapement != info.lfMenuFont.lfEscapement ||
			   logfont.lfOrientation != info.lfMenuFont.lfOrientation ||
			   logfont.lfWeight != info.lfMenuFont.lfWeight ||
			   logfont.lfItalic != info.lfMenuFont.lfItalic ||
			   logfont.lfUnderline != info.lfMenuFont.lfUnderline ||
			   logfont.lfStrikeOut != info.lfMenuFont.lfStrikeOut ||
			   logfont.lfCharSet != info.lfMenuFont.lfCharSet ||
			   logfont.lfOutPrecision != info.lfMenuFont.lfOutPrecision ||
			   logfont.lfClipPrecision != info.lfMenuFont.lfClipPrecision ||
			   logfont.lfQuality != info.lfMenuFont.lfQuality ||
			   logfont.lfPitchAndFamily != info.lfMenuFont.lfPitchAndFamily ||
			   lstrcmp(logfont.lfFaceName, info.lfMenuFont.lfFaceName) != 0)
			{
				HFONT hFontMenu = ::CreateFontIndirect(&info.lfMenuFont);
				ATLASSERT(hFontMenu != NULL);
				if(hFontMenu != NULL)
				{
					if(m_fontMenu.m_hFont != NULL)
						m_fontMenu.DeleteObject();
					m_fontMenu.Attach(hFontMenu);
					SetFont(m_fontMenu);
					AddStrings(_T("NS\0"));   // for proper item height
					AutoSize();
				}
			}
		}

		// check if we need extra spacing for menu item text
		CWindowDC dc(m_hWnd);
		HFONT hFontOld = dc.SelectFont(m_fontMenu);
		RECT rcText = { 0, 0, 0, 0 };
		dc.DrawText(_T("\t"), -1, &rcText, DT_SINGLELINE | DT_LEFT | DT_VCENTER | DT_CALCRECT);
		if((rcText.right - rcText.left) < 4)
		{
			::SetRectEmpty(&rcText);
			dc.DrawText(_T("x"), -1, &rcText, DT_SINGLELINE | DT_LEFT | DT_VCENTER | DT_CALCRECT);
			m_cxExtraSpacing = rcText.right - rcText.left;
		}
		else
		{
			m_cxExtraSpacing = 0;
		}
		dc.SelectFont(hFontOld);

		// get Windows version
		OSVERSIONINFO ovi = { sizeof(OSVERSIONINFO) };
		::GetVersionEx(&ovi);

		// query keyboard cues mode (Windows 2000 or later)
		if(ovi.dwMajorVersion >= 5)
		{
#ifndef SPI_GETKEYBOARDCUES
			const UINT SPI_GETKEYBOARDCUES = 0x100A;
#endif // !SPI_GETKEYBOARDCUES
			BOOL bRetVal = TRUE;
			bRet = ::SystemParametersInfo(SPI_GETKEYBOARDCUES, 0, &bRetVal, 0);
			m_bUseKeyboardCues = (bRet && !bRetVal);
			m_bAllowKeyboardCues = true;
			ShowKeyboardCues(!m_bUseKeyboardCues);
		}

		// query flat menu mode (Windows XP or later)
		if((ovi.dwMajorVersion == 5 && ovi.dwMinorVersion >= 1) || (ovi.dwMajorVersion > 5))
		{
#ifndef SPI_GETFLATMENU
			const UINT SPI_GETFLATMENU = 0x1022;
#endif // !SPI_GETFLATMENU
			BOOL bRetVal = FALSE;
			bRet = ::SystemParametersInfo(SPI_GETFLATMENU, 0, &bRetVal, 0);
			m_bFlatMenus = (bRet && bRetVal);
		}

#if _WTL_CMDBAR_VISTA_MENUS
		// check if we should use Vista menus
		bool bVistaMenus = (RunTimeHelper::IsVista() && RunTimeHelper::IsCommCtrl6() && ((m_dwExtendedStyle & CBR_EX_NOVISTAMENUS) == 0));

		if(bVistaMenus)
		{
			HMODULE hThemeDLL = ::LoadLibrary(_T("uxtheme.dll"));
			if(hThemeDLL != NULL)
			{
				typedef BOOL (STDAPICALLTYPE *PFN_IsThemeActive)();
				PFN_IsThemeActive pfnIsThemeActive = (PFN_IsThemeActive)::GetProcAddress(hThemeDLL, "IsThemeActive");
				ATLASSERT(pfnIsThemeActive != NULL);
				bVistaMenus = bVistaMenus && (pfnIsThemeActive != NULL) && (pfnIsThemeActive() != FALSE);

				typedef BOOL (STDAPICALLTYPE *PFN_IsAppThemed)();
				PFN_IsAppThemed pfnIsAppThemed = (PFN_IsAppThemed)::GetProcAddress(hThemeDLL, "IsAppThemed");
				ATLASSERT(pfnIsAppThemed != NULL);
				bVistaMenus = bVistaMenus && (pfnIsAppThemed != NULL) && (pfnIsAppThemed() != FALSE);

				::FreeLibrary(hThemeDLL);
			}
		}

		if(!bVistaMenus && m_bVistaMenus && (m_hMenu != NULL) && (m_arrCommand.GetSize() > 0))
		{
			T* pT = static_cast<T*>(this);
			pT->_RemoveVistaBitmapsFromMenu();
		}

		m_bVistaMenus = bVistaMenus;
#endif // _WTL_CMDBAR_VISTA_MENUS

#ifdef _CMDBAR_EXTRA_TRACE
		ATLTRACE2(atlTraceUI, 0, _T("CmdBar - GetSystemSettings:\n     m_bFlatMenus = %s\n     m_bUseKeyboardCues = %s     m_bVistaMenus = %s\n"),
			m_bFlatMenus ? "true" : "false", m_bUseKeyboardCues ? "true" : "false", m_bVistaMenus ? "true" : "false");
#endif
	}

// Implementation - alternate focus mode support
	void TakeFocus()
	{
		if((m_dwExtendedStyle & CBR_EX_ALTFOCUSMODE) && m_hWndFocus == NULL)
			m_hWndFocus = ::GetFocus();
		SetFocus();
	}

	void GiveFocusBack()
	{
		if(m_bParentActive)
		{
			if((m_dwExtendedStyle & CBR_EX_ALTFOCUSMODE) && ::IsWindow(m_hWndFocus))
				::SetFocus(m_hWndFocus);
			else if(!(m_dwExtendedStyle & CBR_EX_ALTFOCUSMODE) && m_wndParent.IsWindow())
				m_wndParent.SetFocus();
		}
		m_hWndFocus = NULL;
		SetAnchorHighlight(FALSE);
		if(m_bUseKeyboardCues && m_bShowKeyboardCues)
			ShowKeyboardCues(false);
		m_bSkipPostDown = false;
	}

	void ShowKeyboardCues(bool bShow)
	{
		m_bShowKeyboardCues = bShow;
		SetDrawTextFlags(DT_HIDEPREFIX, m_bShowKeyboardCues ? 0 : DT_HIDEPREFIX);
		Invalidate();
		UpdateWindow();
	}

// Implementation - internal message helpers
	static UINT GetAutoPopupMessage()
	{
		static UINT uAutoPopupMessage = 0;
		if(uAutoPopupMessage == 0)
		{
			CStaticDataInitCriticalSectionLock lock;
			if(FAILED(lock.Lock()))
			{
				ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to lock critical section in CCommandBarCtrlImpl::GetAutoPopupMessage.\n"));
				ATLASSERT(FALSE);
				return 0;
			}

			if(uAutoPopupMessage == 0)
				uAutoPopupMessage = ::RegisterWindowMessage(_T("WTL_CmdBar_InternalAutoPopupMsg"));

			lock.Unlock();
		}
		ATLASSERT(uAutoPopupMessage != 0);
		return uAutoPopupMessage;
	}

	static UINT GetGetBarMessage()
	{
		static UINT uGetBarMessage = 0;
		if(uGetBarMessage == 0)
		{
			CStaticDataInitCriticalSectionLock lock;
			if(FAILED(lock.Lock()))
			{
				ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to lock critical section in CCommandBarCtrlImpl::GetGetBarMessage.\n"));
				ATLASSERT(FALSE);
				return 0;
			}

			if(uGetBarMessage == 0)
				uGetBarMessage = ::RegisterWindowMessage(_T("WTL_CmdBar_InternalGetBarMsg"));

			lock.Unlock();
		}
		ATLASSERT(uGetBarMessage != 0);
		return uGetBarMessage;
	}

// Implementation
	bool CreateInternalImageList(int cImages)
	{
		UINT uFlags = (m_bAlphaImages ? ILC_COLOR32 : ILC_COLOR24) | ILC_MASK;
		m_hImageList = ::ImageList_Create(m_szBitmap.cx, m_szBitmap.cy, uFlags, cImages, 1);
		ATLASSERT(m_hImageList != NULL);
		return (m_hImageList != NULL);
	}

// Implementation - support for Vista menus
#if _WTL_CMDBAR_VISTA_MENUS
	void _AddVistaBitmapsFromImageList(int nStartIndex, int nCount)
	{
		// Create display compatible memory DC
		HDC hDC = ::GetDC(NULL);
		CDC dcMem;
		dcMem.CreateCompatibleDC(hDC);
		HBITMAP hBitmapSave = dcMem.GetCurrentBitmap();

		T* pT = static_cast<T*>(this);
		// Create bitmaps for all menu items
		for(int i = 0; i < nCount; i++)
		{
			HBITMAP hBitmap = pT->_CreateVistaBitmapHelper(nStartIndex + i, hDC, dcMem);
			dcMem.SelectBitmap(hBitmapSave);
			m_arrVistaBitmap.Add(hBitmap);
		}
	}

	void _AddVistaBitmapFromImageList(int nIndex)
	{
		// Create display compatible memory DC
		HDC hDC = ::GetDC(NULL);
		CDC dcMem;
		dcMem.CreateCompatibleDC(hDC);
		HBITMAP hBitmapSave = dcMem.GetCurrentBitmap();

		// Create bitmap for menu item
		T* pT = static_cast<T*>(this);
		HBITMAP hBitmap = pT->_CreateVistaBitmapHelper(nIndex, hDC, dcMem);

		// Select saved bitmap back and add bitmap to the array
		dcMem.SelectBitmap(hBitmapSave);
		m_arrVistaBitmap.Add(hBitmap);
	}

	void _ReplaceVistaBitmapFromImageList(int nIndex)
	{
		// Delete existing bitmap
		if(m_arrVistaBitmap[nIndex] != NULL)
			::DeleteObject(m_arrVistaBitmap[nIndex]);

		// Create display compatible memory DC
		HDC hDC = ::GetDC(NULL);
		CDC dcMem;
		dcMem.CreateCompatibleDC(hDC);
		HBITMAP hBitmapSave = dcMem.GetCurrentBitmap();

		// Create bitmap for menu item
		T* pT = static_cast<T*>(this);
		HBITMAP hBitmap = pT->_CreateVistaBitmapHelper(nIndex, hDC, dcMem);

		// Select saved bitmap back and replace bitmap in the array
		dcMem.SelectBitmap(hBitmapSave);
		m_arrVistaBitmap.SetAtIndex(nIndex, hBitmap);
	}

	HBITMAP _CreateVistaBitmapHelper(int nIndex, HDC hDCSource, HDC hDCTarget)
	{
		// Create 32-bit bitmap
		BITMAPINFO bi = { 0 };
		bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
		bi.bmiHeader.biWidth = m_szBitmap.cx;
		bi.bmiHeader.biHeight = m_szBitmap.cy;
		bi.bmiHeader.biPlanes = 1;
		bi.bmiHeader.biBitCount = 32;
		bi.bmiHeader.biCompression = BI_RGB;
		bi.bmiHeader.biSizeImage = 0;
		bi.bmiHeader.biXPelsPerMeter = 0;
		bi.bmiHeader.biYPelsPerMeter = 0;
		bi.bmiHeader.biClrUsed = 0;
		bi.bmiHeader.biClrImportant = 0;
		HBITMAP hBitmap = ::CreateDIBSection(hDCSource, &bi, DIB_RGB_COLORS, NULL, NULL, 0);
		ATLASSERT(hBitmap != NULL);

		// Select bitmap into target DC and draw from image list to it
		if(hBitmap != NULL)
		{
			::SelectObject(hDCTarget, hBitmap);

			IMAGELISTDRAWPARAMS ildp = { 0 };
			ildp.cbSize = sizeof(IMAGELISTDRAWPARAMS);
			ildp.himl = m_hImageList;
			ildp.i = nIndex;
			ildp.hdcDst = hDCTarget;
			ildp.x = 0;
			ildp.y = 0;
			ildp.cx = 0;
			ildp.cy = 0;
			ildp.xBitmap = 0;
			ildp.yBitmap = 0;
			ildp.fStyle = ILD_TRANSPARENT;
			ildp.fState = ILS_ALPHA;
			ildp.Frame = 255;
			::ImageList_DrawIndirect(&ildp);
		}

		return hBitmap;
	}

	void _RemoveVistaBitmapsFromMenu()
	{
		CMenuHandle menu = m_hMenu;
		for(int i = 0; i < m_arrCommand.GetSize(); i++)
		{
			CMenuItemInfo mii;
			mii.fMask = MIIM_BITMAP;
			mii.hbmpItem = NULL;
			menu.SetMenuItemInfo(m_arrCommand[i], FALSE, &mii);
		}
	}
#endif // _WTL_CMDBAR_VISTA_MENUS
};


class CCommandBarCtrl : public CCommandBarCtrlImpl<CCommandBarCtrl>
{
public:
	DECLARE_WND_SUPERCLASS(_T("WTL_CommandBar"), GetWndClassName())
};


///////////////////////////////////////////////////////////////////////////////
// CMDICommandBarCtrl - ATL implementation of Command Bars for MDI apps

template <class T, class TBase = CCommandBarCtrlBase, class TWinTraits = ATL::CControlWinTraits>
class ATL_NO_VTABLE CMDICommandBarCtrlImpl : public CCommandBarCtrlImpl< T, TBase, TWinTraits>
{
public:
// Data members
	ATL::CContainedWindow m_wndMDIClient;
	bool m_bChildMaximized;
	HWND m_hWndChildMaximized;
	HICON m_hIconChildMaximized;
	int m_nBtnPressed;
	int m_nBtnWasPressed;

	int m_cxyOffset;      // offset between nonclient elements
	int m_cxIconWidth;    // small icon width
	int m_cyIconHeight;   // small icon height
	int m_cxBtnWidth;     // nonclient button width
	int m_cyBtnHeight;    // nonclient button height
	int m_cxLeft;         // left nonclient area width
	int m_cxRight;        // right nonclient area width

// Theme declarations and data members
#ifndef _WTL_NO_AUTO_THEME
#ifndef _UXTHEME_H_
	typedef HANDLE HTHEME;
#endif // !_UXTHEME_H_
	typedef HTHEME (STDAPICALLTYPE *PFN_OpenThemeData)(HWND hwnd, LPCWSTR pszClassList);
	typedef HRESULT (STDAPICALLTYPE *PFN_CloseThemeData)(HTHEME hTheme);
	typedef HRESULT (STDAPICALLTYPE *PFN_DrawThemeBackground)(HTHEME hTheme, HDC hdc, int iPartId, int iStateId, const RECT *pRect, OPTIONAL const RECT *pClipRect);
	typedef HRESULT (STDAPICALLTYPE *PFN_DrawThemeParentBackground)(HWND hwnd, HDC hdc, OPTIONAL RECT* prc);

	HMODULE m_hThemeDLL;
	HTHEME m_hTheme;
	PFN_DrawThemeBackground m_pfnDrawThemeBackground;
	PFN_DrawThemeParentBackground m_pfnDrawThemeParentBackground;
#endif // !_WTL_NO_AUTO_THEME

// Constructor/destructor
	CMDICommandBarCtrlImpl() : 
			m_wndMDIClient(this, 2), m_bChildMaximized(false), 
			m_hWndChildMaximized(NULL), m_hIconChildMaximized(NULL), 
			m_nBtnPressed(-1), m_nBtnWasPressed(-1),
#ifndef _WTL_NO_AUTO_THEME
			m_hThemeDLL(NULL), m_hTheme(NULL), m_pfnDrawThemeBackground(NULL), m_pfnDrawThemeParentBackground(NULL), 
#endif // !_WTL_NO_AUTO_THEME
			m_cxyOffset(2),
			m_cxIconWidth(16), m_cyIconHeight(16),
			m_cxBtnWidth(16), m_cyBtnHeight(14),
			m_cxLeft(20), m_cxRight(55)
	{ }

	~CMDICommandBarCtrlImpl()
	{
		if(m_wndMDIClient.IsWindow())
/*scary!*/			m_wndMDIClient.UnsubclassWindow();
	}

// Operations
	BOOL SetMDIClient(HWND hWndMDIClient)
	{
		ATLASSERT(::IsWindow(m_hWnd));
		ATLASSERT(::IsWindow(hWndMDIClient));
		if(!::IsWindow(hWndMDIClient))
			return FALSE;

#ifdef _DEBUG
		// BLOCK: Test if the passed window is MDICLIENT
		{
			LPCTSTR lpszMDIClientClass = _T("MDICLIENT");
			const int nNameLen = 9 + 1;   // "MDICLIENT" + NULL
			TCHAR szClassName[nNameLen] = { 0 };
			::GetClassName(hWndMDIClient, szClassName, nNameLen);
			ATLASSERT(lstrcmpi(szClassName, lpszMDIClientClass) == 0);
		}
#endif // _DEBUG

		if(m_wndMDIClient.IsWindow())
/*scary!*/		m_wndMDIClient.UnsubclassWindow();

		return m_wndMDIClient.SubclassWindow(hWndMDIClient);
	}

// Message maps
	typedef CCommandBarCtrlImpl< T, TBase, TWinTraits >   _baseClass;
	BEGIN_MSG_MAP(CMDICommandBarCtrlImpl)
		MESSAGE_HANDLER(WM_CREATE, OnCreate)
		MESSAGE_HANDLER(WM_DESTROY, OnDestroy)
#ifndef _WTL_NO_AUTO_THEME
		MESSAGE_HANDLER(_GetThemeChangedMsg(), OnThemeChanged)
#endif // !_WTL_NO_AUTO_THEME
		MESSAGE_HANDLER(WM_SIZE, OnSize)
		MESSAGE_HANDLER(WM_NCCALCSIZE, OnNcCalcSize)
		MESSAGE_HANDLER(WM_NCPAINT, OnNcPaint)
		MESSAGE_HANDLER(WM_NCHITTEST, OnNcHitTest)
		MESSAGE_HANDLER(WM_NCLBUTTONDOWN, OnNcLButtonDown)
		MESSAGE_HANDLER(WM_MOUSEMOVE, OnMouseMove)
		MESSAGE_HANDLER(WM_LBUTTONUP, OnLButtonUp)
		MESSAGE_HANDLER(WM_NCLBUTTONDBLCLK, OnNcLButtonDblClk)
		MESSAGE_HANDLER(WM_CAPTURECHANGED, OnCaptureChanged)
		CHAIN_MSG_MAP(_baseClass)
	ALT_MSG_MAP(1)   // Parent window messages
		MESSAGE_HANDLER(WM_ACTIVATE, OnParentActivate)
		CHAIN_MSG_MAP_ALT(_baseClass, 1)
	ALT_MSG_MAP(2)   // MDI client window messages
		MESSAGE_HANDLER(WM_MDISETMENU, OnMDISetMenu)
		// no chaining needed since this was moved from the base class here
	ALT_MSG_MAP(3)   // Message hook messages
		MESSAGE_RANGE_HANDLER(0, 0xFFFF, OnAllHookMessages)
		CHAIN_MSG_MAP_ALT(_baseClass, 3)
	END_MSG_MAP()

// Additional MDI message handlers
	LRESULT OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
	{
		LRESULT lRet = _baseClass::OnCreate(uMsg, wParam, lParam, bHandled);
		if(lRet == (LRESULT)-1)
			return lRet;

#ifndef _WTL_NO_AUTO_THEME
		// this will fail if theming is not supported
		m_hThemeDLL = ::LoadLibrary(_T("uxtheme.dll"));
		if(m_hThemeDLL != NULL)
		{
			m_pfnDrawThemeBackground = (PFN_DrawThemeBackground)::GetProcAddress(m_hThemeDLL, "DrawThemeBackground");
			ATLASSERT(m_pfnDrawThemeBackground != NULL);
			if(m_pfnDrawThemeBackground != NULL)
			{
				T* pT = static_cast<T*>(this);
				pT->_OpenThemeData();
			}
			else
			{
				::FreeLibrary(m_hThemeDLL);
				m_hThemeDLL = NULL;
			}
			m_pfnDrawThemeParentBackground = (PFN_DrawThemeParentBackground)::GetProcAddress(m_hThemeDLL, "DrawThemeParentBackground");
			ATLASSERT(m_pfnDrawThemeParentBackground != NULL);
		}
#endif // !_WTL_NO_AUTO_THEME

		return lRet;
	}

	LRESULT OnDestroy(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
	{
		LRESULT lRet = _baseClass::OnDestroy(uMsg, wParam, lParam, bHandled);

#ifndef _WTL_NO_AUTO_THEME
		if(m_hThemeDLL != NULL)
		{
			T* pT = static_cast<T*>(this);
			pT->_CloseThemeData();
			::FreeLibrary(m_hThemeDLL);
			m_hThemeDLL = NULL;
		}
#endif // !_WTL_NO_AUTO_THEME

		return lRet;
	}

#ifndef _WTL_NO_AUTO_THEME
	LRESULT OnThemeChanged(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
	{
		if(m_hThemeDLL != NULL)
		{
			T* pT = static_cast<T*>(this);
			pT->_CloseThemeData();
			pT->_OpenThemeData();
		}
		return 0;
	}
#endif // !_WTL_NO_AUTO_THEME

	LRESULT OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/)
	{
		LRESULT lRet = DefWindowProc(uMsg, wParam, lParam);
		T* pT = static_cast<T*>(this);
		pT->_AdjustBtnSize(GET_Y_LPARAM(lParam));
		return lRet;
	}

	LRESULT OnNcCalcSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/)
	{
		LRESULT lRet = DefWindowProc(uMsg, wParam, lParam);

		if(m_bChildMaximized && (BOOL)wParam)
		{
			LPNCCALCSIZE_PARAMS lpParams = (LPNCCALCSIZE_PARAMS)lParam;
			if(m_bLayoutRTL)
			{
				lpParams->rgrc[0].left += m_cxRight;
				lpParams->rgrc[0].right -= m_cxLeft;
			}
			else
			{
				lpParams->rgrc[0].left += m_cxLeft;
				lpParams->rgrc[0].right -= m_cxRight;
			}
		}

		return lRet;
	}

	LRESULT OnNcPaint(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/)
	{
		LRESULT lRet = DefWindowProc(uMsg, wParam, lParam);

		if(!m_bChildMaximized)
			return lRet;

		ATLASSERT(m_hWndChildMaximized != NULL && m_hIconChildMaximized != NULL);

		// get DC and window rectangle
		CWindowDC dc(m_hWnd);
		RECT rect;
		GetWindowRect(&rect);
		int cxWidth = rect.right - rect.left;
		int cyHeight = rect.bottom - rect.top;

		// paint left side nonclient background and draw icon
		::SetRect(&rect, 0, 0, m_cxLeft, cyHeight);
#ifndef _WTL_NO_AUTO_THEME
		if(m_hTheme != NULL)
		{
			if(m_pfnDrawThemeParentBackground != NULL)
				m_pfnDrawThemeParentBackground(m_hWnd, dc, &rect);
			else
				dc.FillRect(&rect, COLOR_WINDOW);
		}
		else
#endif // !_WTL_NO_AUTO_THEME
		{
			if((m_dwExtendedStyle & CBR_EX_TRANSPARENT) != 0)
				dc.FillRect(&rect, COLOR_3DFACE);
			else
				dc.FillRect(&rect, COLOR_MENU);
		}

		RECT rcIcon = { 0 };
		T* pT = static_cast<T*>(this);
		pT->_CalcIconRect(cxWidth, cyHeight, rcIcon);
		dc.DrawIconEx(rcIcon.left, rcIcon.top, m_hIconChildMaximized, m_cxIconWidth, m_cyIconHeight);

		// paint right side nonclient background
		::SetRect(&rect, cxWidth - m_cxRight, 0, cxWidth, cyHeight);
#ifndef _WTL_NO_AUTO_THEME
		if(m_hTheme != NULL)
		{
			if(m_pfnDrawThemeParentBackground != NULL)
			{
				// this is to account for the left non-client area
				POINT ptOrg = { 0, 0 };
				dc.GetViewportOrg(&ptOrg);
				dc.SetViewportOrg(ptOrg.x + m_cxLeft, ptOrg.y);
				::OffsetRect(&rect, -m_cxLeft, 0);

				m_pfnDrawThemeParentBackground(m_hWnd, dc, &rect);

				// restore
				dc.SetViewportOrg(ptOrg);
				::OffsetRect(&rect, m_cxLeft, 0);
			}
			else
			{
				dc.FillRect(&rect, COLOR_3DFACE);
			}
		}
		else
#endif // !_WTL_NO_AUTO_THEME
		{
			if((m_dwExtendedStyle & CBR_EX_TRANSPARENT) != 0)
				dc.FillRect(&rect, COLOR_3DFACE);
			else
				dc.FillRect(&rect, COLOR_MENU);
		}

		// draw buttons
		RECT arrRect[3] = { 0 };
		pT->_CalcBtnRects(cxWidth, cyHeight, arrRect);
		pT->_DrawMDIButton(dc, arrRect, -1);   // draw all buttons

		return lRet;
	}

	LRESULT OnNcHitTest(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/)
	{
		LRESULT lRet = DefWindowProc(uMsg, wParam, lParam);
		if(m_bChildMaximized)
		{
			RECT rect = { 0 };
			GetWindowRect(&rect);
			POINT pt = { GET_X_LPARAM(lParam) - rect.left, GET_Y_LPARAM(lParam) - rect.top };
			if(m_bLayoutRTL)
			{
				if((pt.x < m_cxRight) || (pt.x > ((rect.right - rect.left) - m_cxLeft)))
					lRet = HTBORDER;
			}
			else
			{
				if((pt.x < m_cxLeft) || (pt.x > ((rect.right - rect.left) - m_cxRight)))
					lRet = HTBORDER;
			}
		}
		return lRet;
	}

	LRESULT OnNcLButtonDown(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& bHandled)
	{
		if(!m_bChildMaximized)
		{
			bHandled = FALSE;
			return 1;
		}

		ATLASSERT(_DebugCheckChild());

		POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) };
		RECT rect = { 0 };
		GetWindowRect(&rect);
		pt.x -= rect.left;
		pt.y -= rect.top;

		RECT rcIcon = { 0 };
		T* pT = static_cast<T*>(this);
		pT->_CalcIconRect(rect.right - rect.left, rect.bottom - rect.top, rcIcon, m_bLayoutRTL);
		RECT arrRect[3] = { 0 };
		pT->_CalcBtnRects(rect.right - rect.left, rect.bottom - rect.top, arrRect, m_bLayoutRTL);

		if(::PtInRect(&rcIcon, pt))
		{
#ifdef _CMDBAR_EXTRA_TRACE
			ATLTRACE2(atlTraceUI, 0, _T("MDI CmdBar - LButtonDown: icon\n"));
#endif
#ifndef TPM_VERPOSANIMATION
			const UINT TPM_VERPOSANIMATION = 0x1000L;   // Menu animation flag
#endif
			CMenuHandle menu = ::GetSystemMenu(m_hWndChildMaximized, FALSE);
			UINT uRet = (UINT)menu.TrackPopupMenu(TPM_LEFTBUTTON | TPM_VERTICAL | TPM_LEFTALIGN | TPM_TOPALIGN | TPM_RETURNCMD |  
				(s_bW2K ? TPM_VERPOSANIMATION : 0), m_bLayoutRTL ? rect.right : rect.left, rect.bottom, m_hWndChildMaximized);

			// eat next message if click is on the same button
			::OffsetRect(&rcIcon, rect.left, rect.top);
			MSG msg = { 0 };
			if(::PeekMessage(&msg, m_hWnd, WM_NCLBUTTONDOWN, WM_NCLBUTTONDOWN, PM_NOREMOVE) && ::PtInRect(&rcIcon, msg.pt))
				::PeekMessage(&msg, m_hWnd, WM_NCLBUTTONDOWN, WM_NCLBUTTONDOWN, PM_REMOVE);

			if(uRet != 0)
				::SendMessage(m_hWndChildMaximized, WM_SYSCOMMAND, uRet, 0L);
		}
		else if(::PtInRect(&arrRect[0], pt))
		{
#ifdef _CMDBAR_EXTRA_TRACE
			ATLTRACE2(atlTraceUI, 0, _T("MDI CmdBar - LButtonDown: close button\n"));
#endif
			m_nBtnWasPressed = m_nBtnPressed = 0;
		}
		else if(::PtInRect(&arrRect[1], pt))
		{
#ifdef _CMDBAR_EXTRA_TRACE
			ATLTRACE2(atlTraceUI, 0, _T("MDI CmdBar - LButtonDown: restore button\n"));
#endif
			m_nBtnWasPressed = m_nBtnPressed = 1;
		}
		else if(::PtInRect(&arrRect[2], pt))
		{
#ifdef _CMDBAR_EXTRA_TRACE
			ATLTRACE2(atlTraceUI, 0, _T("MDI CmdBar - LButtonDown: minimize button\n"));
#endif
			m_nBtnWasPressed = m_nBtnPressed = 2;
		}
		else
		{
			bHandled = FALSE;
		}

		// draw the button state if it was pressed
		if(m_nBtnPressed != -1)
		{
			SetCapture();
			CWindowDC dc(m_hWnd);
			pT->_CalcBtnRects(rect.right - rect.left, rect.bottom - rect.top, arrRect);
			pT->_DrawMDIButton(dc, arrRect, m_nBtnPressed);
		}

		return 0;
	}

	LRESULT OnMouseMove(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& bHandled)
	{
		if(!m_bChildMaximized || ::GetCapture() != m_hWnd || m_nBtnWasPressed == -1)
		{
			bHandled = FALSE;
			return 1;
		}

		POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) };
		ClientToScreen(&pt);
		RECT rect = { 0 };
		GetWindowRect(&rect);
		pt.x -= rect.left;
		pt.y -= rect.top;
		RECT arrRect[3] = { 0 };
		T* pT = static_cast<T*>(this);
		pT->_CalcBtnRects(rect.right - rect.left, rect.bottom - rect.top, arrRect, m_bLayoutRTL);
		int nOldBtnPressed = m_nBtnPressed;
		m_nBtnPressed = ::PtInRect(&arrRect[m_nBtnWasPressed], pt) ? m_nBtnWasPressed : -1;
		if(nOldBtnPressed != m_nBtnPressed)
		{
			CWindowDC dc(m_hWnd);
			pT->_CalcBtnRects(rect.right - rect.left, rect.bottom - rect.top, arrRect);
			pT->_DrawMDIButton(dc, arrRect, (m_nBtnPressed != -1) ? m_nBtnPressed : nOldBtnPressed);
		}

		return 0;
	}

	LRESULT OnLButtonUp(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& bHandled)
	{
		if(!m_bChildMaximized || ::GetCapture() != m_hWnd || m_nBtnWasPressed == -1)
		{
			bHandled = FALSE;
			return 1;
		}

		ATLASSERT(_DebugCheckChild());

		POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) };
		ClientToScreen(&pt);
		RECT rect = { 0 };
		GetWindowRect(&rect);
		pt.x -= rect.left;
		pt.y -= rect.top;

		int nBtn = m_nBtnWasPressed;
		ReleaseCapture();

		RECT arrRect[3] = { 0 };
		T* pT = static_cast<T*>(this);
		pT->_CalcBtnRects(rect.right - rect.left, rect.bottom - rect.top, arrRect, m_bLayoutRTL);
		if(::PtInRect(&arrRect[nBtn], pt))
		{
			switch(nBtn)
			{
			case 0:		// close
#ifdef _CMDBAR_EXTRA_TRACE
				ATLTRACE2(atlTraceUI, 0, _T("MDI CmdBar - LButtonUp: close button\n"));
#endif
				::SendMessage(m_hWndChildMaximized, WM_SYSCOMMAND, SC_CLOSE, 0L);
				break;
			case 1:		// restore
#ifdef _CMDBAR_EXTRA_TRACE
				ATLTRACE2(atlTraceUI, 0, _T("MDI CmdBar - LButtonUp: restore button\n"));
#endif
				::SendMessage(m_hWndChildMaximized, WM_SYSCOMMAND, SC_RESTORE, 0L);
				break;
			case 2:		// minimize
#ifdef _CMDBAR_EXTRA_TRACE
				ATLTRACE2(atlTraceUI, 0, _T("MDI CmdBar - LButtonUp: minimize button\n"));
#endif
				::SendMessage(m_hWndChildMaximized, WM_SYSCOMMAND, SC_MINIMIZE, 0L);
				break;
			default:
				break;
			}
		}

		return 0;
	}

	LRESULT OnNcLButtonDblClk(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& bHandled)
	{
		if(!m_bChildMaximized || m_nBtnWasPressed != -1)
		{
			bHandled = FALSE;
			return 1;
		}

		ATLASSERT(_DebugCheckChild());

		POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) };
		RECT rect = { 0 };
		GetWindowRect(&rect);
		pt.x -= rect.left;
		pt.y -= rect.top;

		RECT rcIcon = { 0 };
		T* pT = static_cast<T*>(this);
		pT->_CalcIconRect(rect.right - rect.left, rect.bottom - rect.top, rcIcon, m_bLayoutRTL);
		RECT arrRect[3] = { 0 };
		pT->_CalcBtnRects(rect.right - rect.left, rect.bottom - rect.top, arrRect, m_bLayoutRTL);

		if(::PtInRect(&rcIcon, pt))
		{
			CMenuHandle menu = ::GetSystemMenu(m_hWndChildMaximized, FALSE);
			UINT uDefID = menu.GetMenuDefaultItem();
			if(uDefID == (UINT)-1)
				uDefID = SC_CLOSE;
			::SendMessage(m_hWndChildMaximized, WM_SYSCOMMAND, uDefID, 0L);
		}

		return 0;
	}

	LRESULT OnCaptureChanged(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
	{
		if(m_bChildMaximized)
		{
			if(m_nBtnPressed != -1)
			{
				ATLASSERT(m_nBtnPressed == m_nBtnWasPressed);   // must be
				m_nBtnPressed = -1;
				RECT rect = { 0 };
				GetWindowRect(&rect);
				RECT arrRect[3] = { 0 };
				T* pT = static_cast<T*>(this);
				pT->_CalcBtnRects(rect.right - rect.left, rect.bottom - rect.top, arrRect);
				CWindowDC dc(m_hWnd);
				pT->_DrawMDIButton(dc, arrRect, m_nBtnWasPressed);
			}
			m_nBtnWasPressed = -1;
		}
		else
		{
			bHandled = FALSE;
		}
		return 0;
	}

// Parent window message handlers
	LRESULT OnParentActivate(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled)
	{
		m_bParentActive = (LOWORD(wParam) != WA_INACTIVE);
		RedrawWindow(NULL, NULL, RDW_INVALIDATE | RDW_FRAME | RDW_UPDATENOW);
		bHandled = FALSE;
		return 1;
	}

// MDI client window message handlers
	LRESULT OnMDISetMenu(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/)
	{
		m_wndMDIClient.DefWindowProc(uMsg, NULL, lParam);
		HMENU hOldMenu = GetMenu();
		BOOL bRet = AttachMenu((HMENU)wParam);
		bRet;   // avoid level 4 warning
		ATLASSERT(bRet);

#if (_WIN32_IE >= 0x0400)
		T* pT = static_cast<T*>(this);
		pT->UpdateRebarBandIdealSize();
#endif // (_WIN32_IE >= 0x0400)

		return (LRESULT)hOldMenu;
	}

// All messages from the message hook
	LRESULT OnAllHookMessages(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
	{
		T* pT = static_cast<T*>(this);
		pT->_ProcessAllHookMessages(uMsg, wParam, lParam);

		bHandled = FALSE;
		return 1;
	}

// Overrideables
	// override this to provide different ideal size
	void UpdateRebarBandIdealSize()
	{
		// assuming we are in a rebar, change ideal size to our size
		// we hope that if we are not in a rebar, nCount will be 0
		int nCount = (int)::SendMessage(GetParent(), RB_GETBANDCOUNT, 0, 0L);
		for(int i = 0; i < nCount; i++)
		{
			REBARBANDINFO rbi = { RunTimeHelper::SizeOf_REBARBANDINFO(), RBBIM_CHILD | RBBIM_CHILDSIZE | RBBIM_IDEALSIZE };
			::SendMessage(GetParent(), RB_GETBANDINFO, i, (LPARAM)&rbi);
			if(rbi.hwndChild == m_hWnd)
			{
				rbi.fMask = RBBIM_IDEALSIZE;
				rbi.cxIdeal = m_bChildMaximized ? m_cxLeft + m_cxRight : 0;
				int nBtnCount = GetButtonCount();
				if(nBtnCount > 0)
				{
					RECT rect = { 0 };
					GetItemRect(nBtnCount - 1, &rect);
					rbi.cxIdeal += rect.right;
				}
				::SendMessage(GetParent(), RB_SETBANDINFO, i, (LPARAM)&rbi);
				break;
			}
		}
	}

	// all hook messages - check for the maximized MDI child window change
	void _ProcessAllHookMessages(UINT uMsg, WPARAM /*wParam*/, LPARAM /*lParam*/)
	{
		if(uMsg == WM_MDIGETACTIVE || uMsg == WM_MDISETMENU)
			return;

		BOOL bMaximized = FALSE;
		HWND hWndChild = (HWND)::SendMessage(m_wndMDIClient, WM_MDIGETACTIVE, 0, (LPARAM)&bMaximized);
		bool bMaxOld = m_bChildMaximized;
		m_bChildMaximized = (hWndChild != NULL && bMaximized);
		HICON hIconOld = m_hIconChildMaximized;

		if(m_bChildMaximized)
		{
			if(m_hWndChildMaximized != hWndChild)
			{
				ATL::CWindow wnd = m_hWndChildMaximized = hWndChild;
				m_hIconChildMaximized = wnd.GetIcon(FALSE);
				if(m_hIconChildMaximized == NULL)
				{
					m_hIconChildMaximized = wnd.GetIcon(TRUE);
					if(m_hIconChildMaximized == NULL)
					{
						// no icon set with WM_SETICON, get the class one
// need conditional code because types don't match in winuser.h
#ifdef _WIN64
						m_hIconChildMaximized = (HICON)::GetClassLongPtr(wnd, GCLP_HICONSM);
#else
						m_hIconChildMaximized = (HICON)LongToHandle(::GetClassLongPtr(wnd, GCLP_HICONSM));
#endif
					}
				}
			}
		}
		else
		{
			m_hWndChildMaximized = NULL;
			m_hIconChildMaximized = NULL;
		}

		if(bMaxOld != m_bChildMaximized)
		{
#ifdef _CMDBAR_EXTRA_TRACE
			ATLTRACE2(atlTraceUI, 0, _T("MDI CmdBar - All messages hook change: m_bChildMaximized = %s\n"), m_bChildMaximized ? "true" : "false");
#endif
			// assuming we are in a rebar, change our size to accomodate new state
			// we hope that if we are not in a rebar, nCount will be 0
			int nCount = (int)::SendMessage(GetParent(), RB_GETBANDCOUNT, 0, 0L);
			int cxDiff = (m_bChildMaximized ? 1 : -1) * (m_cxLeft + m_cxRight);
			for(int i = 0; i < nCount; i++)
			{
#if (_WIN32_IE >= 0x0500)
				REBARBANDINFO rbi = { RunTimeHelper::SizeOf_REBARBANDINFO(), RBBIM_CHILD | RBBIM_CHILDSIZE | RBBIM_IDEALSIZE | RBBIM_STYLE };
				::SendMessage(GetParent(), RB_GETBANDINFO, i, (LPARAM)&rbi);
				if(rbi.hwndChild == m_hWnd)
				{
					if((rbi.fStyle & RBBS_USECHEVRON) != 0)
					{
						rbi.fMask = RBBIM_CHILDSIZE | RBBIM_IDEALSIZE;
						rbi.cxMinChild += cxDiff;
						rbi.cxIdeal += cxDiff;
						::SendMessage(GetParent(), RB_SETBANDINFO, i, (LPARAM)&rbi);
					}
					break;
				}
#elif (_WIN32_IE >= 0x0400)
				REBARBANDINFO rbi = { RunTimeHelper::SizeOf_REBARBANDINFO(), RBBIM_CHILD | RBBIM_CHILDSIZE | RBBIM_IDEALSIZE };
				::SendMessage(GetParent(), RB_GETBANDINFO, i, (LPARAM)&rbi);
				if(rbi.hwndChild == m_hWnd)
				{
					rbi.fMask = RBBIM_CHILDSIZE | RBBIM_IDEALSIZE;
					rbi.cxMinChild += cxDiff;
					rbi.cxIdeal += cxDiff;
					::SendMessage(GetParent(), RB_SETBANDINFO, i, (LPARAM)&rbi);
					break;
				}
#else // (_WIN32_IE < 0x0400)
				REBARBANDINFO rbi = { RunTimeHelper::SizeOf_REBARBANDINFO(), RBBIM_CHILD | RBBIM_CHILDSIZE };
				::SendMessage(GetParent(), RB_GETBANDINFO, i, (LPARAM)&rbi);
				if(rbi.hwndChild == m_hWnd)
				{
					rbi.fMask = RBBIM_CHILDSIZE;
					rbi.cxMinChild += cxDiff;
					::SendMessage(GetParent(), RB_SETBANDINFO, i, (LPARAM)&rbi);
					break;
				}
#endif // (_WIN32_IE < 0x0400)
			}
		}

		if(bMaxOld != m_bChildMaximized || hIconOld != m_hIconChildMaximized)
		{
			// force size change and redraw everything
			RECT rect = { 0 };
			GetWindowRect(&rect);
			::MapWindowPoints(NULL, GetParent(), (LPPOINT)&rect, 2);
			SetRedraw(FALSE);
			SetWindowPos(NULL, 0, 0, 1, 1, SWP_NOZORDER | SWP_NOMOVE);
			SetWindowPos(NULL, &rect, SWP_NOZORDER | SWP_NOMOVE);
			SetRedraw(TRUE);
			RedrawWindow(NULL, NULL, RDW_FRAME | RDW_INVALIDATE | RDW_UPDATENOW);
		}
	}

// Implementation
	void GetSystemSettings()
	{
#ifdef _CMDBAR_EXTRA_TRACE
		ATLTRACE2(atlTraceUI, 0, _T("MDI CmdBar - GetSystemSettings\n"));
#endif
		_baseClass::GetSystemSettings();

		NONCLIENTMETRICS info = { RunTimeHelper::SizeOf_NONCLIENTMETRICS() };
		BOOL bRet = ::SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(info), &info, 0);
		ATLASSERT(bRet);
		if(bRet)
		{
			m_cxIconWidth = ::GetSystemMetrics(SM_CXSMICON);
			m_cyIconHeight = ::GetSystemMetrics(SM_CYSMICON);
			m_cxLeft = m_cxIconWidth;

#ifndef _WTL_NO_AUTO_THEME
			if(m_hTheme != NULL)
			{
				m_cxBtnWidth = info.iCaptionWidth - 2 * m_cxyOffset;
				m_cyBtnHeight = info.iCaptionHeight - 2 * m_cxyOffset;
				m_cxRight = 3 * m_cxBtnWidth;
			}
			else
#endif // !_WTL_NO_AUTO_THEME
			{
				m_cxBtnWidth = info.iCaptionWidth - m_cxyOffset;
				m_cyBtnHeight = info.iCaptionHeight - 2 * m_cxyOffset;
				m_cxRight = 3 * m_cxBtnWidth + m_cxyOffset;
			}
		}

		RECT rect = { 0 };
		GetClientRect(&rect);
		T* pT = static_cast<T*>(this);
		pT->_AdjustBtnSize(rect.bottom);
	}

	void _AdjustBtnSize(int cyHeight)
	{
		if(cyHeight > 1 && m_cyBtnHeight > cyHeight)
		{
#ifndef _WTL_NO_AUTO_THEME
			if(m_hTheme != NULL)
			{
				m_cyBtnHeight = cyHeight;
				m_cxBtnWidth = cyHeight;
				m_cxRight = 3 * m_cxBtnWidth;
			}
			else
#endif // !_WTL_NO_AUTO_THEME
			{
				m_cyBtnHeight = cyHeight;
				m_cxBtnWidth = cyHeight + m_cxyOffset;
				m_cxRight = 3 * m_cxBtnWidth + m_cxyOffset;
			}
		}
	}

	void _CalcIconRect(int cxWidth, int cyHeight, RECT& rect, bool bInvertX = false) const
	{
		int xStart = (m_cxLeft - m_cxIconWidth) / 2;
		if(xStart < 0)
			xStart = 0;
		int yStart = (cyHeight - m_cyIconHeight) / 2;
		if(yStart < 0)
			yStart = 0;

		if(bInvertX)
			::SetRect(&rect, cxWidth - (xStart + m_cxBtnWidth), yStart, cxWidth - xStart, yStart + m_cyBtnHeight);
		else
			::SetRect(&rect, xStart, yStart, xStart + m_cxBtnWidth, yStart + m_cyBtnHeight);
	}

	void _CalcBtnRects(int cxWidth, int cyHeight, RECT arrRect[3], bool bInvertX = false) const
	{
		int yStart = (cyHeight - m_cyBtnHeight) / 2;
		if(yStart < 0)
			yStart = 0;

		RECT rcBtn = { cxWidth - m_cxBtnWidth, yStart, cxWidth, yStart + m_cyBtnHeight };
		int nDirection = -1;
		if(bInvertX)
		{
			::SetRect(&rcBtn, 0, yStart, m_cxBtnWidth, yStart + m_cyBtnHeight);
			nDirection = 1;
		}

		arrRect[0] = rcBtn;
#ifndef _WTL_NO_AUTO_THEME
		if(m_hTheme != NULL)
			::OffsetRect(&rcBtn, nDirection * m_cxBtnWidth, 0);
		else
#endif // !_WTL_NO_AUTO_THEME
			::OffsetRect(&rcBtn, nDirection * (m_cxBtnWidth + m_cxyOffset), 0);
		arrRect[1] = rcBtn;
		::OffsetRect(&rcBtn, nDirection * m_cxBtnWidth, 0);
		arrRect[2] = rcBtn;
	}

	void _DrawMDIButton(CWindowDC& dc, LPRECT pRects, int nBtn)
	{
#ifndef _WTL_NO_AUTO_THEME
		if(m_hTheme != NULL)
		{
#ifndef TMSCHEMA_H
			const int WP_MDICLOSEBUTTON = 20;
			const int CBS_NORMAL = 1;
			const int CBS_PUSHED = 3;
			const int CBS_DISABLED = 4;
			const int WP_MDIRESTOREBUTTON = 22;
			const int RBS_NORMAL = 1;
			const int RBS_PUSHED = 3;
			const int RBS_DISABLED = 4;
			const int WP_MDIMINBUTTON = 16;
			const int MINBS_NORMAL = 1;
			const int MINBS_PUSHED = 3;
			const int MINBS_DISABLED = 4;
#endif // TMSCHEMA_H
			if(nBtn == -1 || nBtn == 0)
				m_pfnDrawThemeBackground(m_hTheme, dc, WP_MDICLOSEBUTTON, m_bParentActive ? ((m_nBtnPressed == 0) ? CBS_PUSHED : CBS_NORMAL) : CBS_DISABLED, &pRects[0], NULL);
			if(nBtn == -1 || nBtn == 1)
				m_pfnDrawThemeBackground(m_hTheme, dc, WP_MDIRESTOREBUTTON, m_bParentActive ? ((m_nBtnPressed == 1) ? RBS_PUSHED : RBS_NORMAL) : RBS_DISABLED, &pRects[1], NULL);
			if(nBtn == -1 || nBtn == 2)
				m_pfnDrawThemeBackground(m_hTheme, dc, WP_MDIMINBUTTON, m_bParentActive ? ((m_nBtnPressed == 2) ? MINBS_PUSHED : MINBS_NORMAL) : MINBS_DISABLED, &pRects[2], NULL);
		}
		else
#endif // !_WTL_NO_AUTO_THEME
		{
			if(nBtn == -1 || nBtn == 0)
				dc.DrawFrameControl(&pRects[0], DFC_CAPTION, DFCS_CAPTIONCLOSE | ((m_nBtnPressed == 0) ? DFCS_PUSHED : 0));
			if(nBtn == -1 || nBtn == 1)
				dc.DrawFrameControl(&pRects[1], DFC_CAPTION, DFCS_CAPTIONRESTORE | ((m_nBtnPressed == 1) ? DFCS_PUSHED : 0));
			if(nBtn == -1 || nBtn == 2)
				dc.DrawFrameControl(&pRects[2], DFC_CAPTION, DFCS_CAPTIONMIN | ((m_nBtnPressed == 2) ? DFCS_PUSHED : 0));
		}
	}

#ifndef _WTL_NO_AUTO_THEME
	static UINT _GetThemeChangedMsg()
	{
#ifndef WM_THEMECHANGED
		static const UINT WM_THEMECHANGED = 0x031A;
#endif // !WM_THEMECHANGED
		return WM_THEMECHANGED;
	}

	void _OpenThemeData()
	{
		ATLASSERT(m_hThemeDLL != NULL);

		PFN_OpenThemeData pfnOpenThemeData = (PFN_OpenThemeData)::GetProcAddress(m_hThemeDLL, "OpenThemeData");
		ATLASSERT(pfnOpenThemeData != NULL);
		if(pfnOpenThemeData != NULL)
			m_hTheme = pfnOpenThemeData(m_hWnd, L"Window");
	}

	void _CloseThemeData()
	{
		ATLASSERT(m_hThemeDLL != NULL);

		if(m_hTheme == NULL)
			return;   // nothing to do

		PFN_CloseThemeData pfnCloseThemeData = (PFN_CloseThemeData)::GetProcAddress(m_hThemeDLL, "CloseThemeData");
		ATLASSERT(pfnCloseThemeData != NULL);
		if(pfnCloseThemeData != NULL)
		{
			pfnCloseThemeData(m_hTheme);
			m_hTheme = NULL;
		}
	}
#endif // !_WTL_NO_AUTO_THEME

	bool _DebugCheckChild()
	{
#ifdef _DEBUG
		BOOL bMaximized = FALSE;
		HWND hWndChild = (HWND)::SendMessage(m_wndMDIClient, WM_MDIGETACTIVE, 0, (LPARAM)&bMaximized);
		return (bMaximized && hWndChild == m_hWndChildMaximized);
#else // !_DEBUG
		return true;
#endif // !_DEBUG
	}
};

class CMDICommandBarCtrl : public CMDICommandBarCtrlImpl<CMDICommandBarCtrl>
{
public:
	DECLARE_WND_SUPERCLASS(_T("WTL_MDICommandBar"), GetWndClassName())
};

}; // namespace WTL

#endif // __ATLCTRLW_H__
