// This is part of the Professional User Interface Suite library.
// Copyright (C) 2001-2004 FOSS Software, Inc.
// All rights reserved.
//
// http://www.prof-uis.com
// http://www.fossware.com
// mailto:support@fossware.com
//
// This source code can be used, modified and redistributed
// under the terms of the license agreement that is included
// in the Professional User Interface Suite package.
//
// Warranties and Disclaimers:
// THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND
// INCLUDING, BUT NOT LIMITED TO, WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
// IN NO EVENT WILL FOSS SOFTWARE INC. BE LIABLE FOR ANY DIRECT,
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES,
// INCLUDING DAMAGES FOR LOSS OF PROFITS, LOSS OR INACCURACY OF DATA,
// INCURRED BY ANY PERSON FROM SUCH PERSON'S USAGE OF THIS SOFTWARE
// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.

#if (!defined __EXT_POPUP_MENU_WND_H)
#define __EXT_POPUP_MENU_WND_H

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// ExtPopupMenuWnd.h : header file
//

#if (!defined __EXT_MFC_DEF_H)
	#include <ExtMfcDef.h>
#endif // __EXT_MFC_DEF_H

#if (!defined __AFXTEMPL_H__)
	#include <AfxTempl.h>
#endif

#if (!defined __EXT_CMD_ICON_H)
	#include <ExtCmdIcon.h>
#endif

#if (!defined __ExtCmdManager_H)
	#include <ExtCmdManager.h>
#endif

#if (!defined __EXT_MFC_NO_CUSTOMIZE)
	#if (!defined __EXTCUSTOMIZE_H)
		#include <ExtCustomize.h>
	#endif
#endif // (!defined __EXT_MFC_NO_CUSTOMIZE)

#define __BaseClassOfCExtPopupBaseWnd CWnd 
#define __EXT_MENU_DEF_INPLACE_EDIT_WIDTH 100

/////////////////////////////////////////////////////////////////////////////
// CExtSoundPlayer

class __PROF_UIS_API CExtSoundPlayer : public CObject
{
	struct __PROF_UIS_API InternalSoundEventInitDone_t : public CEvent
	{
		InternalSoundEventInitDone_t();
		void SetInitDone();
		void WaitInitDone();
	};
	struct __PROF_UIS_API InternalSoundThredadParms_t
	{
		InternalSoundEventInitDone_t * m_pEventInitDone;
		TCHAR m_sSoundSpecBuffer[1024];
		HANDLE m_hModule;
		DWORD m_dwPlayerFlags;
		HANDLE m_hThread;
		DWORD m_dwThreadID;
		static CEvent g_EventPlaySnd;
		static CCriticalSection g_CsPlaySnd;
		InternalSoundThredadParms_t(
			__EXT_MFC_SAFE_LPCTSTR sSoundSpecBuffer,
			HANDLE hModule,
			DWORD dwPlayerFlags
			);

		static DWORD WINAPI stat_ParallelPlayerProc(
			InternalSoundThredadParms_t * pParms
			);
		operator LPTHREAD_START_ROUTINE() const
		{
			return (LPTHREAD_START_ROUTINE)stat_ParallelPlayerProc;
		};
	
		void PlaySound();
		void PlaySoundParallel();
	}; // struct __PROF_UIS_API InternalSoundThredadParms_t

public:

	DECLARE_DYNCREATE( CExtSoundPlayer );

	class __PROF_UIS_API CExtSoundPlayerAutoPtr
	{
		CExtSoundPlayer * m_pPlayer;
	public:
		CExtSoundPlayerAutoPtr();
		~CExtSoundPlayerAutoPtr();
		void InstallSoundPlayer(
			CExtSoundPlayer * pPlayer
			);
		CExtSoundPlayer * operator->()
		{
			ASSERT( m_pPlayer != NULL );
			ASSERT_VALID( m_pPlayer );
			return m_pPlayer;
		};
	}; // class CExtSoundPlayerAutoPtr
	
	CExtSoundPlayer();
	~CExtSoundPlayer();

	enum e_ui_sounds_t
	{
	__NO_SOUND					= 0,
	__ON_MENU_EXPAND_CLICKED	= 1,
	__ON_MENU_POPUP_DISPLAYED	= 2,
	__ON_MENU_CMD_CLICKED		= 3,
	}; // enum e_ui_sounds_t

	virtual void PlaySound(
		CExtSoundPlayer::e_ui_sounds_t eSoundID
		);
}; // class CExtSoundPlayer

extern __PROF_UIS_API CExtSoundPlayer::CExtSoundPlayerAutoPtr g_SoundPlayer;

/////////////////////////////////////////////////////////////////////////////
// CExtWndShadow

class __PROF_UIS_API CExtWndShadow
{
	CBitmap m_bmp0, m_bmp1;				// photo of right & bottom shadow parts to save/restore
	COLORREF * m_pHelperDibSurface;
	CRect m_rcWndArea;					// window are not including shadow
	CRect m_rc1stArea;					// basic area
	CRect m_rc2ndArea;					// combined area
	UINT m_nShadowSize;					// shadow size (in pixels)
	UINT m_nBr0,m_nBr1;					// min/max brightness percents [0..100]
	bool m_bEnablePhotos:1;				// use photo bitmaps
	bool m_bEnablePaintManagerColor:1;	// use paing manager's shadow color
	CRgn m_rgnSafe;
	void _FreeWinObjects();
	void _DoPixelOvershadow(
		int nMakeSpec,
		int nPosX,
		int nPosY,
		COLORREF clrShadowAdjust
		);
	bool _MakePhotos( CDC & dc, CDC & dcmm );
	bool _PaintLo( CDC & dc );
	bool _PaintHi( CDC & dc );
public:
	enum eShadowOptions
	{
		DEF_BRIGHTNESS_MIN =  75UL, // default min brightness percent
		DEF_BRIGHTNESS_MAX = 100UL, // default max brightness percent
		DEF_SHADOW_SIZE    =   3UL, // default shadow size (in pixels)
	};

	CExtWndShadow();
	~CExtWndShadow();
	
	bool Restore( CDC & dc );
	bool Paint(
		CDC & dc,
		bool m_bMakePhotosOnly = false
		);
	bool Paint(
		CDC & dc,
		const CRect & rcWndArea,
		const CRect & rc1stArea = CRect(0,0,0,0),
		const CRect & rc2ndArea = CRect(0,0,0,0),
		UINT nShadowSize = DEF_SHADOW_SIZE,
		UINT nBr0 = DEF_BRIGHTNESS_MIN,
		UINT nBr1 = DEF_BRIGHTNESS_MAX,
		bool bEnablePhotos = true,
		bool bEnablePaintManagerColor = true,
		bool m_bMakePhotosOnly = false
		);
	bool HavePhotos() const;
	void Destroy();
}; // class CExtWndShadow


/////////////////////////////////////////////////////////////////////////////
// CExtPopupBaseWnd

