// This is part of the Professional User Interface Suite library.
// Copyright (C) 2001-2002 FOSS Software, Inc.
// All rights reserved.
//
// http://www.fossware.com
// mailto:foss@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 __ExtCmdManager_H)
#include <ExtCmdManager.h>
#endif
#define __BaseClassOfCExtPopupBaseWnd CWnd
/////////////////////////////////////////////////////////////////////////////
// CExtSoundPlayer
class __PROF_UIS_API CExtSoundPlayer : public CObject
{
struct __PROF_UIS_API InternalSoundEventInitDone_t : public CEvent
{
InternalSoundEventInitDone_t()
: CEvent( FALSE, TRUE )
{
}
void SetInitDone()
{
SetEvent();
}
void WaitInitDone()
{
HANDLE hEvent = *this;
ASSERT( hEvent != NULL );
::WaitForSingleObject( hEvent, INFINITE );
}
};
struct __PROF_UIS_API InternalSoundThredadParms_t
{
InternalSoundEventInitDone_t * m_pEventInitDone;
CString m_sSoundSpecBuffer;
HANDLE m_hModule;
DWORD m_dwPlayerFlags;
HANDLE m_hThread;
DWORD m_dwThreadID;
static CEvent g_EventPlaySnd;
static CCriticalSection g_CsPlaySnd;
InternalSoundThredadParms_t(
LPCTSTR sSoundSpecBuffer,
HANDLE hModule = NULL,
DWORD dwPlayerFlags = SND_ALIAS|SND_NODEFAULT|SND_NOWAIT|SND_SYNC
)
: m_sSoundSpecBuffer( sSoundSpecBuffer )
, m_hModule( hModule )
, m_dwPlayerFlags( dwPlayerFlags )
, m_hThread( NULL )
, m_dwThreadID( 0 )
, m_pEventInitDone( NULL )
{
}
static DWORD 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_DYNAMIC( 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; // use photo bitmaps
void _FreeWinObjects();
void _DoPixelOvershadow(
int nMakeSpec,
int nPosX,
int nPosY
);
bool _MakePhotos( CDC & dc, CDC & dcmm );
bool _PaintLo( CDC & dc );
bool _PaintHi( CDC & dc );
public:
enum eShadowOptions
{
DEF_BRIGHTNESS_MIN = 70UL, // default min brightness percent
DEF_BRIGHTNESS_MAX = 100UL, // default max brightness percent
DEF_SHADOW_SIZE = 4UL, // default shadow size (in pixels)
};
CExtWndShadow();
~CExtWndShadow();
bool Restore( CDC & dc );
bool Paint( CDC & dc );
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
);
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 window popup messgae
static UINT g_nMsgPopupNext;
static UINT g_nMsgPopupPrev;
static UINT g_nMsgNotifyMenuExpanded;
static UINT g_nMsgNotifyMenuClosed;
static UINT g_nMsgPopupDrawItem;
static UINT g_nMsgPopupDrawLeftArea;
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 bool g_bUseDesktopWorkArea; // align to desktop work area (false - to screen area)
virtual CRect _CalcDesktopRect();
static bool g_bEnableOnIdleCalls;
protected:
CRect m_rcExcludeArea;
CPoint m_ptTrack;
bool m_bExcludeAreaSpec:1,m_bCombineWithEA:1;
LPVOID m_pCbPaintCombinedCookie;
pCbPaintCombinedContent m_pCbPaintCombinedContent;
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;
// void _BitsSave( CDC &dc );
// void _BitsRestore();
virtual void _InitAnimation();
virtual void _StartAnimation();
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 void _DrawAnimatedState( CDC & dc );
virtual void _DoPaint( CDC & dcPaint, bool bUseBackBuffer = true );
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 );
}
// 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;
CString 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(LPCTSTR lpszText);
bool Show(
CWnd * pWndParent,
const RECT & rcExcludeArea
);
void Hide();
protected:
bool GetWindowRegion(
CDC* pDC,
HRGN* hRegion,
CSize *Size = NULL
);
void _DoPaint( CDC & dcPaint, bool bUseBackBuffer = true );
// Generated message map functions
//{{AFX_MSG(CExtPopupMenuTipWnd)
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
}; // class CExtPopupMenuTipWnd
/////////////////////////////////////////////////////////////////////////////
// CExtPopupMenuSite
class CExtPopupMenuWnd;
class CExtPopupColorMenuWnd;
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 IsTopPupup(
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
class __PROF_UIS_API CExtPopupMenuWnd :
public CExtPopupBaseWnd
{
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;
protected:
CExtPopupMenuTipWnd m_wndToolTip;
int m_nCurIndex,m_nDelayedFocusItemIndex;
bool
m_bTopLevel:1,
m_bScrollingAvailable:1,
m_bExpandAvailable:1,
m_bExpandWasPressed:1
;
UINT m_nWaitingExpandTickCount;
DWORD m_dwTrackFlags;
HWND m_hWndCmdReciever;
//CPoint m_ptTrack;
int m_nDyScrollOffset;
CExtPopupMenuWnd * m_pWndParentMenu;
CRect
m_rcScrollTop,
m_rcScrollBottom,
m_rcExpandBtn;
int m_nScrollingDirection;
UINT m_nLeftAreaWidth;
public:
HWND GetCmdRecieverHWND()
{
ASSERT( m_hWndCmdReciever != NULL );
ASSERT( ::IsWindow( m_hWndCmdReciever ) );
return m_hWndCmdReciever;
}
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
);
virtual BOOL UpdateMdiWindowsMenu(
CWnd * pWndStartSearchMdiFrameWnd = NULL
);
virtual void SetCmdTargetToAllItems(
HWND hWndSpecCmdReciever = 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 CString ItemGetText( INT nPos ) const;
virtual CString 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,
LPCTSTR sText // NULL if empty
);
virtual bool ItemSetPopupAccelText(
INT nPos,
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
LPCTSTR sText = NULL, // for TYPE_POPUP only
HICON hIcon = NULL, // for TYPE_POPUP only
HWND hWndSpecCmdReciever = NULL // specific command reciever
);
virtual BOOL ItemInsertSpecPopup( // insert specific popup implementation
CExtPopupMenuWnd * pSpecPopup,
INT nPos = -1, // append
LPCTSTR sText = NULL,
HICON hIcon = NULL
);
virtual INT ItemFindByAccessChar(
TCHAR chrAccess,
INT nStartIdx = -1,
BOOL bRestartAt0 = TRUE
) const;
virtual INT ItemFindByText(
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
);
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_bMenuWithShadows; // allow shadows
static bool g_bMenuExpanding; // allow hide rarely used
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
protected:
virtual bool _CreateHelper(
CWnd * pWndCmdReciever
);
bool _BuildItems(
CMenu * pBuildMenu,
bool bTopLevel
);
void _UpdateCmdUI();
void _Init();
void _RecalcLayoutImpl();
static int _GetSpecBtnHeight();
virtual int _HitTest(const CPoint & point );
virtual void _DrawAnimatedState( CDC & dc );
virtual void _DoPaint( CDC & dcPaint, bool bUseBackBuffer = true );
virtual void _GetClientRect(RECT * pRectClient);
void _EndSequence(
UINT nCmdID = 0,
HWND hWndDeliver = NULL
);
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 VisibleItemDefinion_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;
VisibleItemDefinion_t()
{
m_nIndex = -1;
m_bRarelyUsed
= m_bRarelyUsedPrev
= m_bRarelyUsedNext
= m_bHelperIsSeparator
= m_bHelperIsPopup
= false;
m_nHelperCmdID = ID_SEPARATOR;
m_rcItem.SetRectEmpty();
}
VisibleItemDefinion_t(
const VisibleItemDefinion_t & other
)
{
AssignFromOther(other);
}
~VisibleItemDefinion_t()
{
}
VisibleItemDefinion_t & operator=(
const VisibleItemDefinion_t & other
)
{
AssignFromOther(other);
return * this;
}
void AssignFromOther(
const VisibleItemDefinion_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 < VisibleItemDefinion_t, VisibleItemDefinion_t & >
visible_items_t;
void _GetVisibleItems(
CDC & dc,
visible_items_t & v
);
BOOL _TrackPopupMenu(
DWORD dwTrackFlags,
int x,
int y,
LPCRECT lpRect,
LPVOID pCbPaintCombinedCookie = NULL,
pCbPaintCombinedContent pCbPaintCombinedContent = NULL
);
public:
void _ItemFocusCancel( BOOL bRepaint );
void _ItemFocusDelay( int nItemIndex = IDX_NOTHING );
void _ItemFocusSet(
int nCurIndex,
BOOL bEnableDropChild,
BOOL bRepaint
);
void _GetItemRect(
int nIndex,
RECT & rectItem
);
public:
virtual bool _OnMouseMove(UINT nFlags, CPoint point);
virtual bool _OnMouseClick(UINT nFlags, CPoint point);
virtual bool _OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags);
protected:
virtual void _FreeWinObjects();
virtual void _OnCancelMode(
bool bNcDestroy = false
);
virtual void _SetCapture();
virtual CExtPopupMenuWnd * _GetCapture();
virtual void _ReleaseCapture();
int _GetMaxScrollPos();
bool _StartScrolling(int nButtonIndex);
virtual void _SyncItems();
void _DoExpand();
bool _CoolTipIsVisible();
void _CoolTipHide(
bool bAdvOperation = true
);
e_combine_align_t m_eCombineAlign;
CRgn m_rgnWnd;
CRect m_rcClient;
virtual CRect _CalcTrackRect();
virtual CSize _CalcTrackSize();
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::MENUITEMDATA
class MENUITEMDATA;
friend class MENUITEMDATA;
class __PROF_UIS_API MENUITEMDATA
{
CExtPopupMenuWnd * m_pWndChild;
int m_nItemIndex;
UINT m_nCmdID; // can be ID_SEPARATOR
CString m_sPopupText,m_sPopupAccelText;
HICON m_hIconPopup;
CSize m_size;
bool m_bSelected:1,m_bDisplayed:1,m_bForceDisplayed:1;
TCHAR m_cAccelChar;
HWND m_hWndSpecCmdReciever;
public:
MENUITEMDATA();
~MENUITEMDATA();
protected:
bool UpdateFromMenu(
HWND hWndCmdRecv,
CMenu * pTrackMenu,
int nItemIndex
);
void AccelCharInit();
TCHAR AccelCharGet() const;
bool AccelCharIsSet() const;
bool UpdateCmdManagerCommand(
CExtCmdManager::cmd_t * p_cmd,
int nItemIndex
);
void MeasureItem();
public:
CExtCmdManager::cmd_t * GetCmd() const;
HWND GetCmdReciever() const
{
ASSERT( m_hWndSpecCmdReciever != NULL );
ASSERT( ::IsWindow(m_hWndSpecCmdReciever) );
return m_hWndSpecCmdReciever;
}
protected:
void SetCmdReciever( HWND hWndSpecCmdReciever )
{
ASSERT( hWndSpecCmdReciever != NULL );
ASSERT( ::IsWindow(hWndSpecCmdReciever) );
m_hWndSpecCmdReciever = hWndSpecCmdReciever;
}
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 );
return m_pWndChild->IsAllItemsRarelyUsed();
}
bool IsEnabled() const
{
if( IsPopup() )
return true;
if( IsSeparator() )
return false;
return GetCmd()->StateIsEnable();
}
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 GetCmd()->StateGetRadio();
}
bool GetCheck() const
{
if( IsPopup() || IsSeparator() )
return false;
return GetCmd()->StateGetCheck();
}
bool GetIndeterminate() const
{
if( IsPopup() || IsSeparator() )
return false;
return GetCmd()->StateGetIndeterminate();
}
LPCTSTR GetText() const
{
if( IsSeparator() )
return _T("");
if( IsPopup() )
return (LPCTSTR)m_sPopupText;
return GetCmd()->m_sMenuText;
}
LPCTSTR GetAccelText() const
{
if( IsSeparator() )
return _T("");
if( IsPopup() )
return (LPCTSTR)m_sPopupAccelText;
return GetCmd()->m_sAccelText;
}
HICON GetIcon()
{
if( IsSeparator() )
return NULL;
if( IsPopup() )
return m_hIconPopup;
return
g_CmdManager->CmdGetHICON(
g_CmdManager->ProfileNameFromWnd( GetCmdReciever() ),
m_nCmdID
);
}
LPCTSTR GetTip() const
{
if( IsPopup() || IsSeparator() )
return _T("");
return GetCmd()->m_sTipStatus;
}
bool IsSeparator() const
{
bool bSeparator =
(m_nCmdID==TYPE_SEPARATOR) ? true : false;
return bSeparator;
}
protected:
void SetSeparator(
int nItemIndex
)
{
if( !IsSeparator() )
{
if( m_pWndChild != NULL )
DestroyPopup();
ASSERT( m_pWndChild == NULL );
m_sPopupText.Empty();
m_nCmdID = TYPE_SEPARATOR;
m_nItemIndex = nItemIndex;
}
MeasureItem();
}
void SetPopup(
int nItemIndex,
LPCTSTR sText = NULL,
HICON hIcon = NULL,
CExtPopupMenuWnd * pSpecPopup = NULL
)
{
ASSERT( m_hWndSpecCmdReciever != NULL );
ASSERT( ::IsWindow(m_hWndSpecCmdReciever) );
if( m_pWndChild == NULL )
{
if( pSpecPopup == NULL )
{
ConstructPopup();
} // if( pSpecPopup == NULL )
else
{
m_pWndChild = pSpecPopup;
ASSERT( m_pWndChild != NULL );
m_pWndChild->m_hWndCmdReciever = m_hWndSpecCmdReciever;
} // else from if( pSpecPopup == NULL )
}
m_nCmdID = (UINT)TYPE_POPUP;
m_sPopupAccelText = _T("");
m_sPopupText = _T("");
m_nItemIndex = nItemIndex;
ASSERT( m_hIconPopup == NULL );
VERIFY( SetPopupIcon(hIcon) );
VERIFY( SetPopupText(sText) );
MeasureItem();
}
bool SetPopupIcon( HICON hIcon )
{
if( !IsPopup() )
{
ASSERT( FALSE );
return false;
}
if( m_hIconPopup != NULL
&& m_hIconPopup != hIcon
)
{
VERIFY( DestroyIcon(m_hIconPopup) );
}
if( hIcon == NULL )
{
m_hIconPopup = NULL;
return true;
}
CExtCmdManager::icon_t _icon( hIcon, true );
m_hIconPopup = _icon.Detach();
ASSERT( m_hIconPopup != NULL );
return true;
}
bool SetPopupText( LPCTSTR sText ) // NULL if empty
{
if( !IsPopup() )
{
ASSERT( FALSE );
return false;
}
m_sPopupText =
(sText == NULL) ? _T("") : sText;
int nPos = m_sPopupText.Find(_T('\t'));
if( nPos >= 0 )
{
CString sLeft = m_sPopupText.Left(nPos);
CString sRight = m_sPopupText.Right(m_sPopupText.GetLength()-nPos-1);
m_sPopupText = sLeft;
m_sPopupAccelText = sRight;
}
return true;
}
bool SetPopupAccelText( LPCTSTR sText ) // NULL if empty
{
if( !IsPopup() )
{
ASSERT( FALSE );
return false;
}
m_sPopupAccelText =
(sText == NULL) ? _T("") : sText;
return true;
}
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
{
if( IsSeparator() || IsPopup() )
return (UINT)(IDC_STATIC);
ASSERT( GetCmd()->m_nCmdID == m_nCmdID );
return m_nCmdID;
}
bool IsExecutableCmdID() const
{
if( IsSeparator() || IsPopup() )
return false;
return true;
}
int GetMeasuredHeight() const
{
return m_size.cy;
}
int GetMeasuredWidth() const
{
return m_size.cx;
}
CRect GetBaseRect() const
{
CRect rcItem(
CPoint(0,0),
m_size
);
return rcItem;
}
int GetIndex() const
{
return m_nItemIndex;
}
protected:
void SetIndex( int nItemIndex )
{
m_nItemIndex = nItemIndex;
}
friend class CExtPopupMenuWnd;
}; // class MENUITEMDATA
/////////////////////////////////////////////////////////////////////////////
// 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_bMenuOwnderDrawFixed:1;
const bool m_bPopupItem:1;
const bool m_bRarelyUsed:1;
const bool m_bRarelyUsedPreviouse:1;
const bool m_bRarelyUsedNext:1;
protected:
DRAWITEMDATA(
CDC * pDC,
LPCRECT pRectItem,
const MENUITEMDATA * pItemData,
CExtPopupMenuWnd * pPopup,
bool bMenuOwnderDrawFixed,
bool bPopupItem,
bool bRarelyUsed,
bool bRarelyUsedPreviouse,
bool bRarelyUsedNext
)
: m_pDC( pDC )
, m_pRectItem( pRectItem )
, m_pItemData( pItemData )
, m_pPopup( pPopup )
, m_bMenuOwnderDrawFixed( bMenuOwnderDrawFixed )
, m_bPopupItem( bPopupItem )
, m_bRarelyUsed( bRarelyUsed )
, m_bRarelyUsedPreviouse( bRarelyUsedPreviouse )
, 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 HICON()
{
ASSERT( this != NULL );
ASSERT( m_pItemData != NULL );
return (
const_cast < MENUITEMDATA * > ( m_pItemData )
)->GetIcon();
}
operator 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:
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;
void _InsertItem(
int nInsertBefore,
MENUITEMDATA & mi
);
public:
// 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();
}
protected:
virtual void PostNcDestroy();
// Generated message map functions
//{{AFX_MSG(CExtPopupMenuWnd)
afx_msg void OnCancelMode();
afx_msg void OnTimer(UINT nIDEvent);
//}}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 OnLButtonUp(UINT nFlags, CPoint point);
// afx_msg void OnLButtonDblClk(UINT nFlags, CPoint point);
// afx_msg void OnMButtonDown(UINT nFlags, CPoint point);
// afx_msg void OnMButtonUp(UINT nFlags, CPoint point);
// afx_msg void OnMButtonDblClk(UINT nFlags, CPoint point);
// afx_msg void OnRButtonDown(UINT nFlags, CPoint point);
// afx_msg void OnRButtonUp(UINT nFlags, CPoint point);
// afx_msg void OnRButtonDblClk(UINT nFlags, CPoint point);
// afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags);
// afx_msg void OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags);
// afx_msg void OnSysKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags);
// afx_msg void OnSysKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags);
// afx_msg void OnSysDeadChar(UINT nChar, UINT nRepCnt, UINT nFlags);
// afx_msg void OnChar(UINT nChar, UINT nRepCnt, UINT nFlags);
class CExtPopupMenuCmdUI;
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_clrDefault,m_clrInitial;
bool m_bEnableBtnColorDefault:1;
bool m_bEnableBtnColorCustom:1;
CString m_sBtnTextColorDefault;
CString 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 * pWndCmdReciever
);
// To hold the colours and their names
struct __PROF_UIS_API COLORREF_TABLE_ENTRY
{
COLORREF m_clr;
LPCTSTR m_sName;
};
static COLORREF_TABLE_ENTRY g_colors[];
virtual int _HitTest(const CPoint & point )
{
ASSERT_VALID( this );
point;
return IDX_NOTHING;
}
void _NotifyColorChanged(
bool bFinal = false
);
CPoint _GetColorItemCoord(int nIdx);
CRect _GetColorItemRect(int nIdx);
int _ColorItemHitTest(const CPoint & point);
virtual CRect _CalcTrackRect();
virtual CSize _CalcTrackSize();
virtual void _DoPaint( CDC & dcPaint, bool bUseBackBuffer = true );
public:
virtual bool _OnMouseMove(UINT nFlags, CPoint point);
virtual bool _OnMouseClick(UINT nFlags, CPoint point);
virtual bool _OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags);
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