class __PROF_UIS_API CExtPopupBaseWnd :
	public __BaseClassOfCExtPopupBaseWnd
{
public:
	DECLARE_DYNCREATE(CExtPopupBaseWnd)

	CExtPopupBaseWnd();

	virtual BOOL DestroyWindow();

// Overrides
	// ClassWizard generated virtual function overrides
	//{{AFX_VIRTUAL(CExtPopupBaseWnd)
	protected:
	virtual void PostNcDestroy();
	//}}AFX_VIRTUAL

// Implementation
public:
	virtual ~CExtPopupBaseWnd();

	static UINT g_nMsgPrepareMenu; // prepare popup-menu window message
	static UINT g_nMsgPopupNext;
	static UINT g_nMsgPopupPrev;
	static UINT g_nMsgNotifyMenuExpanded;
	static UINT g_nMsgNotifyMenuClosed;
	static UINT g_nMsgPopupDrawItem;
	static UINT g_nMsgPopupDrawLeftArea;
	static UINT g_nMsgCreateInplaceEdit;

	enum e_combine_align_t // relatively to menu window rect
	{
		__CMBA_NONE = 0,
		__CMBA_TOP = 1,
		__CMBA_BOTTOM = 2,
		__CMBA_RIGHT = 3,
		__CMBA_LEFT = 4,
	};

	typedef
		void (*pCbPaintCombinedContent)(
			LPVOID pCookie,
			CDC & dc,
			const CWnd & refWndMenu,
			const CRect & rcExcludeArea, // in screen coords
			int eCombineAlign // CExtPopupMenuWnd::e_combine_align_t values
			);

	enum e_animation_type_t
	{
		__AT_NONE = 0,
		__AT_RANDOM = 1,
		__AT_ROLL = 2,
		__AT_SLIDE = 3,
		__AT_FADE = 4,
		__AT_ROLL_AND_STRETCH = 5,
		__AT_SLIDE_AND_STRETCH = 6,
		__AT_NOISE = 7,
		__AT_BOXES = 8,
		__AT_CIRCLES = 9,
		__AT_HOLES = 10,
		
		__AT_MAX_VALID_VALUE = 10, // used for random effect selection
		__AT_CONTENT_DISPLAY = -1, // internal helper - delayed display
		__AT_CONTENT_EXPAND = -2 // internal helper - funny expand/stretch rarely used items (office XP like)
	};
	static e_animation_type_t g_DefAnimationType;
	static CExtSafeString GetAnimaptionName( e_animation_type_t eAT );

	static bool g_bUseDesktopWorkArea; // align to desktop work area (false - to screen area)
	static bool g_bEnableOnIdleCalls; // enable idle time processing

protected:
	
	CRect m_rcExcludeArea;
	CPoint m_ptTrack;
	bool m_bExcludeAreaSpec:1,m_bCombineWithEA:1;

	LPVOID m_pCbPaintCombinedCookie;
	pCbPaintCombinedContent m_pCbPaintCombinedContent;
	bool m_bCookieIsObject;

public:
	virtual CObject * GetCoockieAsObject();
	virtual bool IsToolBtnCombinedArea() const;
	pCbPaintCombinedContent GetCbPaintCombinedContent() const
	{
		return (pCbPaintCombinedContent) m_pCbPaintCombinedContent;
	}
	LPVOID GetCbPaintCombinedCookie() const
	{
		return (LPVOID)m_pCbPaintCombinedCookie;
	}

protected:
	e_animation_type_t m_AnimationType;
	CExtSoundPlayer::e_ui_sounds_t m_ePlaySoundOnAnimationFinished;

	COLORREF * m_clrFadeBitsSrc;
	COLORREF * m_clrFadeBitsDst;
	COLORREF * m_clrFadeBitsTmp;
	int m_nAnimPercent,m_nAnimPercentOld;
	bool m_bAnimFinished:1;

	CSize m_sizeFullItems;

	CExtWndShadow m_ShadowMain, m_ShadowCMBA;
	CBitmap
		m_bmpScreenSrc,m_bmpScreenDst,m_bmpScreenTmp;
		//m_bmpSaveBits;

	virtual bool _FindCustomizeMode() const;
	virtual void _InitAnimation();
	virtual void _StartAnimation();
	virtual void _AdjustAnimation( e_animation_type_t & eAT );

	void _SurfacesDelete()
	{
		ASSERT_VALID( this );

		if( m_bmpScreenDst.GetSafeHandle() != NULL )
		{
			VERIFY(
				m_bmpScreenDst.DeleteObject()
				);
		}
		if( m_bmpScreenSrc.GetSafeHandle() != NULL )
		{
			VERIFY(
				m_bmpScreenSrc.DeleteObject()
				);
		}
		if( m_bmpScreenTmp.GetSafeHandle() != NULL )
		{
			VERIFY(
				m_bmpScreenTmp.DeleteObject()
				);
		}
		m_clrFadeBitsSrc
			= m_clrFadeBitsDst
			= m_clrFadeBitsTmp
			= NULL;
	}
	
	virtual void _EndAnimation()
	{
		ASSERT_VALID( this );

		_SurfacesDelete();
	}

	virtual bool _IsPopupWithShadows() const;
	virtual int _GetPopupShadowSize() const;

	virtual void _DrawAnimatedState( CDC & dc );
public:
	virtual void _DoPaint( CDC & dcPaint, bool bUseBackBuffer = true );
protected:
	virtual void _GetClientRect(RECT * pRectClient)
	{
		ASSERT_VALID( this );

		ASSERT( GetSafeHwnd() != NULL );
		ASSERT( pRectClient != NULL );
		GetClientRect(pRectClient);
	}
	void _GetClientRect(RECT & rectClient)
	{
		ASSERT_VALID( this );

		_GetClientRect( &rectClient );
	}

public:
	virtual bool _FindHelpMode() const;

protected:

	// Generated message map functions
	//{{AFX_MSG(CExtPopupBaseWnd)
	afx_msg int OnMouseActivate(CWnd* pDesktopWnd, UINT nHitTest, UINT message);
	afx_msg BOOL OnEraseBkgnd(CDC* pDC);
	afx_msg void OnPaint();
	afx_msg void OnNcPaint();
	afx_msg void OnNcCalcSize(BOOL bCalcValidRects, NCCALCSIZE_PARAMS FAR* lpncsp);
	afx_msg void OnSize(UINT nType, int cx, int cy);
	afx_msg BOOL OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message);
	afx_msg void OnTimer(UINT nIDEvent);
	//}}AFX_MSG
	DECLARE_MESSAGE_MAP()

}; // class CExtPopupBaseWnd

/////////////////////////////////////////////////////////////////////////////
// CExtPopupMenuTipWnd

class __PROF_UIS_API CExtPopupMenuTipWnd :
	public CExtPopupBaseWnd
{
	CSize m_IconSize;
	HICON m_hIcon;
	CExtSafeString m_sText;
	HRGN m_hRgn;
	bool m_bFlipHorz:1,m_bFlipVert:1;

public:
	DECLARE_DYNCREATE(CExtPopupMenuTipWnd)


	CExtPopupMenuTipWnd();

// Overrides
	// ClassWizard generated virtual function overrides
	//{{AFX_VIRTUAL(CExtPopupMenuTipWnd)
	//}}AFX_VIRTUAL

// Implementation
public:
	virtual ~CExtPopupMenuTipWnd();

	void SetIcon(HICON hIcon);
	void SetText(__EXT_MFC_SAFE_LPCTSTR lpszText);

	bool Show(
		CWnd * pWndParent,
		const RECT & rcExcludeArea
		);
	void Hide();

protected:
	bool GetWindowRegion(
		CDC* pDC,
		HRGN* hRegion,
		CSize *Size = NULL
		);
public:
	virtual void _DoPaint( CDC & dcPaint, bool bUseBackBuffer = true );
protected:

	// Generated message map functions
	//{{AFX_MSG(CExtPopupMenuTipWnd)
	//}}AFX_MSG
	DECLARE_MESSAGE_MAP()

}; // class CExtPopupMenuTipWnd

/////////////////////////////////////////////////////////////////////////////
// CExtPopupMenuSite

class CExtPopupMenuWnd;
class CExtPopupColorMenuWnd;
class CExtPopupInplaceListBox;

class __PROF_UIS_API CExtPopupMenuSite
{
	bool m_bShutdownMode:1;
	CExtPopupMenuWnd
		* m_pTopMenu,
		* m_pWndCapture,
		* m_pWndAnimation;
	HHOOK m_hMouseHook;
	HHOOK m_hKeyboardHook;
	UINT * m_lpnResultCmdID;

	void _Done();

	// hooks
	static LRESULT CALLBACK _HookMouseProc(
		int nCode,      // hook code
		WPARAM wParam,  // message identifier
		LPARAM lParam   // mouse coordinates
		);
	static LRESULT CALLBACK _HookKeyboardProc(
		int nCode,      // hook code
		WPARAM wParam,  // virtual-key code
		LPARAM lParam   // keystroke-message information
		);
	void _Hook( bool bHook = true );

public:
	
	CExtPopupMenuSite();
	~CExtPopupMenuSite();

	bool IsEmpty() const
	{
		return (m_pTopMenu == NULL) ? true : false;
	}
	bool IsShutdownMode() const
	{
		return m_bShutdownMode;
	}

	void SetTargetCmdIdPtr( UINT * lpnResultCmdID = NULL );
	UINT * GetTargetCmdIdPtr();

	CExtPopupMenuWnd * GetCapture();
	void SetCapture( CExtPopupMenuWnd * pNewPopup = NULL );

	CExtPopupMenuWnd * GetAnimated();
	void SetAnimated( CExtPopupMenuWnd * pNewPopup = NULL );

	void SetInstance( CExtPopupMenuWnd * pTopMenu = NULL );
	CExtPopupMenuWnd * GetInstance();
	void DoneInstance();
	
	void operator=( CExtPopupMenuWnd * pTopMenu )
	{
		SetInstance(pTopMenu);
	}

	CExtPopupMenuWnd * operator->()
	{
		ASSERT( !IsEmpty() );
		ASSERT( !IsShutdownMode() );
		ASSERT( m_pTopMenu != NULL );
		return m_pTopMenu;
	}

	bool IsTopPopup(
		CExtPopupMenuWnd * pTopMenu
		) const;

	static CExtPopupMenuSite g_DefPopupMenuSite;

	friend class CExtPopupBaseWnd;
	friend class CExtPopupMenuWnd;
}; // class CExtPopupMenuSite

/////////////////////////////////////////////////////////////////////////////
// CExtPopupMenuWnd

// track flags (menu area align)
#define TPMX_LEFTALIGN				0x00000001L
#define TPMX_CENTERALIGN			0x00000002L
#define TPMX_RIGHTALIGN				0x00000003L
#define TPMX_TOPALIGN				0x00000004L
#define TPMX_VCENTERALIGN			0x00000005L
#define TPMX_BOTTOMALIGN			0x00000006L
#define TPMX_ALIGN_MASK				0x0000000FL
// track flags (menu area combine type)
#define TPMX_COMBINE_NONE			0x00000000L // do not combine menu area with lpRect
#define TPMX_COMBINE_ANY_SUITABLE	0x00000010L // try combine menu area with lpRect
#define TPMX_COMBINE_DEFAULT		0x00000020L // do like PaintManager said
#define TPMX_COMBINE_MASK			0x00000030L
// select first enabled menu item
#define TPMX_SELECT_ANY				0x00000040L
// perform message loop
#define TPMX_DO_MESSAGE_LOOP		0x00000080L
// initially expand rarely used items
#define TPMX_NO_HIDE_RARELY			0x00000100L
// do not post WM_COMMAND message
// (result could be stored in lpnResultCmdID)
#define TPMX_NO_WM_COMMAND			0x00000200L
// do not update cmdui
#define TPMX_NO_CMD_UI				0x00000400L
// ownerdraw items
// (variable sizes are not supported)
#define TPMX_OWNERDRAW_FIXED		0x00000800L
// force no shadows
#define TPMX_NO_SHADOWS				0x00001000L
// help ctx mode
#define TPMX_HELP_CTX_MODE			0x00002000L
// customize mode / no menu site control
#define TPMX_CUSTOMIZE_MODE			0x00004000L

class __PROF_UIS_API CExtPopupMenuWnd
	: public CExtPopupBaseWnd
#if (!defined __EXT_MFC_NO_CUSTOMIZE)
	, public CExtCustomizeSite::ICustomizeDropTarget
	, public CExtCustomizeSite::ICustomizeDropSource
#endif // (!defined __EXT_MFC_NO_CUSTOMIZE)
{
	friend class CExtControlBar;
	friend class CExtToolControlBar;
	friend class CExtMenuControlBar;

	class __PROF_UIS_API InternalFriendlyWinApp : CWinApp
	{
	public:
		inline static InternalFriendlyWinApp * _GetFriendlyApp()
		{
			CWinApp * pApp = ::AfxGetApp();
			ASSERT( pApp != NULL );
			return (InternalFriendlyWinApp *)pApp;
		}
		CRecentFileList * _GetRecentFileList()
		{
			//ASSERT( m_pRecentFileList != NULL );
			return m_pRecentFileList;
		}
	}; // class InternalFriendlyWinApp

public:

	// is allowed menu item positioning without
	// using only & - marked text
	static bool g_bAllowNonAccelPositioning;

	friend class CExtPopupMenuSite;

public:
	DECLARE_DYNCREATE(CExtPopupMenuWnd)

	CExtPopupMenuWnd();

// Attributes
public:

	virtual int _GetCurIndex() const;
	void _DoShowChain( int nCmdShow = SW_SHOWNA );
	void _DoResetChainPositions();
protected:
	void _DoResetChainPositionsImpl(
		CExtPopupMenuWnd * pPrev
		);

#if (!defined __EXT_MFC_NO_CUSTOMIZE)
public:
	int m_nHelperDropIndexBefore;
	virtual void _SetDropIndexBefore(
		int nIndex = -1 // reset
		);
protected:
	bool m_bHelperNoHideChild:1, m_bHelperNoRemoveSrc:1, m_bHelperDragOverPassed:1;
	CPoint m_ptHelperDragStart;
	int m_nDragSrcIdx;
	CExtCustomizeCmdTreeNode * m_pNode, * m_pDragSrcNode;
	CExtCustomizeSite * m_pCustomizeSite;
public:
	CExtCustomizeCmdTreeNode * _CmdNodeGet()
	{
		ASSERT_VALID( this );
#ifdef _DEBUG
		if( m_pNode != NULL )
		{
			ASSERT_VALID( m_pNode );
		}
#endif // _DEBUG
		return m_pNode;
	}
	const CExtCustomizeCmdTreeNode * _CmdNodeGet() const
	{
		ASSERT_VALID( this );
#ifdef _DEBUG
		if( m_pNode != NULL )
		{
			ASSERT_VALID( m_pNode );
		}
#endif // _DEBUG
		return m_pNode;
	}
	void _CmdNodeSet( CExtCustomizeCmdTreeNode * pNode )
	{
		ASSERT_VALID( this );
#ifdef _DEBUG
		if( pNode != NULL )
		{
			ASSERT_VALID( pNode );
		}
#endif // _DEBUG
		m_pNode = pNode;
	}
	virtual CExtCustomizeSite * _FindCustomizeSite() const;
protected:
	// CExtCustomizeSite::ICustomizeDropTarget
	virtual DROPEFFECT OnCustomizeTargetOver(
		CExtCustomizeSite::CCmdDragInfo & _dragInfo,
		CPoint point,
		DWORD dwKeyState
		);
	virtual void OnCustomizeTargetLeave();
	virtual bool OnCustomizeTargetDrop(
		CExtCustomizeSite::CCmdDragInfo & _dragInfo,
		CPoint point,
		DROPEFFECT de
		);
	// CExtCustomizeSite::ICustomizeDropSource
	virtual void OnCustomizeSourceDragComplete(
		DROPEFFECT de,
		bool bCanceled,
		bool * p_bNoResetActiveItem
		);
#endif // (!defined __EXT_MFC_NO_CUSTOMIZE)
	virtual bool _FindCustomizeMode() const;

	CExtPopupMenuTipWnd m_wndToolTip;

	int m_nCurIndex, m_nDelayedFocusItemIndex,
		//m_nDelayedHidingItemIndex,
		m_nLastMousePick;
	bool
		m_bTopLevel:1,
		m_bScrollingAvailable:1,
		m_bExpandAvailable:1,
		m_bExpandWasPressed:1;
		//m_bDelayedHiding:1;
	UINT m_nWaitingExpandTickCount;
	DWORD m_dwTrackFlags;

	HWND m_hWndCmdReceiver;

	//CPoint m_ptTrack;
	int m_nDyScrollOffset;
	CExtPopupMenuWnd * m_pWndParentMenu;

	CRect
		m_rcScrollTop,
		m_rcScrollBottom,
		m_rcExpandBtn;
	int m_nScrollingDirection;

	UINT m_nLeftAreaWidth;

public:
	CExtPopupMenuWnd * GetParentMenuWnd()
	{
		return m_pWndParentMenu;
	}
	const CExtPopupMenuWnd * GetParentMenuWnd() const
	{
		return m_pWndParentMenu;
	}
	virtual HWND GetCmdReceiverHWND()
	{
		ASSERT( m_hWndCmdReceiver != NULL );
		ASSERT( ::IsWindow( m_hWndCmdReceiver ) );
		return m_hWndCmdReceiver;
	}
protected:
	enum spec_buttons_index_t
	{
		IDX_NOTHING = -1,
		IDX_SCROLL_TOP = -2,
		IDX_SCROLL_BOTTOM = -3,
		IDX_EXPAND = -4
	};
// Operations
public:
	virtual BOOL LoadMenu( 
		HWND hWndCmdRecv,
		UINT nIDResource,
		bool bPopupMenu = true
		);
	virtual HMENU ExportToMenu(
		BOOL bDeep = TRUE
		) const;
	virtual BOOL UpdateFromMenu( 
		HWND hWndCmdRecv,
		CMenu *pBuildMenu,
		bool bPopupMenu = true,
		bool bTopLevel = true
		);
#if (!defined __EXT_MFC_NO_CUSTOMIZE)
	bool UpdateFromCmdTree(
		HWND hWndCmdRecv,
		CExtCustomizeCmdTreeNode * pNode,
		bool bTopLevel = true
		);
#endif // (!defined __EXT_MFC_NO_CUSTOMIZE)
	virtual BOOL UpdateMdiWindowsMenu(
		CWnd * pWndStartSearchMdiFrameWnd = NULL
		);
	virtual void SetCmdTargetToAllItems(
		HWND hWndSpecCmdReceiver = NULL,
		bool bOnlyThisLevel = false
		);

	enum menu_item_type_t
	{
		TYPE_POPUP		= 0xFFFFFFFF,
		TYPE_SEPARATOR	= 0x00000000 // same as ID_SEPARATOR
	};

	virtual INT ItemGetCount() const;
	virtual UINT ItemGetCmdID( // menu_item_type_t values can be returned
		INT nPos
		) const;
	virtual HICON ItemGetIcon( INT nPos ) const;
	virtual CExtSafeString ItemGetText( INT nPos ) const;
	virtual CExtSafeString ItemGetAccelText( INT nPos ) const;
	virtual INT ItemFindPosForCmdID(
		UINT nCmdID,
		INT nPosStart = -1
		) const;
	virtual bool ItemSetPopupIcon(
		INT nPos,
		HICON hIcon = NULL // no icon by default
		);
	virtual bool ItemSetPopupText(
		INT nPos,
		__EXT_MFC_SAFE_LPCTSTR sText // NULL if empty
		);
	virtual bool ItemSetPopupAccelText(
		INT nPos,
		__EXT_MFC_SAFE_LPCTSTR sText // NULL if empty
		);
	virtual CExtPopupMenuWnd * ItemGetPopup(
		INT nPos
		);
	virtual const CExtPopupMenuWnd * ItemGetPopup(
		INT nPos
		) const;
	virtual bool ItemIsDisplayed(
		INT nPos
		) const;
	virtual void ItemSetDisplayed(
		INT nPos,
		bool bForceDisplayed = true
		);
	virtual BOOL ItemRemove(
		INT nPos = -1 // remove all
		);
	virtual BOOL ItemInsert(
		UINT nCmdID = TYPE_SEPARATOR,
		INT nPos = -1, // append
		__EXT_MFC_SAFE_LPCTSTR sText = NULL, // for TYPE_POPUP only
		HICON hIcon = NULL, // for TYPE_POPUP only
		HWND hWndSpecCmdReceiver = NULL // specific command receiver
		);
	virtual BOOL ItemInsertCommand( // no references to command manager
		UINT nCmdID,
		INT nPos, // -1 append
		__EXT_MFC_SAFE_LPCTSTR sItemText, // may be NULL
		__EXT_MFC_SAFE_LPCTSTR sAccelText, // may be NULL
		const CExtCmdIcon & icon,
		int nCheck = 0, // 0 - no check, 1 - checked, 2 - indeterminate, 3 - radio
		HWND hWndSpecCmdReceiver = NULL
		);
	BOOL ItemInsertCommand( // no references to command manager
		UINT nCmdID = TYPE_SEPARATOR,
		INT nPos = -1, // append
		__EXT_MFC_SAFE_LPCTSTR sItemText = NULL,
		__EXT_MFC_SAFE_LPCTSTR sAccelText = NULL,
		HICON hIcon = NULL,
		bool bCopyIcon = true,
		int nCheck = 0, // 0 - no check, 1 - checked, 2 - indeterminate, 3 - radio
		HWND hWndSpecCmdReceiver = NULL
		);
	virtual BOOL ItemInsertSpecPopup( // insert specific popup implementation
		CExtPopupMenuWnd * pSpecPopup,
		INT nPos = -1, // append
		__EXT_MFC_SAFE_LPCTSTR sText = NULL,
		HICON hIcon = NULL
		);
	virtual INT ItemFindByAccessChar(
		__EXT_MFC_SAFE_TCHAR chrAccess,
		INT nStartIdx = -1,
		BOOL bRestartAt0 = TRUE
		) const;
	virtual INT ItemFindByText(
		__EXT_MFC_SAFE_LPCTSTR sText,
		INT nStartIdx = -1,
		BOOL bRestartAt0 = TRUE
		) const;

	virtual bool IsAllItemsRarelyUsed() const;
	virtual BOOL CreatePopupMenu( HWND hWndCmdRecv ); // alternative to LoadMenu()

	void SetLeftAreaWidth( UINT nWidth = 0 );
	UINT GetLeftAreaWidth() const;

	static CExtPopupMenuWnd * GetTrackingMenu();
	static void CancelMenuTracking();
	inline static BOOL IsKeyPressed(
		int nVirtKey
		)
	{
		SHORT nKeyState =
			::GetKeyState( nVirtKey );
		if( (nKeyState & (1 << (sizeof(SHORT)*8-1))) != 0 )
			return TRUE;
		return FALSE;
	}
	static BOOL IsCmdKeyActivation(
		LPARAM lParam = 0
		);
	static BOOL IsMenuTracking();

	virtual BOOL TrackPopupMenu(
		DWORD dwTrackFlags,
		int x,
		int y,
		LPCRECT lpRect = NULL,
		LPVOID pCbPaintCombinedCookie = NULL,
		pCbPaintCombinedContent pCbPaintCombinedContent = NULL,
		UINT * lpnResultCmdID = NULL,
		bool bCookieIsObject = false
		);

	struct __PROF_UIS_API MsgPrepareMenuData_t
	{
		bool m_bMenuChanged:1;
		bool m_bMenuCanceled:1;
		CExtPopupMenuWnd * m_pPopup;

		MsgPrepareMenuData_t(
			CExtPopupMenuWnd * pPopup
			)
			: m_bMenuChanged( false )
			, m_bMenuCanceled( false )
			, m_pPopup( pPopup )
		{
			ASSERT( m_pPopup != NULL );
		}
		~MsgPrepareMenuData_t()
		{
		}

		operator WPARAM() const
		{
			return WPARAM( this );
		}

		LRESULT SendMessage( HWND hWnd )
		{
			ASSERT( m_pPopup != NULL );

			ASSERT( hWnd != NULL );
			ASSERT( ::IsWindow(hWnd) );
			LRESULT lResult =
				::SendMessage(
					hWnd,
					CExtPopupMenuWnd::g_nMsgPrepareMenu,
					WPARAM( *this ),
					LPARAM( m_pPopup )
					);
			
			return lResult;
		}
		LRESULT SendMessage( CWnd * pWnd )
		{
			return SendMessage( pWnd->GetSafeHwnd() );
		}
	}; // struct MsgPrepareMenuData_t

	static bool g_bFullScreenMode;
	static bool g_bMenuWithShadows; // allow shadows
	static bool g_bMenuExpanding; // allow hide rarely used
	static bool g_bMenuDelayExpanding; // show full menu after short delay
	static bool g_bMenuHighlightRarely; // display rarely used in different style
	static bool g_bMenuShowCoolTips; // allow display cool tooltips
	static bool g_bMenuExpandAnimation; // allow animation when show rarely used
	static bool g_bUseStretchOnExpandAnimation; // use StretchBlt() instead of BitBlt() for painting menu expand amimation
	static bool g_bMenuLargeIcons; // use large icons

public:
	static void stat_paint_combined_menu_toolbtn(
		LPVOID pCookie,
		CDC & dc,
		const CWnd & refWndMenu,
		const CRect & rcExcludeArea, // in screen coords
		int eCombineAlign // CExtPopupMenuWnd::e_combine_align_t values
		);
protected:
	virtual bool _CreateHelper(
		CWnd * pWndCmdReceiver
		);
	virtual bool _BuildItems(
		CMenu * pBuildMenu,
		bool bTopLevel
		);
	virtual void _UpdateCmdUI();
	virtual void _Init();
	virtual void _RecalcLayoutImpl();
	static int _GetSpecBtnHeight();
public:
	virtual int OnQueryMenuBorderSize() const;
	virtual int _HitTest(
		const CPoint & point,
		bool * p_bInplaceControlArea = NULL,
		bool * p_bInplaceDropDownArea = NULL
		);
protected:
	virtual void _DrawAnimatedState( CDC & dc );
public:
	virtual void _DoPaint( CDC & dcPaint, bool bUseBackBuffer = true );
protected:
	virtual void _GetClientRect(RECT * pRectClient);
public:
	static void PassMsgLoop(
		bool bEnableOnIdleCalls
		);
protected:

	struct __PROF_UIS_API ExpandEffectRects_t
	{
		CRect m_rcSrc,m_rcDst;
		ExpandEffectRects_t()
		{
			m_rcSrc.SetRectEmpty();
			m_rcDst.SetRectEmpty();
		};
		ExpandEffectRects_t(
			const RECT & rcSrc,
			const RECT & rcDst
			)
		{
			m_rcSrc = rcSrc;
			m_rcDst = rcDst;
		}
		ExpandEffectRects_t(
			const ExpandEffectRects_t & other
			)
		{
			m_rcSrc = other.m_rcSrc;
			m_rcDst = other.m_rcDst;
		}
		ExpandEffectRects_t &
			operator= (
				const ExpandEffectRects_t & other
				)
		{
			m_rcSrc = other.m_rcSrc;
			m_rcDst = other.m_rcDst;
			return * this;
		}
	}; // struct ExpandEffectRects_t

	typedef
		CArray < ExpandEffectRects_t, ExpandEffectRects_t & >
		expand_effect_rects_container_t;

	struct __PROF_UIS_API VisibleItemDefinition_t
	{
		INT m_nIndex;
		bool m_bRarelyUsed:1;
		bool m_bRarelyUsedPrev:1;
		bool m_bRarelyUsedNext:1;
		bool m_bHelperIsSeparator:1;
		bool m_bHelperIsPopup:1;
		UINT m_nHelperCmdID;
		CRect m_rcItem;
		VisibleItemDefinition_t()
		{
			m_nIndex = -1;
			m_bRarelyUsed
				= m_bRarelyUsedPrev
				= m_bRarelyUsedNext
				= m_bHelperIsSeparator
				= m_bHelperIsPopup
				= false;
			m_nHelperCmdID = ID_SEPARATOR;
			m_rcItem.SetRectEmpty();
		}
		VisibleItemDefinition_t(
			const VisibleItemDefinition_t & other
			)
		{
			AssignFromOther(other);
		}
		~VisibleItemDefinition_t()
		{
		}
		VisibleItemDefinition_t & operator=(
			const VisibleItemDefinition_t & other
			)
		{
			AssignFromOther(other);
			return * this;
		}
		void AssignFromOther(
			const VisibleItemDefinition_t & other
			)
		{
			m_nIndex = other.m_nIndex;
			m_bRarelyUsed = other.m_bRarelyUsed;
			m_bRarelyUsedPrev = other.m_bRarelyUsedPrev;
			m_bRarelyUsedNext = other.m_bRarelyUsedNext;
			m_bHelperIsSeparator = other.m_bHelperIsSeparator;
			m_bHelperIsPopup = other.m_bHelperIsPopup;
			m_nHelperCmdID = other.m_nHelperCmdID;
			m_rcItem = other.m_rcItem;
		}
		operator int() const
		{
			return m_nIndex;
		}
	};

	typedef
		CArray < VisibleItemDefinition_t, VisibleItemDefinition_t & >
		visible_items_t;
	virtual void _GetVisibleItems(
		HDC hDcTest, // may be NULL
		visible_items_t & v
		);

	//virtual void _DelayHide( bool bDelay );
	virtual BOOL _TrackPopupMenu(
		DWORD dwTrackFlags,
		int x,
		int y,
		LPCRECT lpRect,
		LPVOID pCbPaintCombinedCookie = NULL,
		pCbPaintCombinedContent pCbPaintCombinedContent = NULL,
		bool bCookieIsObject = false
		);
public:
	virtual void _ItemFocusCancel( BOOL bRepaint );
	virtual void _ItemFocusDelay( int nItemIndex = IDX_NOTHING );
	virtual void _ItemFocusSet(
		int nCurIndex,
		BOOL bEnableDropChild,
		BOOL bRepaint,
		BOOL bSelectAnyInChild = TRUE
		);
	virtual void _GetItemRect(
		int nIndex,
		RECT & rectItem
		);
public:
	virtual bool _OnMouseWheel(
		WPARAM wParam,
		LPARAM lParam,
		bool & bNoEat
		);
	virtual bool _OnMouseMove(
		UINT nFlags,
		CPoint point,
		bool & bNoEat
		);
	virtual bool _OnMouseClick(
		UINT nFlags,
		CPoint point,
		bool & bNoEat
		);
	virtual bool _OnKeyDown(
		UINT nChar,
		UINT nRepCnt,
		UINT nFlags,
		bool & bNoEat
		);

	virtual bool _CanStartLevelTracking();

protected:
	virtual void _FreeWinObjects();
	virtual void _OnCancelMode(
		bool bNcDestroy = false
		);
	virtual bool _PtInWndArea( CPoint ptClient );


public:
	virtual void _SetCapture();
	virtual CExtPopupMenuWnd * _GetCapture();
	virtual void _ReleaseCapture();
protected:

	virtual int _GetMaxScrollPos();
	virtual bool _StartScrolling(int nButtonIndex);

public:
	virtual void _SyncItems();
protected:
	virtual void _DoExpand();
	virtual bool _CoolTipIsVisible();
	virtual void _CoolTipHide(
		bool bAdvOperation = true
		);

	e_combine_align_t m_eCombineAlign;
	CRgn m_rgnWnd;
	CRect m_rcClient;

	virtual CRect _CalcTrackRect();
	virtual CSize _CalcTrackSize();
	virtual bool _IsPopupWithShadows() const;
	virtual int _GetPopupShadowSize() const;

	enum next_item_t
	{
		__NI_NOTHING,
		__NI_ANY,
		__NI_NEXT,
		__NI_PREV,
		__NI_PAGE_UP,
		__NI_PAGE_DOWN
	};
	
	virtual int _GetNextItem(
		next_item_t nit
		);

public:
	
	/////////////////////////////////////////////////////////////////////////////
	// CExtPopupMenuWnd::CInPlaceEditWnd

	class CInPlaceEditWnd;

	typedef
		bool (*pCbInplaceEditWndProc)(
			LRESULT & lResult,
			UINT message,
			WPARAM wParam,
			LPARAM lParam,
			CInPlaceEditWnd & wndEdit,
			LPVOID pCoockie
			);
	typedef
		bool (*pCbVerifyTextInput)(
			CInPlaceEditWnd & wndEdit,
			LPVOID pCoockie,
			__EXT_MFC_SAFE_LPCTSTR sTextOld,
			__EXT_MFC_SAFE_LPCTSTR sTextNew
			);
	typedef
		void (*pCbPutTextInputResult)(
			CInPlaceEditWnd & wndEdit,
			LPVOID pCoockie,
			__EXT_MFC_SAFE_LPCTSTR sTextNew
			);

	class CInPlaceEditWnd : public CEdit
	{
		pCbVerifyTextInput m_pCbVerifyTextInput;
		pCbPutTextInputResult m_pCbPutTextInputResult;
		pCbInplaceEditWndProc m_pCbWndProc;
		LPVOID m_pCbCoockie;
		CExtSafeString * m_pStr;
		CExtSafeString m_sTextSaved;
		bool m_bNoCancelAtKillFocus:1;
	public:
		static UINT g_nMsgDeleteSelection, g_nMsgSelectAll;
		CInPlaceEditWnd(
			CExtSafeString * pStr,
			pCbVerifyTextInput pCbVerify = NULL,
			pCbPutTextInputResult pCbResult = NULL,
			pCbInplaceEditWndProc pCbWndProc = NULL,
			LPVOID pCbCoockie = NULL
			);
		~CInPlaceEditWnd();
#ifdef _DEBUG
		virtual void AssertValid() const;
#endif // _DEBUG
		virtual bool Create(
			CExtPopupMenuWnd * pPopup,
			CRect rc,
			UINT nDlgCtrlID
			);
		virtual LRESULT WindowProc(
			UINT message,
			WPARAM wParam,
			LPARAM lParam
			);
	protected:
		virtual void PostNcDestroy();
		CExtPopupMenuWnd * GetPopupMenu();
	}; // class CInPlaceEditWnd


	/////////////////////////////////////////////////////////////////////////////
	// CExtPopupMenuWnd::MENUITEMDATA
	
	class MENUITEMDATA;
	friend class MENUITEMDATA;
	class CExtPopupMenuCmdUI;

	struct __PROF_UIS_API INPLACEEDITCREATEINFO
	{
		CWnd ** m_ppInplaceEdit;
		CExtPopupMenuWnd * m_pPopup;
		MENUITEMDATA * m_pMenuItemData;
		CExtSafeString * m_pInplaceEditStr;
		pCbVerifyTextInput m_pCbVerifyTextInput;
		pCbPutTextInputResult m_pCbPutTextInputResult;
		pCbInplaceEditWndProc m_pInplaceEditCbWndProc;
		LPVOID m_pInplaceEditCbCoockie;
		CRect m_rc;
		INPLACEEDITCREATEINFO(
			CWnd ** ppInplaceEdit,
			CExtPopupMenuWnd * pPopup,
			MENUITEMDATA * pMenuItemData,
			CExtSafeString * pInplaceEditStr,
			pCbVerifyTextInput pCbVerify,
			pCbPutTextInputResult pCbResult,
			pCbInplaceEditWndProc pInplaceEditCbWndProc,
			LPVOID pInplaceEditCbCoockie,
			const RECT & rc
			)
			: m_ppInplaceEdit( ppInplaceEdit )
			, m_pPopup( pPopup )
			, m_pMenuItemData( pMenuItemData )
			, m_pInplaceEditStr( pInplaceEditStr )
			, m_pCbVerifyTextInput( pCbVerify )
			, m_pCbPutTextInputResult( pCbResult )
			, m_pInplaceEditCbWndProc( pInplaceEditCbWndProc )
			, m_pInplaceEditCbCoockie( pInplaceEditCbCoockie )
			, m_rc( rc )
		{
		}
	}; // struct INPLACEEDITCREATEINFO

	class __PROF_UIS_API MENUITEMDATA
	{
	public:
		typedef bool (*pCbItemClick)(
			CExtPopupMenuWnd * pPopup,
			MENUITEMDATA * pItemData
			);
	protected:
#if (!defined __EXT_MFC_NO_CUSTOMIZE)
		CExtCustomizeCmdTreeNode * m_pCmdNode;
#endif // (!defined __EXT_MFC_NO_CUSTOMIZE)
		CExtPopupMenuWnd * m_pWndChild;
		int m_nItemIndex;
		
		UINT m_nCmdID; // can be ID_SEPARATOR
		CExtSafeString m_sItemText, m_sAccelText;
		CExtCmdIcon m_iconPopup;

		CSize m_sizeItem;
		INT m_nIconAreaWidth;
		bool m_bSelected:1, m_bDisplayed:1, m_bForceDisplayed:1,
			m_bChildCombine:1, m_bToolButton:1, m_bForceEnabled:1,
			m_bForceNoLeftGradient:1,
			m_bCheck:1,m_bRadio:1,m_bEnabled:1,m_bIndeterminate:1,
			m_bXtraChecked:1,m_bNoCmdUI:1;
		pCbItemClick m_pCbCmdDeliver;
		pCbItemClick m_pCbXtraMarkState;
		__EXT_MFC_SAFE_TCHAR m_cAccelChar;

		HWND m_hWndSpecCmdReceiver;
		
		CWnd * m_pHelperInplaceEditWnd;
		CExtSafeString * m_pInplaceEditStr;
		pCbVerifyTextInput m_pCbVerifyTextInput;
		pCbPutTextInputResult m_pCbPutTextInputResult;
		pCbInplaceEditWndProc m_pInplaceEditCbWndProc;
		LPVOID m_pInplaceEditCbCoockie;
		int m_nInplaceEditWidth;
		bool m_bAllowInplaceEditActivation:1;

		bool m_bTempSelTextValid:1;
		CExtSafeString m_sTempSelText;

		LPARAM m_nLParam;

	public:
		MENUITEMDATA();
		MENUITEMDATA( const MENUITEMDATA & other );
		~MENUITEMDATA();
		MENUITEMDATA & operator=( const MENUITEMDATA & other );
	private:
		void AssignFromOther( const MENUITEMDATA & other );
	public:
		bool UpdateFromMenu(
			HWND hWndCmdRecv,
			CMenu * pTrackMenu,
			int nItemIndex
			);
#if (!defined __EXT_MFC_NO_CUSTOMIZE)
		bool UpdateFromCmdTree(
			HWND hWndCmdRecv,
			CExtCustomizeCmdTreeNode * pNode,
			int nItemIndex
			);
#endif // (!defined __EXT_MFC_NO_CUSTOMIZE)

	public:
		void AccelCharInit();
		__EXT_MFC_SAFE_TCHAR AccelCharGet() const;
		bool AccelCharIsSet() const;

	protected:
		bool UpdateCmdManagerCommand(
			CExtCmdItem * pCmdItem,
			int nItemIndex
			);

	public:
		void MeasureItem();

		CExtCmdItem * GetCmd() const;
#if (!defined __EXT_MFC_NO_CUSTOMIZE)
		CExtCustomizeCmdTreeNode * GetCmdNode();
		const CExtCustomizeCmdTreeNode * GetCmdNode() const
		{
			return
				( const_cast < MENUITEMDATA * > ( this ) )
					-> GetCmdNode();
		}
#endif // (!defined __EXT_MFC_NO_CUSTOMIZE)

		HWND GetCmdReceiver() const
		{
			ASSERT( m_hWndSpecCmdReceiver != NULL );
			ASSERT( ::IsWindow(m_hWndSpecCmdReceiver) );
			return m_hWndSpecCmdReceiver;
		}
		void SetCmdReceiver( HWND hWndSpecCmdReceiver )
		{
			ASSERT( hWndSpecCmdReceiver != NULL );
			ASSERT( ::IsWindow(hWndSpecCmdReceiver) );
			m_hWndSpecCmdReceiver = hWndSpecCmdReceiver;
		}

	protected:
		void SetDisplayed( bool bDisplayed )
		{
			m_bDisplayed = bDisplayed;
		}
		void SetForceDisplayed( bool bForceDisplayed )
		{
			m_bForceDisplayed = bForceDisplayed;
		}
	public:
		bool IsDisplayed() const
		{
			return m_bDisplayed || m_bForceDisplayed;
		}
		bool IsForceDisplayed()
		{
			return m_bForceDisplayed;
		}
		bool IsAllItemsRarelyUsed() const
		{
			ASSERT( IsPopup() );
			ASSERT( m_pWndChild != NULL );
			if( IsNoCmdUI() )
				return false;
			return m_pWndChild->IsAllItemsRarelyUsed();
		}

		bool IsEnabled() const
		{
			//if( IsPopup() && (! IsInplaceEdit()) )
			if( IsPopup() && GetCmd() == NULL )
				return true;
			if( IsSeparator() )
				return false;
			if( IsForceEnabled() )
				return true;
			return m_bEnabled;
		}
		bool Enable( bool bOn )
		{
//			if( IsPopup() )
//				return true;
			if( IsSeparator() )
				return false;
			bool bRetVal = m_bEnabled;
			m_bEnabled = bOn;
			return bRetVal;
		}
		bool IsIndeterminated() const
		{
			if( IsPopup() || IsSeparator() )
				return false;
			return m_bIndeterminate;
		}
		bool Indeterminate( bool bOn )
		{
			bool bRetVal = m_bIndeterminate;
			m_bIndeterminate = bOn;
			return bRetVal;
		}

		bool IsSelected() const
		{
			if( /*IsPopup() ||*/ IsSeparator() )
				return false;
			return m_bSelected;
		}
	protected:
		void SetSelected( bool bOn = true )
		{
			m_bSelected = bOn;
		}
	public:
		bool GetRadio() const
		{
			if( IsPopup() || IsSeparator() )
				return false;
			return m_bRadio;
		}
		bool Radio( bool bOn )
		{
			bool bRetVal = m_bRadio;
			m_bRadio = bOn;
			return bRetVal;
		}

		bool GetCheck() const
		{
			if( IsPopup() || IsSeparator() )
				return false;
			return m_bCheck;
		}
		bool Check( bool bOn )
		{
			bool bRetVal = m_bCheck;
			m_bCheck = bOn;
			return bRetVal;
		}

		pCbItemClick GetCmdDeliverCb() const
		{
			if( IsSeparator() )
				return NULL;
			return (pCbItemClick)m_pCbCmdDeliver;
		}
		void SetCmdDeliverCb( pCbItemClick pCb )
		{
			if( IsSeparator() )
				return;
			m_pCbCmdDeliver = pCb;
		}

		bool IsExtraMark() const
		{
			if( IsSeparator() )
				return false;
			return (m_pCbXtraMarkState != NULL) ? true : false;
		}
		pCbItemClick GetExtraMarkCallback() const
		{
			return (pCbItemClick)m_pCbXtraMarkState;
		}
		void SetExtraMark( pCbItemClick pCb )
		{
			if( IsSeparator() )
				return;
			m_pCbXtraMarkState = pCb;
		}
		bool IsExtraChecked() const
		{
			if( !IsExtraMark() )
				return false;
			return m_bXtraChecked;
		}
		void SetExtraChecked( bool bOn )
		{
			if( !IsExtraMark() )
				return;
			m_bXtraChecked = bOn;
		}
		
		bool IsNoCmdUI() const
		{
			return m_bNoCmdUI;
		}
		void SetNoCmdUI( bool bOn )
		{
			m_bNoCmdUI = bOn;
		}

		LPARAM LParamGet() const
		{
			return m_nLParam;
		}
		void LParamSet( LPARAM nLParam )
		{
			m_nLParam = nLParam;
		}

		__EXT_MFC_SAFE_LPCTSTR GetText() const;
		void SetText( __EXT_MFC_SAFE_LPCTSTR strText );
		__EXT_MFC_SAFE_LPCTSTR GetAccelText() const;
		void SetAccelText( __EXT_MFC_SAFE_LPCTSTR strText );
		
		CExtCmdIcon * GetIconPtr();

		void GetTip( CExtSafeString & sTip ) const;

		bool IsSeparator() const
		{
			bool bSeparator =
				(m_nCmdID==TYPE_SEPARATOR) ? true : false;
			return bSeparator;
		}

		bool IsChildCombine() const
		{
			return m_bChildCombine;
		}
		void SetChildCombine( bool bChildCombine = true )
		{
			m_bChildCombine = bChildCombine;
		}

		bool IsToolButton() const
		{
			return m_bToolButton;
		}
		void SetToolButton( bool bToolButton = true )
		{
			if(		(m_bToolButton && bToolButton)
				||	((!m_bToolButton) && (!bToolButton))
				)
				return;
			m_bToolButton = bToolButton;
			MeasureItem();
		}
		
		bool IsForceEnabled() const
		{
			return m_bForceEnabled;
		}
		void SetForceEnabled( bool bForceEnabled = true )
		{
			if(		(m_bForceEnabled && bForceEnabled)
				||	((!m_bForceEnabled) && (!bForceEnabled))
				)
				return;
			m_bForceEnabled = bForceEnabled;
		}

		bool IsForceNoLeftGradient() const
		{
			return m_bForceNoLeftGradient;
		}
		void SetForceNoLeftGradient( bool bForceNoLeftGradient = true )
		{
			if(		(m_bForceNoLeftGradient && bForceNoLeftGradient)
				||	((!m_bForceNoLeftGradient) && (!bForceNoLeftGradient))
				)
				return;
			m_bForceNoLeftGradient = bForceNoLeftGradient;
			MeasureItem();
		}

		bool IsInplaceEdit() const
		{
			return (m_pInplaceEditStr != NULL) ? true : false;
		}
		void SetInplaceEdit(
			CExtSafeString * pInplaceEditStr,
			pCbVerifyTextInput pCbVerify = NULL,
			pCbPutTextInputResult pCbResult = NULL,
			pCbInplaceEditWndProc pInplaceEditCbWndProc = NULL,
			LPVOID pInplaceEditCbCoockie = NULL,
			int nInplaceEditWidth = __EXT_MENU_DEF_INPLACE_EDIT_WIDTH
			)
		{
			ASSERT( pInplaceEditStr != NULL );
			ASSERT( nInplaceEditWidth > 0 );
			m_pInplaceEditStr = pInplaceEditStr;
			m_pCbVerifyTextInput = pCbVerify;
			m_pCbPutTextInputResult = pCbResult;
			m_pInplaceEditCbWndProc = pInplaceEditCbWndProc;
			m_pInplaceEditCbCoockie = pInplaceEditCbCoockie;
			m_nInplaceEditWidth = nInplaceEditWidth;
			MeasureItem();
		}
		void ResetActiveInplaceEditPtr()
		{
			m_pHelperInplaceEditWnd = NULL;
		}
		CWnd * GetInplaceEditPtr()
		{
			if( !IsInplaceEdit() )
				return NULL;
			return m_pHelperInplaceEditWnd;
		}
		int GetInplaceEditWidth() const
		{
			if( !IsInplaceEdit() )
				return 0;
			ASSERT( m_nInplaceEditWidth > 0 );
			return m_nInplaceEditWidth;
		}
		bool IsAllowInplaceEditActivation() const
		{
			if( !IsInplaceEdit() )
				return false;
			return m_bAllowInplaceEditActivation;
		}
		void AllowInplaceEditActivation(
			bool bAllowInplaceEditActivation
			)
		{
			m_bAllowInplaceEditActivation = bAllowInplaceEditActivation;
		}
		CExtSafeString GetInplaceEditText() const
		{
			CExtSafeString s( _T("") );
			if(		IsInplaceEdit()
				&&	m_pInplaceEditStr != NULL
				)
			{
				if( m_bTempSelTextValid )
					s = m_sTempSelText;
				else
					s = *m_pInplaceEditStr;
			}
			return s;
		}
		void SetTempSelectedInplaceEditText(
			__EXT_MFC_SAFE_LPCTSTR sTempSelText = NULL // NULL - reset
			)
		{
			m_bTempSelTextValid = false;
			m_sTempSelText.Empty();
			if(		(!IsInplaceEdit())
				||	sTempSelText == NULL
				)
				return;
			m_bTempSelTextValid = true;
			m_sTempSelText = sTempSelText;
		}
		bool CreateInplaceEdit(
			CExtPopupMenuWnd * pPopup,
			CRect rc
			)
		{
			if( m_pInplaceEditStr == NULL )
			{
				ASSERT( FALSE );
				return false;
			}
			m_pHelperInplaceEditWnd = NULL;
			HWND hWndCmdReceiver = GetCmdReceiver();
			if(		hWndCmdReceiver != NULL
				&&	::IsWindow( hWndCmdReceiver )
				)
			{
				CExtPopupMenuWnd::INPLACEEDITCREATEINFO _ieci(
					&m_pHelperInplaceEditWnd,
					pPopup,
					this,
					m_pInplaceEditStr,
					m_pCbVerifyTextInput,
					m_pCbPutTextInputResult,
					m_pInplaceEditCbWndProc,
					m_pInplaceEditCbCoockie,
					rc
					);
				::SendMessage(
					hWndCmdReceiver,
					CExtPopupBaseWnd::g_nMsgCreateInplaceEdit,
					(WPARAM)(&_ieci),
					(LPARAM)0L
					);
			}
			
			if( m_pHelperInplaceEditWnd == NULL )
			{
				m_pHelperInplaceEditWnd =
					new CInPlaceEditWnd(
						m_pInplaceEditStr,
						m_pCbVerifyTextInput,
						m_pCbPutTextInputResult,
						m_pInplaceEditCbWndProc,
						m_pInplaceEditCbCoockie
						);
				if( !((CInPlaceEditWnd*)m_pHelperInplaceEditWnd)->
						Create( pPopup, rc, GetCmdID() ) )
				{
					ASSERT( FALSE );
					delete m_pHelperInplaceEditWnd;
					m_pHelperInplaceEditWnd = NULL;
					return false;
				}
			} // if( m_pHelperInplaceEditWnd == NULL )
#ifdef _DEBUG
			else
			{
				ASSERT(
						m_pHelperInplaceEditWnd->GetSafeHwnd() != NULL
						&&	::IsWindow( m_pHelperInplaceEditWnd->GetSafeHwnd() )
					);
			} // else from if( m_pHelperInplaceEditWnd == NULL )
#endif // _DEBUG

			return true;
		}

		CRect AdjustInplaceEditRect( const RECT & rcItem ) const;
		
	protected:
		void SetSeparator(
			int nItemIndex
			)
		{
			if( !IsSeparator() )
			{
				if( m_pWndChild != NULL )
					DestroyPopup();
				ASSERT( m_pWndChild == NULL );
				m_sItemText.Empty();
				m_nCmdID = TYPE_SEPARATOR;
				m_nItemIndex = nItemIndex;
			}
			MeasureItem();
		}

		void SetPopup(
			int nItemIndex,
			__EXT_MFC_SAFE_LPCTSTR sText = NULL,
			HICON hIcon = NULL,
			CExtPopupMenuWnd * pSpecPopup = NULL
			)
		{
			ASSERT( m_hWndSpecCmdReceiver != NULL );
			ASSERT( ::IsWindow(m_hWndSpecCmdReceiver) );

			if( m_pWndChild == NULL )
			{
				if( pSpecPopup == NULL )
				{
					ConstructPopup();
				} // if( pSpecPopup == NULL )
				else
				{
					m_pWndChild = pSpecPopup;
					ASSERT( m_pWndChild != NULL );
					m_pWndChild->m_hWndCmdReceiver = m_hWndSpecCmdReceiver;
				} // else from if( pSpecPopup == NULL )
			}
			
			m_nCmdID = (UINT)TYPE_POPUP;
			m_sItemText = _T("");
			m_sAccelText = _T("");
			m_nItemIndex = nItemIndex;
			ASSERT( m_iconPopup.IsEmpty() );
			VERIFY( SetPopupIcon(hIcon) );
			VERIFY( SetPopupText(sText) );
			MeasureItem();
		}
		bool SetPopupIcon( HICON hIcon, bool bCopyIcon = true )
		{
			if( ! ( IsPopup() || IsNoCmdUI() ) )
			{
				ASSERT( FALSE );
				return false;
			}
			if( hIcon == NULL )
			{
				m_iconPopup.Empty();
				return true;
			}
			m_iconPopup.AssignFromHICON( hIcon, bCopyIcon );
			return true;
		}
		bool SetPopupIcon( const CExtCmdIcon & icon )
		{
			if( ! ( IsPopup() || IsNoCmdUI() ) )
			{
				ASSERT( FALSE );
				return false;
			}
			if( icon.IsEmpty() )
			{
				m_iconPopup.Empty();
				return true;
			}
			m_iconPopup = icon;
			return true;
		}
		CExtCmdIcon & GetPopupIcon()
		{
			return m_iconPopup;
		}
		const CExtCmdIcon & GetPopupIcon() const
		{
			return m_iconPopup;
		}
		bool SetPopupText( __EXT_MFC_SAFE_LPCTSTR strText );
		bool SetPopupAccelText( __EXT_MFC_SAFE_LPCTSTR strText ); // NULL if empty
		bool ConstructPopup();
		void DestroyPopup();
	public:
		CExtPopupMenuWnd * GetPopup()
		{
			ASSERT( m_pWndChild != NULL );
			return m_pWndChild;
		}
		const CExtPopupMenuWnd * GetPopup() const
		{
			ASSERT( m_pWndChild != NULL );
			return m_pWndChild;
		}
		bool IsPopup() const
		{
			return ( m_nCmdID == TYPE_POPUP ) ? true : false;
		}

		UINT GetCmdID() const;
		UINT SetCmdID( UINT nCmdID );

		bool IsExecutableCmdID() const;

		int GetMeasuredHeight() const
		{
			return m_sizeItem.cy;
		}
		int GetMeasuredWidth() const
		{
			return m_sizeItem.cx;
		}
		int GetIconAreaWidth() const
		{
			return m_nIconAreaWidth;
		}
		void UpdateIconAreaWidth(
			INT nIconAreaWidthLager
			)
		{
			if( IsToolButton() )
				return;
			if( nIconAreaWidthLager <= m_nIconAreaWidth )
				return;
			if( !IsSeparator() )
				m_sizeItem.cx +=
					nIconAreaWidthLager - m_nIconAreaWidth;
			m_nIconAreaWidth = nIconAreaWidthLager;
		}

		CRect GetBaseRect() const
		{
			CRect rcItem(
				CPoint(0,0),
				m_sizeItem
				);
			return rcItem;
		}
		
		int GetIndex() const
		{
			return m_nItemIndex;
		}
	protected:
		void SetIndex( int nItemIndex )
		{
			m_nItemIndex = nItemIndex;
		}

		friend class CExtPopupMenuWnd;
		friend class CExtPopupMenuCmdUI;

#if (!defined __EXT_MFC_NO_CUSTOMIZE)
	#if (!defined __EXT_MFC_NO_BUILTIN_TEXTFIELD)
		static bool stat_CbVerifyTextInput(
			CInPlaceEditWnd & wndEdit,
			CExtCustomizeCmdTreeNode * pNode,
			__EXT_MFC_SAFE_LPCTSTR sTextOld,
			__EXT_MFC_SAFE_LPCTSTR sTextNew
			);
		static void stat_CbPutTextInputResult(
			CInPlaceEditWnd & wndEdit,
			CExtCustomizeCmdTreeNode * pNode,
			__EXT_MFC_SAFE_LPCTSTR sTextNew
			);
		static bool stat_CbInplaceEditWndProc(
			LRESULT & lResult,
			UINT message,
			WPARAM wParam,
			LPARAM lParam,
			CEdit & wndEdit,
			CExtCustomizeCmdTreeNode * pNode
			);
		static bool stat_CbInitListBoxContent(
			CExtPopupInplaceListBox & wndListBox,
			CExtCustomizeCmdTreeNode * pNode
			);
		static bool stat_CbListBoxSelection(
			CExtPopupInplaceListBox & wndListBox,
			CExtCustomizeCmdTreeNode * pNode,
			int eSAT // CExtPopupInplaceListBox::e_sel_action_t
			);
		static bool stat_CbListBoxItemDraw(
			CExtPopupInplaceListBox & wndListBox,
			CExtCustomizeCmdTreeNode * pNode,
			LPDRAWITEMSTRUCT pDIS
			);
		static bool stat_CbListBoxItemMeasure(
			CExtPopupInplaceListBox & wndListBox,
			CExtCustomizeCmdTreeNode * pNode,
			LPMEASUREITEMSTRUCT pMIS
			);
	#endif // (!defined __EXT_MFC_NO_BUILTIN_TEXTFIELD)
#endif // (!defined __EXT_MFC_NO_CUSTOMIZE)
	}; // class MENUITEMDATA
	
	CExtPopupMenuWnd::MENUITEMDATA & ItemGetInfo( INT nPos );
	const CExtPopupMenuWnd::MENUITEMDATA & ItemGetInfo( INT nPos ) const;

	/////////////////////////////////////////////////////////////////////////////
	// CExtPopupMenuWnd::DRAWITEMDATA
	
	struct DRAWITEMDATA;
	friend struct DRAWITEMDATA;
	
	struct __PROF_UIS_API DRAWITEMDATA
	{
		CDC * m_pDC;
		LPCRECT m_pRectItem;
		const MENUITEMDATA * m_pItemData;
		CExtPopupMenuWnd * m_pPopup;
		const bool m_bMenuOwnerDrawFixed:1;
		const bool m_bPopupItem:1;
		const bool m_bRarelyUsed:1;
		const bool m_bRarelyUsedPrevious:1;
		const bool m_bRarelyUsedNext:1;
	protected:
		DRAWITEMDATA(
			CDC * pDC,
			LPCRECT pRectItem,
			const MENUITEMDATA * pItemData,
			CExtPopupMenuWnd * pPopup,
			bool bMenuOwnerDrawFixed,
			bool bPopupItem,
			bool bRarelyUsed,
			bool bRarelyUsedPrevious,
			bool bRarelyUsedNext
			)
			: m_pDC( pDC )
			, m_pRectItem( pRectItem )
			, m_pItemData( pItemData )
			, m_pPopup( pPopup )
			, m_bMenuOwnerDrawFixed( bMenuOwnerDrawFixed )
			, m_bPopupItem( bPopupItem )
			, m_bRarelyUsed( bRarelyUsed )
			, m_bRarelyUsedPrevious( bRarelyUsedPrevious )
			, m_bRarelyUsedNext( bRarelyUsedNext )
		{
			ASSERT( m_pDC != NULL );
			ASSERT( m_pDC->GetSafeHdc() != NULL );
			ASSERT( m_pRectItem != NULL );
			ASSERT( m_pItemData != NULL );
			ASSERT( m_pPopup != NULL );
		}
	public:
		operator CDC *()
		{
			ASSERT( this != NULL );
			ASSERT( m_pDC != NULL );
			ASSERT( m_pDC->GetSafeHdc() != NULL );
			return m_pDC;
		}
		operator LPCRECT()
		{
			ASSERT( this != NULL );
			ASSERT( m_pRectItem != NULL );
			return m_pRectItem;
		}
		operator const MENUITEMDATA *()
		{
			ASSERT( this != NULL );
			ASSERT( m_pItemData != NULL );
			return m_pItemData;
		}
		operator __EXT_MFC_SAFE_LPCTSTR()
		{
			ASSERT( this != NULL );
			ASSERT( m_pItemData != NULL );
			return m_pItemData->GetText();
		}
		operator CSize()
		{
			ASSERT( this != NULL );
			ASSERT( m_pRectItem != NULL );
			return
				CSize(
					m_pRectItem->right - m_pRectItem->left,
					m_pRectItem->bottom - m_pRectItem->top
					);
		}
		operator CExtPopupMenuWnd *()
		{
			ASSERT( this != NULL );
			ASSERT( m_pPopup != NULL );
			return m_pPopup;
		}
		CExtPopupMenuWnd * operator ->()
		{
			ASSERT( this != NULL );
			ASSERT( m_pPopup != NULL );
			return m_pPopup;
		}
		operator LPARAM()
		{
			return reinterpret_cast < LPARAM > ( this );
		}
		UINT GetCmdID()
		{
			ASSERT( this != NULL );
			ASSERT( m_pItemData != NULL );
			return m_pItemData->GetCmdID();
		}
		void PaintDefault(
			bool bForceNoIcon = false,
			bool bForceNoText = false,
			bool bForceNoCheck = false,
			bool bForceEnabled = false,
			bool bForceUnselected = false
			);
		void PaintDefaultBk()
		{
			PaintDefault(
				true,
				true,
				true,
				true,
				false
				);
		}
	protected:
		bool DoOwnerDrawPainting();
		friend class CExtPopupMenuWnd;
	}; // struct DRAWITEMDATA

	/////////////////////////////////////////////////////////////////////////////
	// CExtPopupMenuWnd::DRAWLEFTAREADATA
	
	struct DRAWLEFTAREADATA;
	friend struct DRAWLEFTAREADATA;
	
	struct __PROF_UIS_API DRAWLEFTAREADATA
	{
		CDC * m_pDC;
		LPCRECT m_pRectLeftArea;
		CExtPopupMenuWnd * m_pPopup;
	protected:
		DRAWLEFTAREADATA(
			CDC * pDC,
			LPCRECT pRectLeftArea,
			CExtPopupMenuWnd * pPopup
			)
			: m_pDC( pDC )
			, m_pRectLeftArea( pRectLeftArea )
			, m_pPopup( pPopup )
		{
			ASSERT( m_pDC != NULL );
			ASSERT( m_pDC->GetSafeHdc() != NULL );
			ASSERT( m_pRectLeftArea != NULL );
			ASSERT( m_pPopup != NULL );
		}
	public:
		operator CDC *()
		{
			ASSERT( this != NULL );
			ASSERT( m_pDC != NULL );
			ASSERT( m_pDC->GetSafeHdc() != NULL );
			return m_pDC;
		}
		operator LPCRECT()
		{
			ASSERT( this != NULL );
			ASSERT( m_pRectLeftArea != NULL );
			return m_pRectLeftArea;
		}
		operator CSize()
		{
			ASSERT( this != NULL );
			ASSERT( m_pRectLeftArea != NULL );
			return
				CSize(
					m_pRectLeftArea->right - m_pRectLeftArea->left,
					m_pRectLeftArea->bottom - m_pRectLeftArea->top
					);
		}
		operator CExtPopupMenuWnd *()
		{
			ASSERT( this != NULL );
			ASSERT( m_pPopup != NULL );
			return m_pPopup;
		}
		CExtPopupMenuWnd * operator ->()
		{
			ASSERT( this != NULL );
			ASSERT( m_pPopup != NULL );
			return m_pPopup;
		}
		operator LPARAM()
		{
			return reinterpret_cast < LPARAM > ( this );
		}
	protected:
		bool DoOwnerDrawPainting();
		friend class CExtPopupMenuWnd;
		friend class CExtPopupColorMenuWnd;
	}; // struct DRAWLEFTAREADATA

protected:
	void _EndSequenceEx(
		MENUITEMDATA & mi
		);
	virtual void _EndSequence(
		UINT nCmdID = 0,
		HWND hWndDeliver = NULL
		);

	typedef
		CArray < MENUITEMDATA, MENUITEMDATA & >
		items_container_t;
	typedef
		const items_container_t
		const_items_container_t;
	items_container_t m_items_all;
//	items_container_t & _GetItemsContaner();
//	const_items_container_t & _GetItemsContaner() const;
	MENUITEMDATA & _GetItemRef(int nIndex);
	const MENUITEMDATA & _GetItemRef(int nIndex) const;
	virtual void _InsertItem(
		int nInsertBefore,
		MENUITEMDATA & mi
		);

public:

	static bool TestHoverEnabledFromActiveHWND(
		HWND hWndTestFrom,
		HWND hWndActive = ::GetActiveWindow(),
		bool bCheckEnabled = true,
		bool bCheckVisible = true,
		bool bCheckExtPopupMenuTracking = true
		);

// Overrides
	// ClassWizard generated virtual function overrides
	//{{AFX_VIRTUAL(CExtPopupMenuWnd)
	//}}AFX_VIRTUAL

// Implementation
public:
	virtual ~CExtPopupMenuWnd();
	virtual CExtPopupMenuSite & GetSite() const;

protected:
	virtual void _StartAnimation();
	virtual void _EndAnimation()
	{
		ASSERT_VALID( this );

		CExtPopupBaseWnd::_EndAnimation();
		Invalidate( FALSE );
		_SetCapture();
	}
	

public:
	virtual bool _FindHelpMode() const;

	virtual BOOL DestroyWindow();

protected:
	virtual void PostNcDestroy();

	// Generated message map functions
	//{{AFX_MSG(CExtPopupMenuWnd)
	afx_msg void OnCancelMode();
	afx_msg void OnTimer(UINT nIDEvent);
	afx_msg void OnShowWindow(BOOL bShow, UINT nStatus);
	afx_msg BOOL OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message);
	//}}AFX_MSG
#if _MFC_VER < 0x700
	afx_msg void OnActivateApp(BOOL bActive, HTASK hTask);
#else
	afx_msg void OnActivateApp(BOOL bActive, DWORD hTask);
#endif
	DECLARE_MESSAGE_MAP()

	afx_msg void OnMouseMove(UINT nFlags, CPoint point);
	afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
	afx_msg void OnRButtonDown(UINT nFlags, CPoint point);

	friend class CExtPopupMenuCmdUI;
}; // class CExtPopupMenuWnd

class __PROF_UIS_API CExtPopupColorMenuWnd :
	public CExtPopupMenuWnd
{
public:
	DECLARE_DYNCREATE(CExtPopupColorMenuWnd)

	CExtPopupColorMenuWnd();

// Attributes
public:
	static UINT g_nMsgNotifyColorChanged;
	static UINT g_nMsgNotifyColorChangedFinally;
	static UINT g_nMsgNotifyCustColor;

	HWND m_hWndNotifyColorChanged; // def is NULL - use command targed
	LPARAM m_lParamCookie;
	COLORREF * m_pClrValueFinal;
	enum e_color_selection_t
	{
		__ECST_NONE = COLORREF( -1L ),
		__ECST_BUTTON_CUSTOM = COLORREF( -2L ),
	};

	COLORREF m_clrDefault,m_clrInitial;
	bool m_bEnableBtnColorDefault:1;
	bool m_bEnableBtnColorCustom:1;

	CExtSafeString m_sBtnTextColorDefault;
	CExtSafeString m_sBtnTextColorCustom;

protected:
	CRect m_rcDefColorText,m_rcCustColorText;

	enum
	{
		IDX_DEFAULT_COLOR_BTN = -4,
		IDX_CUSTOM_COLOR_BTN = -5
	};

// Implementation
protected:
	int m_nColorIdxCurr, m_nInitialColorIdx;

	HWND _GetWndNotifyColorChanged();

	int _FindCellByColorRef(COLORREF clr);

	virtual bool _CreateHelper(
		CWnd * pWndCmdReceiver
		);
	virtual bool IsAllItemsRarelyUsed() const;

public:
	struct __PROF_UIS_API COLORREF_TABLE_ENTRY
	{
#if (defined _AFXDLL && !defined __STATPROFUIS_WITH_DLLMFC__)
		const UINT m_nStrTblResID;
		mutable CExtSafeString m_sColorNameLocal;
#endif // if (defined _AFXDLL && !defined __STATPROFUIS_WITH_DLLMFC__)
		const COLORREF m_clrValue;
		__EXT_MFC_SAFE_LPCTSTR m_sColorNameEnglish;
		COLORREF_TABLE_ENTRY(
			UINT nStrTblResID,
			COLORREF clrValue,
			__EXT_MFC_SAFE_LPCTSTR sColorNameEnglish
			);
		__EXT_MFC_SAFE_LPCTSTR GetLocalColorName() const;
	}; // struct COLORREF_TABLE_ENTRY

	static const COLORREF_TABLE_ENTRY g_colors[40];

	virtual int _HitTest(
		const CPoint & point,
		bool * p_bInplaceControlArea = NULL,
		bool * p_bInplaceDropDownArea = NULL
		)
	{
		ASSERT_VALID( this );
		if( p_bInplaceControlArea != NULL )
			*p_bInplaceControlArea = false;
		if( p_bInplaceDropDownArea != NULL )
			*p_bInplaceDropDownArea = false;
		point;
		return IDX_NOTHING;
	}
protected:

	void _NotifyColorChanged(
		bool bFinal = false
		);

	CPoint _GetColorItemCoord(int nIdx);
	CRect _GetColorItemRect(int nIdx);
	int _ColorItemHitTest(const CPoint & point);

	virtual CRect _CalcTrackRect();
	virtual CSize _CalcTrackSize();
public:
	virtual void _DoPaint( CDC & dcPaint, bool bUseBackBuffer = true );
protected:

#if (!defined __EXT_MFC_NO_CUSTOMIZE)
	// CExtCustomizeSite::ICustomizeDropTarget
	virtual DROPEFFECT OnCustomizeTargetOver(
		CExtCustomizeSite::CCmdDragInfo & _dragInfo,
		CPoint point,
		DWORD dwKeyState
		);
	virtual void OnCustomizeTargetLeave();
	virtual bool OnCustomizeTargetDrop(
		CExtCustomizeSite::CCmdDragInfo & _dragInfo,
		CPoint point,
		DROPEFFECT de
		);
	// CExtCustomizeSite::ICustomizeDropSource
	virtual void OnCustomizeSourceDragComplete(
		DROPEFFECT de,
		bool bCanceled,
		bool * p_bNoResetActiveItem
		);
#endif // (!defined __EXT_MFC_NO_CUSTOMIZE)

public:
	virtual bool _OnMouseWheel(
		WPARAM wParam,
		LPARAM lParam,
		bool & bNoEat
		);
	virtual bool _OnMouseMove(
		UINT nFlags,
		CPoint point,
		bool & bNoEat
		);
	virtual bool _OnMouseClick(
		UINT nFlags,
		CPoint point,
		bool & bNoEat
		);
	virtual bool _OnKeyDown(
		UINT nChar,
		UINT nRepCnt,
		UINT nFlags,
		bool & bNoEat
		);

	virtual bool _CanStartLevelTracking();

protected:
	// Generated message map functions
	//{{AFX_MSG(CExtPopupColorMenuWnd)
	//}}AFX_MSG
    afx_msg BOOL OnQueryNewPalette();
    afx_msg void OnPaletteChanged(CWnd* pFocusWnd);
	DECLARE_MESSAGE_MAP()
}; // class CExtPopupColorMenuWnd

/////////////////////////////////////////////////////////////////////////////

//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

#endif // __EXT_POPUP_MENU_WND_H
