// 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.
#include "stdafx.h"
#if _MFC_VER < 0x700
#include <../src/AfxImpl.h>
#else
#include <../src/mfc/AfxImpl.h>
#endif
#if (!defined __EXT_TOOLCONTROLBAR_H)
#include <ExtToolControlBar.h>
#endif
#if (!defined __EXT_MENUCONTROLBAR_H)
#include <ExtMenuControlBar.h>
#endif
#if (!defined __EXTDOCKBAR_H)
#include "ExtDockBar.h"
#endif
#if( !defined __EXTMINIDOCKFRAMEWND_H)
#include "ExtMiniDockFrameWnd.h"
#endif
#if (!defined __EXT_PAINT_MANAGER_H)
#include <ExtPaintManager.h>
#endif
#if (!defined __EXT_MEMORY_DC_H)
#include <../Src/ExtMemoryDC.h>
#endif
#if (!defined __EXT_POPUP_MENU_WND_H)
#include <ExtPopupMenuWnd.h>
#endif
#if (!defined __ExtCmdManager_H)
#include <ExtCmdManager.h>
#endif
#if (!defined __EXT_LOCALIZATION_H)
#include <../Src/ExtLocalization.h>
#endif
#include <../profuisdll/resource.h>
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#define CX_BORDER 1
#define CY_BORDER 1
const UINT CExtToolControlBar::g_nMsgPutToPopupMenu =
::RegisterWindowMessage(
_T("CExtToolControlBar::g_nMsgPutToPopupMenu")
);
/////////////////////////////////////////////////////////////////////////////
// CExtBarButton
IMPLEMENT_DYNAMIC(CExtBarButton, CObject)
bool CExtBarButton::IsAbleToTrackMenu()
{
if( GetMenu() != NULL
||
IsKindOf(RUNTIME_CLASS(CExtBarContentExpandButton))
)
return true;
return false;
}
CString CExtBarButton::GetText() const
{
CString sText( _T("") );
if( IsSeparator() )
return sText;
CExtCmdManager::cmd_t * p_cmd =
g_CmdManager->CmdGetPtr(
g_CmdManager->ProfileNameFromWnd( m_pBar->GetSafeHwnd() ),
GetCmdID()
);
ASSERT( p_cmd != NULL );
if( !p_cmd->m_sToolbarText.IsEmpty() )
sText = p_cmd->m_sToolbarText;
int nTabChrPos = sText.Find( _T('\t') );
if( nTabChrPos < 0 )
return sText;
return sText.Left( nTabChrPos );
}
BOOL CExtBarButton::PutToPopupMenu(
CExtPopupMenuWnd * pPopup
)
{
ASSERT( pPopup != NULL );
ASSERT( pPopup->GetSafeHwnd() == NULL );
if( m_pCtrl != NULL )
{
if( m_pCtrl->SendMessage(
CExtToolControlBar::g_nMsgPutToPopupMenu,
reinterpret_cast <WPARAM> ( pPopup ),
0
)
)
return TRUE;
}
HMENU hMenu = GetMenu();
if( hMenu != NULL )
{
ASSERT( ::IsMenu(hMenu) );
CExtCmdManager::cmd_t * p_cmd =
g_CmdManager->CmdGetPtr(
g_CmdManager->ProfileNameFromWnd( m_pBar->GetSafeHwnd() ),
GetCmdID()
);
ASSERT( p_cmd != NULL );
CString sText = p_cmd->m_sMenuText;
if( sText.IsEmpty() )
sText = p_cmd->m_sToolbarText;
HICON hIcon =
g_CmdManager->CmdGetHICON(
g_CmdManager->ProfileNameFromWnd( m_pBar->GetSafeHwnd() ),
GetCmdID()
);
if( hIcon != NULL )
{
CExtCmdManager::icon_t _icon(
hIcon,
true
);
hIcon = _icon.Detach();
}
VERIFY(
pPopup->ItemInsert(
(UINT)CExtPopupMenuWnd::TYPE_POPUP,
-1,
(LPCTSTR)sText,
hIcon
)
);
CExtPopupMenuWnd * pChildPopup =
pPopup->ItemGetPopup(
pPopup->ItemGetCount() - 1
);
ASSERT( pChildPopup != NULL );
CMenu _menu;
_menu.Attach( hMenu );
pChildPopup->UpdateFromMenu(
GetCmdTargetWnd()->GetSafeHwnd(), //m_pBar->GetSafeHwnd(),
&_menu,
IsContainerOfPopupLikeMenu() ? true : false,
false
);
_menu.Detach();
} // if( hMenu != NULL )
else
{
if( !pPopup->ItemInsert(GetCmdID()) )
{
ASSERT( FALSE );
return FALSE;
}
} // else from if( hMenu != NULL )
return TRUE;
}
CSize CExtBarButton::CalculateLayout(
CDC & dc,
CSize sizePreCalc,
BOOL bHorz
)
{
ASSERT_VALID( m_pBar );
ASSERT_VALID( (&dc) );
if( (m_pCtrl != NULL) && (!m_bVertDocked || GetCtrlVisibleVertically()) )
{
ASSERT_VALID( m_pCtrl );
CRect rcCtrl;
m_pCtrl->GetWindowRect( &rcCtrl );
//return rcCtrl.Size();
m_ActiveSize.cx = rcCtrl.Width();
m_ActiveSize.cy = sizePreCalc.cy;
return m_ActiveSize;
} // if( (m_pCtrl != NULL) && (!m_bVertDocked || GetCtrlVisibleVertically()) )
m_ActiveSize = sizePreCalc;
if( IsSeparator() )
{
if( bHorz )
m_ActiveSize.cx = __TB_SEPARATOR_WIDTH__;
else
m_ActiveSize.cy = __TB_SEPARATOR_WIDTH__;
} // if( IsSeparator() )
else
{
CExtCmdManager::cmd_t * p_cmd =
g_CmdManager->CmdGetPtr(
g_CmdManager->ProfileNameFromWnd( m_pBar->GetSafeHwnd() ),
GetCmdID()
);
ASSERT( p_cmd != NULL );
CExtCmdManager::icon_t * p_icon =
g_CmdManager->CmdGetIconPtr(
g_CmdManager->ProfileNameFromWnd( m_pBar->GetSafeHwnd() ),
GetCmdID()
);
CSize _size(0,0);
if( p_icon != NULL )
_size = *p_icon;
CString sMeasureText = GetText();
if( !sMeasureText.IsEmpty() )
{
static TCHAR stat_strDummyAmpSeq[] = _T("\001\001");
sMeasureText.Replace( _T("&&"), stat_strDummyAmpSeq );
sMeasureText.Remove( _T('&') );
sMeasureText.Replace( stat_strDummyAmpSeq, _T("&") );
int iPixTextWidth =
dc.GetTextExtent(
(LPCTSTR)sMeasureText
).cx
+ __TB_TEXT_MARGINE__*2;
if( bHorz )
_size.cx += iPixTextWidth;
else
_size.cy += iPixTextWidth;
} // if( !sMeasureText.IsEmpty() )
if( m_ActiveSize.cx < _size.cx )
m_ActiveSize.cx = _size.cx;
if( m_ActiveSize.cy < _size.cy )
m_ActiveSize.cy = _size.cy;
} // else from if( IsSeparator() )
if( GetMenu() != NULL
&& (!m_pBar->IsKindOf(RUNTIME_CLASS(CExtMenuControlBar)))
)
{
if( bHorz )
{
m_ActiveSize.cx +=
__DROPDOWN_ARROW_GAP*2
+ CExtPaintManager::g_glyph_btn_expand_bottom.Size().cx
;
} // if( bHorz )
else
{
m_ActiveSize.cy +=
__DROPDOWN_ARROW_GAP*2
+ CExtPaintManager::g_glyph_btn_expand_right.Size().cy
;
} // else from if( bHorz )
}
m_ActiveSize.cx += __TB_BUTTON_MARGINE__*2;
m_ActiveSize.cy += __TB_BUTTON_MARGINE__*2;
return m_ActiveSize;
}
HICON CExtBarButton::GetHICON()
{
HICON hIcon =
g_CmdManager->CmdGetHICON(
g_CmdManager->ProfileNameFromWnd( m_pBar->GetSafeHwnd() ),
GetCmdID()
);
return hIcon;
}
void CExtBarButton::Paint(
CDC & dc,
bool bHorz
)
{
ASSERT_VALID( (&dc) );
if( (m_pCtrl != NULL) && (!m_bVertDocked || GetCtrlVisibleVertically()) )
return;
ASSERT( !IsSeparator() );
CRect rcArea( m_ActiveRect );
rcArea.DeflateRect(
__TB_BUTTON_MARGINE__,
__TB_BUTTON_MARGINE__
);
if( rcArea.right <= rcArea.left
||
rcArea.bottom <= rcArea.top
)
return;
if( GetStyle() & TBBS_HIDDEN )
return;
if( (!IsVisible())
||
(!dc.RectVisible(&m_ActiveRect))
)
return;
ASSERT(
m_ActiveSize.cx >= __TB_BUTTON_MARGINE__*2
&&
m_ActiveSize.cy >= __TB_BUTTON_MARGINE__*2
);
bool bPushed =
IsPressed() ? true : false;
bool bEnabled = IsDisabled() ? false : true;
bool bHover =
( IsHover()
&& !CExtToolControlBar::g_bMenuTracking
&& !CExtPopupMenuWnd::IsMenuTracking()
) ? true : false;
bool bIndeterminate = IsIndeterminate() ? true : false;
CString sText = GetText();
g_PaintManager->PaintPushButton(
dc,
bHorz,
rcArea,
(LPCTSTR)sText,
GetHICON(),
true,
bHover,
bPushed,
bIndeterminate,
bEnabled,
true,false,false,
CExtPaintManager::__ALIGN_HORIZ_CENTER
| CExtPaintManager::__ALIGN_VERT,
NULL,
(GetMenu() != NULL
&& (!m_pBar->IsKindOf(RUNTIME_CLASS(CExtMenuControlBar)))
) ? true : false,
0,
( bEnabled && (!bHover) && (!bPushed) )
);
}
void CExtBarButton::SetMenu(
HMENU hMenu,
BOOL bPopupMenu,
BOOL bAutoDestroyMenu
)
{
_DestroyMenu();
m_hMenu = hMenu;
if( m_hMenu != NULL )
{
ASSERT( ::IsMenu(hMenu) );
VERIFY(
g_CmdManager->UpdateFromMenu(
g_CmdManager->ProfileNameFromWnd( m_pBar->GetSafeHwnd() ),
hMenu
)
);
m_bPopupMenu = bPopupMenu;
ModifyStyle(0,TBBS_DISABLED);
m_bAutoDestroyMenu = bAutoDestroyMenu;
}
}
UINT CExtBarButton::_GetTrackPopupFlags()
{
ASSERT_VALID( m_pBar );
if( m_pBar->m_bPresubclassDialogMode )
{
if( m_pBar->IsDockedAtRight() )
return TPMX_RIGHTALIGN;
if( m_pBar->IsDockedAtLeft() )
return TPMX_LEFTALIGN;
if( m_pBar->IsDockedAtBottom() )
return TPMX_BOTTOMALIGN;
return TPMX_TOPALIGN;
}
switch( m_pBar->GetSafeDockBarDlgCtrlID() )
{
case AFX_IDW_DOCKBAR_TOP:
return TPMX_TOPALIGN;
case AFX_IDW_DOCKBAR_BOTTOM:
return TPMX_BOTTOMALIGN;
case AFX_IDW_DOCKBAR_LEFT:
return TPMX_LEFTALIGN;
case AFX_IDW_DOCKBAR_RIGHT:
return TPMX_RIGHTALIGN;
default: // floating
return TPMX_TOPALIGN;
} // switch( m_pBar->GetSafeDockBarDlgCtrlID() )
}
CWnd * CExtBarButton::GetCmdTargetWnd()
{
ASSERT_VALID( m_pBar );
//CWnd * pWnd = m_pBar->_GetDockingFrameImpl();
// if( pWnd == NULL )
// pWnd = m_pBar->GetOwner();
CWnd * pWnd = m_pBar->GetOwner();
ASSERT_VALID( pWnd );
return pWnd;
}
void CExtBarButton::OnTrackPopup(
CPoint point
)
{
ASSERT_VALID( m_pBar );
if( !IsEnabled() )
return;
HMENU hMenu = GetMenu();
if( hMenu == NULL )
return;
ASSERT( ::IsMenu(hMenu) );
bool bPrevTBMT = CExtToolControlBar::g_bMenuTracking;
if( CExtToolControlBar::g_bMenuTracking
//&& CExtPopupMenuWnd::IsMenuTracking()
&& m_pBar->_GetIndexOf(this) ==
m_pBar->m_nBtnIdxMenuTracking
)
return;
CExtToolControlBar::_CloseTrackingMenus();
if( m_pBar->IsFloating() )
{
m_pBar->ActivateTopParent();
CFrameWnd * pFrame =
m_pBar->GetDockingFrame();
ASSERT_VALID( pFrame );
pFrame->BringWindowToTop();
}
CWnd * pWndCmdTarger = GetCmdTargetWnd();
ASSERT_VALID( pWndCmdTarger );
CExtPopupMenuWnd * pPopup = new CExtPopupMenuWnd;
CMenu _menu;
_menu.Attach( hMenu );
VERIFY(
pPopup->UpdateFromMenu(
pWndCmdTarger->GetSafeHwnd(),
&_menu,
m_bPopupMenu ? true : false
)
);
_menu.Detach();
if( IsAppendMdiWindowsMenu() )
pPopup->UpdateMdiWindowsMenu( pWndCmdTarger );
CExtToolControlBar::g_bMenuTracking = bPrevTBMT;
CRect rcBtn = Rect();
m_pBar->ClientToScreen( &rcBtn );
m_pBar->ClientToScreen( &point );
DWORD dwTrackFlags =
_GetTrackPopupFlags()
| TPMX_COMBINE_DEFAULT
| TPMX_OWNERDRAW_FIXED
;
if( m_pBar->IsKindOf(RUNTIME_CLASS(CExtMenuControlBar)) )
dwTrackFlags |= TPMX_SELECT_ANY;
if( CExtToolControlBar::g_bMenuTrackingExpanded )
dwTrackFlags |= TPMX_NO_HIDE_RARELY;
m_pBar->_SwitchMenuTrackingIndex(
m_pBar->_GetIndexOf( this )
);
if( !pPopup->TrackPopupMenu(
dwTrackFlags,
point.x,point.y,
&rcBtn,
m_pBar,
CExtToolControlBar::_CbPaintCombinedContent
)
)
{
delete pPopup;
CExtToolControlBar::_CloseTrackingMenus();
return;
}
CExtToolControlBar::g_bMenuTracking = true;
}
void CExtBarButton::OnHover(
CPoint point,
bool bOn
)
{
ASSERT_VALID( m_pBar );
if( bOn )
{
/// if( CExtToolControlBar::g_bMenuTracking
/// && CExtPopupMenuWnd::IsMenuTracking()
/// && m_pBar->m_nBtnIdxHover != m_pBar->m_nBtnIdxMenuTracking
/// )
/// CExtPopupMenuWnd::CancelMenuTracking();
if( CExtToolControlBar::g_bMenuTracking )
OnTrackPopup( point );
else
{
m_pBar->GetOwner()->
//m_pBar->_GetDockingFrameImpl()->
SendMessage(
WM_SETMESSAGESTRING,
(WPARAM)(
CExtCmdManager::IsCommand(GetCmdID()) ?
GetCmdID() : AFX_IDS_IDLEMESSAGE
)
);
}
CWnd * pCtrl = CtrlGet();
if( pCtrl == NULL
|| (pCtrl->GetStyle() & WS_VISIBLE) == 0
)
m_pBar->SetCapture();
} // if( bOn )
else
ReleaseCapture();
}
void CExtBarButton::OnClick(
CPoint point,
bool bDown
)
{
ASSERT_VALID( m_pBar );
if( bDown )
{
CExtToolControlBar::_CloseTrackingMenus();
if( GetMenu() != NULL )
{
CExtToolControlBar::g_bMenuTrackingExpanded = false;
OnTrackPopup( point );
return;
}
m_pBar->GetOwner()->SendMessage(
WM_SETMESSAGESTRING,
(WPARAM)GetCmdID()
);
return;
} // if( bDown )
m_pBar->GetOwner()->SendMessage(
WM_SETMESSAGESTRING,
AFX_IDS_IDLEMESSAGE
);
if( GetMenu() != NULL )
{
// OnTrackPopup( point );
return;
}
CWnd * pCtrl = CtrlGet();
if( pCtrl != NULL
&& (pCtrl->GetStyle() & WS_VISIBLE)
)
{
ASSERT_VALID( pCtrl );
CExtToolControlBar * pBar = GetBar();
ASSERT_VALID( pBar );
if( CWnd::GetCapture() == pBar )
pBar->SendMessage( WM_CANCELMODE );
//pCtrl->SetFocus();
return;
}
if( !CExtCmdManager::IsCommand( GetCmdID() ) )
return;
CExtCmdManager::cmd_t * p_cmd =
g_CmdManager->CmdGetPtr(
g_CmdManager->ProfileNameFromWnd( m_pBar->GetSafeHwnd() ),
GetCmdID()
);
ASSERT( p_cmd != NULL );
if( p_cmd == NULL )
return;
VERIFY(
p_cmd->Deliver(
m_pBar,
true
)
);
}
int CExtBarButton::OnToolHitTest(
CPoint point,
TOOLINFO * pTI
)
{
ASSERT_VALID( this );
point; // should be inside this button
if( IsSeparator()
//|| pTBB->IsAbleToTrackMenu()
)
return -1;
int nCmdID = (int)GetCmdID();
CExtCmdManager::cmd_t * p_cmd =
g_CmdManager->CmdGetPtr(
g_CmdManager->ProfileNameFromWnd( GetBar()->GetSafeHwnd() ),
nCmdID
);
if( p_cmd == NULL
|| p_cmd->m_sTipTool.IsEmpty()
)
return false;
if( pTI != NULL )
{
CRect rcArea = Rect();
::CopyRect(
&(pTI->rect),
&rcArea
);
pTI->uId = (UINT)nCmdID;
pTI->hwnd = GetBar()->GetSafeHwnd();
pTI->lpszText = (LPTSTR)
::calloc(
(p_cmd->m_sTipTool.GetLength() + 1),
sizeof(TCHAR)
);
if( pTI->lpszText != NULL )
_tcscpy(
pTI->lpszText,
(LPCTSTR)p_cmd->m_sTipTool
);
else
pTI->lpszText = LPSTR_TEXTCALLBACK;
} // if( pTI != NULL )
return nCmdID;
}
/////////////////////////////////////////////////////////////////////////////
// CExtBarContentExpandButton
IMPLEMENT_DYNAMIC(CExtBarContentExpandButton, CExtBarButton)
CSize CExtBarContentExpandButton::CalculateLayout(
CDC & dc,
CSize sizePreCalc,
BOOL bHorz
)
{
dc;
ASSERT( m_pCtrl == NULL );
ASSERT( !IsSeparator() );
ASSERT( GetCmdID() == __ID_TOOLBAR_RIGHT_BUTTON__ );
CSize _size(
bHorz ? __RIGHT_BUTTON_HORZ_DX__ : sizePreCalc.cx,
bHorz ? sizePreCalc.cy : __RIGHT_BUTTON_VERT_DY__
);
m_ActiveSize = _size;
m_ActiveSize.cx += __TB_BUTTON_MARGINE__*2;
m_ActiveSize.cy += __TB_BUTTON_MARGINE__*2;
return m_ActiveSize;
}
void CExtBarContentExpandButton::Paint(
CDC & dc,
bool bHorz
)
{
ASSERT( m_pCtrl == NULL );
ASSERT_VALID( (&dc) );
ASSERT( !IsSeparator() );
ASSERT( GetCmdID() == __ID_TOOLBAR_RIGHT_BUTTON__ );
// ASSERT( !IsDisabled() );
CRect rcArea( m_ActiveRect );
rcArea.DeflateRect(
__TB_BUTTON_MARGINE__,
__TB_BUTTON_MARGINE__
);
if( rcArea.right <= rcArea.left
||
rcArea.bottom <= rcArea.top
)
return;
if( // (!IsVisible()) ||
(!dc.RectVisible(&m_ActiveRect))
)
return;
ASSERT(
m_ActiveSize.cx >= __TB_BUTTON_MARGINE__*2
&&
m_ActiveSize.cy >= __TB_BUTTON_MARGINE__*2
);
bool bEnabled = !IsDisabled();
bool bBarIsCompletelyVisible =
(GetButtons().GetSize() == 0) ? true : false;
bool bEmpty =
( !m_pBar->m_bRightButtonDisplayBarsList
&& bBarIsCompletelyVisible
) ? true : false;
bool bPushed =
( !bEmpty && bEnabled && IsPressed() ) ? true : false;
bool bHover =
( !bEmpty
&& bEnabled
&& IsHover()
&& !CExtToolControlBar::g_bMenuTracking
&& !CExtPopupMenuWnd::IsMenuTracking()
) ? true : false;
g_PaintManager->PaintToolbarExpandButton(
dc,
rcArea,
bHorz,
bBarIsCompletelyVisible,
bEnabled && !bEmpty,
bPushed,
bHover,
( (!bHover) && (!bPushed) )
);
}
BOOL CExtBarContentExpandButton::PutToPopupMenu(
CExtPopupMenuWnd * pPopup
)
{
pPopup;
ASSERT( FALSE );
return FALSE;
}
void CExtBarContentExpandButton::OnTrackPopup(
CPoint point
)
{
ASSERT_VALID( m_pBar );
if( !IsEnabled() )
return;
bool bPrevTBMT = CExtToolControlBar::g_bMenuTracking;
if( CExtToolControlBar::g_bMenuTracking
//&& CExtPopupMenuWnd::IsMenuTracking()
&& m_pBar->_GetIndexOf(this) ==
m_pBar->m_nBtnIdxMenuTracking
)
return;
bool bBarIsCompletelyVisible =
(GetButtons().GetSize() == 0) ? true : false;
bool bEmpty =
( !m_pBar->m_bRightButtonDisplayBarsList
&& bBarIsCompletelyVisible
) ? true : false;
if( bEmpty )
return;
CExtToolControlBar::_CloseTrackingMenus();
CExtToolControlBar::g_bMenuTracking = bPrevTBMT;
if( m_pBar->IsFloating() )
{
m_pBar->ActivateTopParent();
CFrameWnd * pFrame =
m_pBar->GetParentFrame();
if( pFrame != NULL )
pFrame->BringWindowToTop();
}
HWND hWndTrack = GetCmdTargetWnd()->GetSafeHwnd();
ASSERT(
hWndTrack != NULL
&& ::IsWindow(hWndTrack)
);
CExtPopupMenuWnd * pPopup =
new CExtPopupMenuWnd;
VERIFY( pPopup->CreatePopupMenu(hWndTrack) );
// append hidden buttons
int nCount = GetButtons().GetSize();
if( nCount != 0 )
{
ASSERT( nCount > 0 );
int nCountBefore = pPopup->ItemGetCount();
for( int i=0; i< nCount; i++ )
{
CExtBarButton * pTBB = GetButtons() [i];
ASSERT( pTBB != NULL );
if( i==0 && pTBB->IsSeparator() )
continue;
ASSERT( !pTBB->IsKindOf(RUNTIME_CLASS(CExtBarContentExpandButton)) );
VERIFY( pTBB->PutToPopupMenu(pPopup) );
} // for( int i=0; i< nCount; i++ )
int nCountAfter = pPopup->ItemGetCount();
ASSERT( nCountAfter >= nCountBefore );
if( nCountAfter != nCountBefore
&& (!m_pBar->m_bPresubclassDialogMode)
&& m_pBar->m_bRightButtonDisplayBarsList
)
{
// append separator
VERIFY(
pPopup->ItemInsert(
CExtPopupMenuWnd::TYPE_SEPARATOR
)
);
}
} // if( nCount != 0 )
// append show/hide popup
if( (!m_pBar->m_bPresubclassDialogMode)
&& m_pBar->m_bRightButtonDisplayBarsList
)
{
CFrameWnd * pFrame = m_pBar->_GetDockingFrameImpl();
if( pFrame != NULL )
{
ASSERT_VALID( pFrame );
#if (defined _AFXDLL && !defined __STATPROFUIS_WITH_DLLMFC__)
CExtLocalResourceHelper _LRH;
#endif // #if (defined _AFXDLL && !defined __STATPROFUIS_WITH_DLLMFC__)
CString sShowHidePanels;
if( !sShowHidePanels.LoadString(IDS_SHOW_HIDE_PANELS) )
{
#if (defined _AFXDLL && !defined __STATPROFUIS_WITH_DLLMFC__)
ASSERT( FALSE );
#endif // #if (defined _AFXDLL && !defined __STATPROFUIS_WITH_DLLMFC__)
sShowHidePanels = _T("&Show/hide panels");
}
VERIFY(
pPopup->ItemInsert(
(UINT)CExtPopupMenuWnd::TYPE_POPUP,
-1,
sShowHidePanels
)
);
CExtPopupMenuWnd * pPopupBars =
pPopup->ItemGetPopup(
pPopup->ItemGetCount() - 1
);
ASSERT( pPopupBars != NULL );
CExtDockBar::_ContextMenuBuild(
pFrame,
pPopupBars
);
} // if( pFrame != NULL )
} // if( (!m_pBar->m_bPresubclassDialogMode) ...
CRect rcBtn = Rect();
m_pBar->ClientToScreen( &rcBtn );
m_pBar->ClientToScreen( &point );
DWORD dwTrackFlags =
_GetTrackPopupFlags()
| TPMX_COMBINE_DEFAULT
| TPMX_OWNERDRAW_FIXED
;
if( m_pBar->IsKindOf(RUNTIME_CLASS(CExtMenuControlBar)) )
dwTrackFlags |= TPMX_SELECT_ANY;
if( CExtToolControlBar::g_bMenuTrackingExpanded )
dwTrackFlags |= TPMX_NO_HIDE_RARELY;
m_pBar->_SwitchMenuTrackingIndex(
m_pBar->_GetIndexOf( this )
);
if( !pPopup->TrackPopupMenu(
dwTrackFlags,
point.x,point.y,
&rcBtn,
m_pBar,
CExtToolControlBar::_CbPaintCombinedContent
)
)
{
delete pPopup;
CExtToolControlBar::_CloseTrackingMenus();
return;
}
CExtToolControlBar::g_bMenuTracking = true;
}
void CExtBarContentExpandButton::OnHover(
CPoint point,
bool bOn
)
{
ASSERT_VALID( m_pBar );
CExtBarButton::OnHover(
point,
bOn
);
}
void CExtBarContentExpandButton::OnClick(
CPoint point,
bool bDown
)
{
ASSERT_VALID( m_pBar );
// if( bDown )
if( !bDown )
return;
CExtToolControlBar::g_bMenuTrackingExpanded = false;
OnTrackPopup( point );
}
int CExtBarContentExpandButton::OnToolHitTest(
CPoint point,
TOOLINFO * pTI
)
{
ASSERT_VALID( this );
point; // should be inside this button
if( pTI != NULL )
{
CRect rcArea = Rect();
::CopyRect(
&(pTI->rect),
&rcArea
);
int nCmdID = (int)GetBar()->GetDlgCtrlID();
pTI->uId = (UINT)nCmdID;
pTI->hwnd = GetBar()->GetSafeHwnd();
#if (defined _AFXDLL && !defined __STATPROFUIS_WITH_DLLMFC__)
CExtLocalResourceHelper _LRH;
#endif // #if (defined _AFXDLL && !defined __STATPROFUIS_WITH_DLLMFC__)
CString sExpandTip;
if( !sExpandTip.LoadString(IDS_CONTENT_EXPAND_TIP) )
{
#if (defined _AFXDLL && !defined __STATPROFUIS_WITH_DLLMFC__)
ASSERT( FALSE );
#endif // #if (defined _AFXDLL && !defined __STATPROFUIS_WITH_DLLMFC__)
sExpandTip = _T("Where are buttons?");
}
pTI->lpszText = (LPTSTR)
::calloc(
(sExpandTip.GetLength() + 1),
sizeof(TCHAR)
);
if( pTI->lpszText != NULL )
_tcscpy(
pTI->lpszText,
(LPCTSTR)sExpandTip
);
else
pTI->lpszText = LPSTR_TEXTCALLBACK;
return nCmdID;
} // if( pTI != NULL )
return -1;
}
/////////////////////////////////////////////////////////////////////////////
// CExtToolControlBar
IMPLEMENT_DYNAMIC(CExtToolControlBar, CExtControlBar)
CExtBarButton * CExtToolControlBar::_GetButtonPtr(int nIndex) const
{
int nButtonsCount = m_buttons.GetSize();
if( !(nIndex >= 0 && nIndex < nButtonsCount) )
{
ASSERT( FALSE );
return NULL;
}
CExtBarButton * pTBB =
m_buttons[nIndex];
ASSERT_VALID( pTBB );
return pTBB;
}
void CExtToolControlBar::_RemoveAllButtonsImpl()
{
for( INT iBtn=0; iBtn<m_buttons.GetSize(); iBtn++ )
{
CExtBarButton * pTBB = m_buttons[iBtn];
ASSERT( pTBB != NULL );
delete pTBB;
}
m_buttons.RemoveAll();
m_pRightBtn = NULL;
m_nBtnIdxCapture = -1; // nothing captured
m_nBtnIdxHover = -1;
m_nBtnIdxMenuTracking = -1;
}
int CExtToolControlBar::_GetButtonsCountImpl() const
{
int nCountOfButtons = m_buttons.GetSize();
return nCountOfButtons;
}
bool CExtToolControlBar::g_bMenuTracking = false;
bool CExtToolControlBar::g_bMenuTrackingExpanded = false;
const CSize CExtToolControlBar::g_sizeDefTBB( 23, 22 );
CExtToolControlBar::CExtToolControlBar()
{
m_bGripperStaticallyAtTop = false;
m_pRightBtn = NULL;
m_bRightButtonDisplayBarsList = true;
m_bFixedMode = true;
m_bReposSingleChildMode = false;
m_nBtnIdxCapture = -1;
m_nBtnIdxHover = -1;
m_nBtnIdxMenuTracking = -1;
// aditional spaces
m_cxLeftBorder = 1;
m_cxRightBorder = 1;
m_cyTopBorder = 1;
m_cyBottomBorder = 1;
m_nGripWidthAtLeft = 8;
m_nGripHeightAtTop = 10;
}
CExtToolControlBar::~CExtToolControlBar()
{
_RemoveAllButtonsImpl();
int nCountOfBars = g_AllBars.GetSize();
for( int i=0; i<nCountOfBars; i++ )
{
CExtControlBar * pBar = g_AllBars[i];
ASSERT( pBar != NULL );
if( pBar == this )
{
g_AllBars.RemoveAt( i );
break;
}
}
}
void CExtToolControlBar::SetSizes(
SIZE sizeTBB,
SIZE sizeImage
)
{
sizeTBB;
sizeImage;
ASSERT_VALID( this );
ASSERT(sizeTBB.cx > 0 && sizeTBB.cy > 0);
// Invalidate();
ASSERT( FALSE ); // not implemented
}
BOOL CExtToolControlBar::LoadToolBar(LPCTSTR lpszResourceName)
{
CToolBar _bar;
if( !_bar.Create(
this,
WS_CHILD|CBRS_TOP,
AFX_IDW_TOOLBAR + 1000
)
)
{
ASSERT( FALSE );
return FALSE;
}
if( !_bar.LoadToolBar(
lpszResourceName
)
)
{
ASSERT( FALSE );
return FALSE;
}
if( !g_CmdManager->UpdateFromToolBar(
g_CmdManager->ProfileNameFromWnd( GetSafeHwnd() ),
_bar
)
)
{
ASSERT( FALSE );
return FALSE;
}
int nIDCount = _bar.GetToolBarCtrl().GetButtonCount();
if( nIDCount <= 0 )
return TRUE;
UINT * lpIDArray = new UINT[nIDCount];
if( lpIDArray == NULL )
{
ASSERT( FALSE );
return FALSE;
}
for( int i=0; i<nIDCount; i++ )
{
UINT nID,nStyle;
int iImage;
_bar.GetButtonInfo(i,nID,nStyle,iImage);
lpIDArray[i] = nID;
};
BOOL bRetVal =
SetButtons(
lpIDArray,
nIDCount
);
delete [] lpIDArray;
return bRetVal;
}
bool CExtToolControlBar::_IsShowContentWhenDragging() const
{
//BOOL bDragShowContent = FALSE;
// ::SystemParametersInfo(
// SPI_GETDRAGFULLWINDOWS,
// 0,
// &bDragShowContent,
// 0
// );
// return bDragShowContent ? true : false;
// if( IsKindOf(RUNTIME_CLASS(CExtToolControlBar)) )
// return true;
// return false;
// if( CExtPopupMenuWnd::IsKeyPressed(VK_CONTROL) )
// return false;
return true;
}
BOOL CExtToolControlBar::RemoveButton(
int nPos,
BOOL bDoRecalcLayout // = TRUE
)
{
if( nPos < 0 )
{
ASSERT( FALSE );
return FALSE;
}
int nCountOfButtons = _GetButtonsCountImpl();
if( nPos >= nCountOfButtons )
{
ASSERT( FALSE );
return FALSE;
}
CExtBarButton * pTBB =
_GetButtonPtr( nPos );
ASSERT_VALID( pTBB );
if( pTBB->IsKindOf(RUNTIME_CLASS(CExtBarContentExpandButton)) )
{
ASSERT( FALSE );
return FALSE;
}
delete pTBB;
m_buttons.RemoveAt( nPos );
m_nBtnIdxCapture = -1; // nothing captured
m_nBtnIdxHover = -1;
m_nBtnIdxMenuTracking = -1;
if( bDoRecalcLayout )
_RecalcLayoutImpl();
return TRUE;
}
BOOL CExtToolControlBar::InsertSpecButton(
int nPos, // -1 - append
CExtBarButton * pButton,
BOOL bDoRecalcLayout // = TRUE
)
{
int nCountOfButtons = _GetButtonsCountImpl();
if( nPos < 0 )
nPos = nCountOfButtons;
if( nPos > nCountOfButtons )
{
ASSERT( FALSE );
return FALSE;
}
if( nCountOfButtons > 0
&& nPos == nCountOfButtons
)
{
CExtBarButton * pTBB =
_GetButtonPtr( nCountOfButtons - 1 );
ASSERT_VALID( pTBB );
if( pTBB->IsKindOf(RUNTIME_CLASS(CExtBarContentExpandButton)) )
nPos--;
}
ASSERT_VALID( pButton );
ASSERT( pButton->GetBar() != NULL );
ASSERT( pButton->GetBar() == this );
if( _GetIndexOf(pButton) >= 0 )
{
ASSERT( FALSE ); // already inserted
return FALSE;
}
m_buttons.InsertAt( nPos, pButton );
ASSERT( _GetIndexOf(pButton) >= 0 );
if( bDoRecalcLayout )
_RecalcLayoutImpl();
return TRUE;
}
BOOL CExtToolControlBar::InsertButton(
int nPos, // = -1, // append
UINT nCmdID, // = ID_SEPARATOR
BOOL bDoRecalcLayout // = TRUE
)
{
int nCountOfButtons = _GetButtonsCountImpl();
if( nPos < 0 )
nPos = nCountOfButtons;
if( nPos > nCountOfButtons )
{
ASSERT( FALSE );
return FALSE;
}
if( nCountOfButtons > 0
&& nPos == nCountOfButtons
)
{
CExtBarButton * pTBB =
_GetButtonPtr( nCountOfButtons - 1 );
ASSERT_VALID( pTBB );
if( pTBB->IsKindOf(RUNTIME_CLASS(CExtBarContentExpandButton)) )
nPos--;
}
try
{
CExtBarButton * pTBB =
new CExtBarButton(
this,
nCmdID
);
ASSERT_VALID( pTBB );
m_buttons.InsertAt(
nPos,
pTBB
);
if( bDoRecalcLayout )
_RecalcLayoutImpl();
} // try
// catch( std::exception * pXept )
// {
// delete pXept;
// ASSERT( FALSE );
// return FALSE;
// } // catch( std::exception * pXept )
catch( CException * pXept )
{
pXept->Delete();
ASSERT( FALSE );
return FALSE;
} // catch( CException * pXept )
catch( ... )
{
ASSERT( FALSE );
return FALSE;
} // catch( ... )
return TRUE;
}
CExtBarContentExpandButton * CExtToolControlBar::OnCreateBarRightBtn()
{
CExtBarContentExpandButton * pRightBtn =
new CExtBarContentExpandButton( this );
ASSERT_VALID( pRightBtn );
return pRightBtn;
}
BOOL CExtToolControlBar::SetButtons(
const UINT * lpIDArray, // = NULL
int nIDCount // = 0
)
{
ASSERT_VALID( this );
ASSERT(
lpIDArray == NULL
|| nIDCount == 0
|| AfxIsValidAddress(
lpIDArray,
sizeof(UINT) * nIDCount,
FALSE
)
);
_RemoveAllButtonsImpl();
if( lpIDArray == NULL
|| nIDCount == 0
)
return TRUE;
try
{
for( int i = 0; i < nIDCount; i++ )
{
CExtBarButton * pTBB =
new CExtBarButton(
this,
*lpIDArray++
);
ASSERT_VALID( pTBB );
m_buttons.Add( pTBB );
} // for( int i = 0; i < nIDCount; i++ )
ASSERT( m_pRightBtn == NULL );
m_pRightBtn = OnCreateBarRightBtn();
if( m_pRightBtn != NULL )
{
ASSERT_VALID( m_pRightBtn );
ASSERT_KINDOF( CExtBarContentExpandButton, m_pRightBtn );
m_buttons.Add( m_pRightBtn );
} // if( m_pRightBtn != NULL )
} // try
catch( CException * pXept )
{
pXept->Delete();
ASSERT( FALSE );
return FALSE;
} // catch( CException * pXept )
catch( ... )
{
ASSERT( FALSE );
return FALSE;
} // catch( ... )
return TRUE;
}
/////////////////////////////////////////////////////////////////////////////
// CExtToolControlBar attribute access
int CExtToolControlBar::CommandToIndex(UINT nIDFind) const
{
ASSERT_VALID(this);
int nCountOfButtons = _GetButtonsCountImpl();
for( int nBtnIdx = 0; nBtnIdx < nCountOfButtons; nBtnIdx++ )
{
CExtBarButton * pTBB = _GetButtonPtr( nBtnIdx );
ASSERT_VALID( pTBB );
if( pTBB->GetCmdID() == nIDFind )
return nBtnIdx;
}
return -1;
}
UINT CExtToolControlBar::GetButtonID(int nIndex) const
{
ASSERT_VALID(this);
CExtBarButton * pTBB =
_GetButtonPtr(nIndex);
if( pTBB == NULL )
return ID_SEPARATOR;
ASSERT_VALID( pTBB );
return pTBB->GetCmdID();
}
void CExtToolControlBar::GetButtonRect(int nIndex, LPRECT lpRect) const
{
ASSERT_VALID(this);
ASSERT(AfxIsValidAddress(lpRect, sizeof(RECT)));
CExtBarButton * pTBB =
_GetButtonPtr(nIndex);
if( pTBB == NULL )
{
::memset( lpRect, 0, sizeof(RECT) );
return;
}
ASSERT_VALID( pTBB );
*lpRect = *pTBB;
}
UINT CExtToolControlBar::GetButtonStyle(int nIndex) const
{
CExtBarButton * pTBB =
_GetButtonPtr(nIndex);
if( pTBB == NULL )
return 0;
ASSERT_VALID( pTBB );
return pTBB->GetStyle();
}
void CExtToolControlBar::SetButtonStyle(int nIndex, UINT nStyle)
{
CExtBarButton * pTBB =
_GetButtonPtr(nIndex);
if( pTBB == NULL )
return;
ASSERT_VALID( pTBB );
UINT nOldStyle = pTBB->GetStyle();
if( nOldStyle != nStyle )
{
pTBB->SetStyle( nStyle );
_InvalidateButton( nIndex );
UpdateWindow();
}
}
CWnd * CExtToolControlBar::GetButtonCtrl(
int nIndex
)
{
CExtBarButton * pTBB =
_GetButtonPtr(nIndex);
ASSERT( pTBB != NULL );
if( pTBB == NULL )
return NULL;
ASSERT_VALID( pTBB );
CWnd * pCtrl = pTBB->CtrlGet();
return pCtrl;
}
void CExtToolControlBar::SetButtonCtrlVisibleVertically(
int nIndex,
bool bVisible // = true
)
{
CExtBarButton * pTBB =
_GetButtonPtr(nIndex);
ASSERT( pTBB != NULL );
if( pTBB == NULL )
return;
pTBB->SetCtrlVisibleVertically( bVisible );
}
bool CExtToolControlBar::GetButtonCtrlVisibleVertically(
int nIndex
) const
{
CExtBarButton * pTBB =
_GetButtonPtr(nIndex);
ASSERT( pTBB != NULL );
if( pTBB == NULL )
return false;
return pTBB->GetCtrlVisibleVertically();
}
BOOL CExtToolControlBar::SetButtonCtrl(
int nIndex,
CWnd * pCtrl, // = NULL
BOOL bCtrlAutoDestroyed // = TRUE
)
{
CExtBarButton * pTBB =
_GetButtonPtr(nIndex);
ASSERT( pTBB != NULL );
if( pTBB == NULL )
return FALSE;
ASSERT_VALID( pTBB );
if( pCtrl != NULL )
{
ASSERT_VALID( pCtrl );
DWORD dwCtrlStyle = pCtrl->GetStyle();
ASSERT( (dwCtrlStyle&WS_CHILD) != 0 );
if( (dwCtrlStyle&WS_CHILD) == 0 )
return FALSE;
ASSERT( IsChild( pCtrl ) );
if( !IsChild( pCtrl ) )
return FALSE;
UINT nDlgCtrlID = (UINT)pCtrl->GetDlgCtrlID();
ASSERT( nDlgCtrlID == pTBB->GetCmdID() );
if( nDlgCtrlID != pTBB->GetCmdID() )
return FALSE;
}
pTBB->CtrlSet(
pCtrl,
bCtrlAutoDestroyed
);
_RecalcLayoutImpl();
return TRUE;
}
int CExtToolControlBar::GetButtonByAccessKey(TCHAR vkTCHAR)
{
int nCountOfButtons = _GetButtonsCountImpl();
ASSERT( nCountOfButtons >= 0 );
if( nCountOfButtons == 0 )
return -1;
for( int nBtnIdx=0; nBtnIdx<nCountOfButtons; nBtnIdx++ )
{
CExtBarButton * pTBB =
_GetButtonPtr(nBtnIdx);
ASSERT_VALID( pTBB );
if( pTBB->IsSeparator()
|| ( pTBB->GetStyle() & TBBS_HIDDEN )
|| pTBB->IsKindOf(RUNTIME_CLASS(CExtBarContentExpandButton))
)
continue;
UINT nCmdID = pTBB->GetCmdID();
ASSERT( CExtCmdManager::IsCommand(nCmdID) );
CExtCmdManager::cmd_t * p_cmd =
g_CmdManager->CmdGetPtr(
g_CmdManager->ProfileNameFromWnd( GetSafeHwnd() ),
nCmdID
);
ASSERT( p_cmd != NULL );
if( p_cmd->m_sToolbarText.IsEmpty() )
continue;
int nTextLen = p_cmd->m_sToolbarText.GetLength();
ASSERT( nTextLen > 0 );
int nAmdIndex = p_cmd->m_sToolbarText.Find(_T('&'));
if( nAmdIndex == nTextLen - 1 ) // !?!?!
continue;
TCHAR vk = p_cmd->m_sToolbarText[nAmdIndex+1];
//ASSERT( _istalnum(vk) );
// if( ! _istalnum(vk) )
// continue;
TCHAR szChar[2] = { vk, _T('\0') };
::CharUpper( szChar );
vk = szChar[0];
if( vkTCHAR == vk )
{
if( ( !pTBB->IsVisible() ) )
{
if( m_pRightBtn != NULL )
return _GetIndexOf( m_pRightBtn );
continue;
}
return nBtnIdx;
}
} // for( int nBtnIdx=0; nBtnIdx<nCountOfButtons; nBtnIdx++ )
return -1;
}
HMENU CExtToolControlBar::GetButtonMenu(
int nIndex
)
{
CExtBarButton * pTBB =
_GetButtonPtr(nIndex);
ASSERT( pTBB != NULL );
if( pTBB == NULL )
return NULL;
ASSERT_VALID( pTBB );
return ((HMENU)(*pTBB));
}
BOOL CExtToolControlBar::MarkButtonAsMdiWindowsMenu(
int nIndex,
BOOL bAppendMdiWindowsMenu // = TRUE
)
{
CExtBarButton * pTBB =
_GetButtonPtr(nIndex);
ASSERT( pTBB != NULL );
if( pTBB == NULL )
return FALSE;
ASSERT_VALID( pTBB );
pTBB->SetAppendMdiWindowsMenu(
bAppendMdiWindowsMenu
);
return TRUE;
}
BOOL CExtToolControlBar::SetButtonMenu(
int nIndex,
HMENU hMenu, // = NULL
BOOL bPopupMenu, // = TRUE
BOOL bAutoDestroyMenu, // = TRUE
BOOL bDoRecalcLayout // = TRUE
)
{
CExtBarButton * pTBB =
_GetButtonPtr(nIndex);
ASSERT( pTBB != NULL );
if( pTBB == NULL )
return FALSE;
ASSERT_VALID( pTBB );
pTBB->SetMenu(
hMenu,
bPopupMenu,
bAutoDestroyMenu
);
if( bDoRecalcLayout )
_RecalcLayoutImpl();
return TRUE;
}
int CExtToolControlBar::GetVisibleButton(
int nBtnIdx,
BOOL bNext,
BOOL bPassDisabled // = TRUE
)
{
int nCountOfButtons = _GetButtonsCountImpl();
ASSERT( nCountOfButtons >= 0 );
if( nCountOfButtons == 0 )
return -1;
if( nCountOfButtons == 1 )
return 0;
if( bNext )
{
int iNewButton = nBtnIdx + 1;
if( iNewButton >= nCountOfButtons )
iNewButton = 0;
while( iNewButton != nBtnIdx )
{
CExtBarButton * pTBB =
_GetButtonPtr(iNewButton);
ASSERT_VALID( pTBB );
if( pTBB->IsVisible()
&& ( pTBB->GetStyle() & TBBS_HIDDEN ) == 0
&& (!pTBB->IsSeparator())
&& (!pTBB->IsKindOf(RUNTIME_CLASS(CExtBarMdiRightButton)))
&& ( (!bPassDisabled)
|| (bPassDisabled && (!pTBB->IsDisabled()))
)
)
{
return iNewButton;
}
iNewButton++;
if( iNewButton >= nCountOfButtons )
iNewButton = 0;
}
return iNewButton;
} // if( bNext )
else
{
int iNewButton =
nBtnIdx - 1;
if( iNewButton < 0 )
iNewButton = nCountOfButtons - 1;
while( iNewButton != nBtnIdx )
{
CExtBarButton * pTBB =
_GetButtonPtr(iNewButton);
ASSERT_VALID( pTBB );
if( pTBB->IsVisible()
&& ( pTBB->GetStyle() & TBBS_HIDDEN ) == 0
&& (!pTBB->IsSeparator())
&& (!pTBB->IsKindOf(RUNTIME_CLASS(CExtBarMdiRightButton)))
&& ( (!bPassDisabled)
|| (bPassDisabled && (!pTBB->IsDisabled()))
)
)
return iNewButton;
iNewButton--;
if( iNewButton < 0 )
iNewButton = nCountOfButtons - 1;
}
return iNewButton;
} // else from if( bNext )
}
BOOL CExtToolControlBar::TrackButtonMenu(
int nIndex
)
{
if( g_bMenuTracking
&& m_nBtnIdxMenuTracking == nIndex
)
return TRUE;
if( !SafeDisplayBar() )
return false;
CExtBarButton * pTBB =
_GetButtonPtr(nIndex);
ASSERT( pTBB != NULL );
if( pTBB == NULL )
return FALSE;
ASSERT_VALID( pTBB );
if( pTBB->GetStyle() & (TBBS_HIDDEN|TBBS_DISABLED) )
return FALSE;
if( !pTBB->IsAbleToTrackMenu() )
return FALSE;
CPoint point;
VERIFY( ::GetCursorPos(&point) );
ScreenToClient( &point );
pTBB->OnTrackPopup(point);
return TRUE;
}
CSize CExtToolControlBar::CalcDynamicLayout(int nLength, DWORD dwMode)
{
if( (nLength == -1)
&& !(dwMode & (LM_MRUWIDTH|LM_COMMIT))
&& (dwMode & (LM_HORZDOCK|LM_VERTDOCK))
)
return
CalcFixedLayout(
dwMode & LM_STRETCH,
dwMode & LM_HORZDOCK
);
ASSERT(
(dwMode&(LM_HORZ|LM_HORZDOCK))
||
(!(dwMode&LM_HORZDOCK))
);
return _CalcLayout( dwMode, nLength );
}
CSize CExtToolControlBar::CalcFixedLayout(
BOOL bStretch,
BOOL bHorz
)
{
DWORD dwMode = bStretch ? LM_STRETCH : 0;
dwMode |= bHorz ? LM_HORZ : 0;
ASSERT(
(dwMode&(LM_HORZ|LM_HORZDOCK))
||
(!(dwMode&LM_HORZDOCK))
);
return _CalcLayout( dwMode );
}
CSize CExtToolControlBar::_CalcLayout(
DWORD dwMode,
int nLength
)
{
ASSERT_VALID(this);
CSize sizeCalcLayout = _GetDefButtonSize();
if( _GetButtonsCountImpl() > 0 )
{
if( m_pRightBtn != NULL )
m_pRightBtn->ClearContent( false );
BOOL bDynamic = m_dwStyle & CBRS_SIZE_DYNAMIC;
INT nLengthToSizeTB =
(dwMode & LM_HORZ) ? 32767 : 0;
BOOL bVertSizeTB = FALSE;
if( bDynamic )
{
if( dwMode & LM_MRUWIDTH )
nLengthToSizeTB = m_nMRUWidth;
else if( dwMode & LM_HORZDOCK )
nLengthToSizeTB = 32767;
else if( dwMode & LM_VERTDOCK )
nLengthToSizeTB = 0;
else if( nLength != -1 )
{
CRect rcInside( 0, 0, 0, 0 );
_CalcInsideRect(
rcInside,
(dwMode & LM_HORZ)
);
bVertSizeTB = (dwMode & LM_LENGTHY);
nLengthToSizeTB =
nLength +
( bVertSizeTB ?
rcInside.Height() : rcInside.Width()
);
}
else if( m_dwStyle & CBRS_FLOATING )
nLengthToSizeTB = m_nMRUWidth;
} // if( bDynamic )
_SizeToolBar( nLengthToSizeTB, bVertSizeTB );
sizeCalcLayout =
_CalcSize(
(dwMode & LM_HORZ) == 0
);
if( m_pRightBtn != NULL
&& m_pRightBtn->GetButtons().GetSize() == 0
)
{
m_pRightBtn->ClearContent();
sizeCalcLayout = _CalcSize( (dwMode & LM_HORZ) == 0 );
}
if( dwMode & LM_COMMIT )
if( m_dwStyle & (CBRS_FLOATING|CBRS_SIZE_DYNAMIC) )
if( dwMode & LM_HORZ )
m_nMRUWidth = sizeCalcLayout.cx;
CRect rcInside( 0, 0, 0, 0 );
_CalcInsideRect(
rcInside,
(dwMode & LM_HORZ)
);
sizeCalcLayout.cy -= rcInside.Height();
sizeCalcLayout.cx -= rcInside.Width();
CSize sizeCalcFixedLayout =
CControlBar::CalcFixedLayout(
dwMode & LM_STRETCH,
dwMode & LM_HORZ
);
sizeCalcLayout.cx =
max( sizeCalcLayout.cx, sizeCalcFixedLayout.cx );
sizeCalcLayout.cy =
max( sizeCalcLayout.cy, sizeCalcFixedLayout.cy );
if( IsFloating() && IsBarWithGripper() )
{
int nCyGripper = min( m_rcGrip.Width(), m_rcGrip.Height() );
sizeCalcLayout.cy += nCyGripper;
}
//_RecalcPositionsImpl();
} // if( _GetButtonsCountImpl() > 0 )
if( IsDockedHorizontally() )
{
m_sizeDockedH = sizeCalcLayout;
m_nMinHW = sizeCalcLayout.cy;
}
else if( IsDockedVertically() )
{
m_sizeDockedV = sizeCalcLayout;
m_nMinVH = sizeCalcLayout.cx;
}
else if( IsFloating() )
m_sizeFloated = sizeCalcLayout;
if( m_pDockSite == NULL )
{ // specific for dialog mode
if( IsDockedHorizontally() )
sizeCalcLayout.cy += 4;
else
sizeCalcLayout.cx += 4;
} // specific for dialog mode
return sizeCalcLayout;
}
CSize CExtToolControlBar::_CalcSize( BOOL bVerticallyDocked )
{
int nCountOfButtons = _GetButtonsCountImpl();
if( nCountOfButtons == 0 )
return _GetDefButtonSize();
CClientDC dc( this );
CFont* pOldFont = (CFont*)
dc.SelectObject(
bVerticallyDocked ?
&(g_PaintManager->m_FontNormalVert)
:
&(g_PaintManager->m_FontNormal)
);
ASSERT( pOldFont != NULL );
CSize sizeCalc( _GetDefButtonSize() );
CPoint ptCurrent( __TB_BUTTON_MARGINE__, __TB_BUTTON_MARGINE__ );
for( int nBtnIdx = 0; nBtnIdx < nCountOfButtons; nBtnIdx++ )
{
CExtBarButton * pTBB = _GetButtonPtr( nBtnIdx );
ASSERT_VALID( pTBB );
if( pTBB->GetStyle() & TBBS_HIDDEN )
continue;
if( nBtnIdx == (nCountOfButtons-1)
&& m_pRightBtn != NULL
&& IsFloating()
)
{
ASSERT_VALID( m_pRightBtn );
ASSERT( m_pRightBtn == pTBB );
break;
}
CSize sizeTBB(
pTBB->CalculateLayout(
dc,
_GetDefButtonSize(),
!bVerticallyDocked
)
);
if( (!bVerticallyDocked)
&& ( ptCurrent.x == __TB_BUTTON_MARGINE__
|| pTBB->IsWrap() )
&& pTBB->IsSeparator()
)
sizeTBB = CSize( 0, 0 );
sizeCalc.cx =
max(
ptCurrent.x + sizeTBB.cx,
sizeCalc.cx
);
sizeCalc.cy =
max(
ptCurrent.y + sizeTBB.cy,
sizeCalc.cy
);
if( bVerticallyDocked )
{
ptCurrent.x = __TB_BUTTON_MARGINE__;
ptCurrent.y += sizeTBB.cy;
} // if( bVerticallyDocked )
else
{
ptCurrent.x += sizeTBB.cx;
if( pTBB->IsWrap() )
{
ptCurrent.x = __TB_BUTTON_MARGINE__;
ptCurrent.y += _GetDefButtonSize().cy + __TB_LINE_OFFSET;
}
} // else from if( bVerticallyDocked )
} // for( int nBtnIdx = 0; nBtnIdx < nCountOfButtons; nBtnIdx++ )
dc.SelectObject( pOldFont );
if( bVerticallyDocked && sizeCalc.cx > __TB_LINE_OFFSET/2 )
sizeCalc.cx -= __TB_LINE_OFFSET/2;
if( (!bVerticallyDocked) && sizeCalc.cy > __TB_LINE_OFFSET/2 )
sizeCalc.cy -= __TB_LINE_OFFSET/2;
if( !bVerticallyDocked )
{
sizeCalc.cx += m_cxLeftBorder + m_cxRightBorder;
sizeCalc.cx += __TB_LINE_OFFSET/2;
}
else
{
sizeCalc.cy += m_cyTopBorder + m_cyBottomBorder;
sizeCalc.cy += __TB_LINE_OFFSET;
}
return sizeCalc;
}
void CExtToolControlBar::_SizeToolBar(int nLength, BOOL bVert)
{
int nCountOfButtons = _GetButtonsCountImpl();
if( nCountOfButtons == 0 )
return;
if( !IsFloating() )
{
_WrapToolBar(
bVert ? 32767 : nLength,
bVert ? nLength : 32767
);
return;
}
INT nMinExtent = _GetDefButtonSize().cx / 2;
ASSERT( nMinExtent > 0 );
if( bVert )
{
CSize size( 32767, 32767 );
for( INT nCalcExtent = nMinExtent;
nLength < size.cy;
nCalcExtent += nMinExtent
)
{
_WrapToolBar( nCalcExtent );
size = _CalcSize( FALSE );
}
_WrapToolBar( size.cx );
return;
}
INT nCountOfRowsDesired = _WrapToolBar( nLength );
INT nCountOfRowsCurrent = _WrapToolBar( nMinExtent );
if( nCountOfRowsCurrent == nCountOfRowsDesired
|| nMinExtent >= nLength
)
{
_WrapToolBar( _CalcSize(FALSE).cx );
return;
}
while( nMinExtent < nLength )
{
INT nCurrentExtent = (nMinExtent + nLength) / 2;
nCountOfRowsCurrent = _WrapToolBar( nCurrentExtent );
if( nCountOfRowsCurrent == nCountOfRowsDesired )
{
nLength = nCurrentExtent;
continue;
}
if( nMinExtent == nCurrentExtent )
{
_WrapToolBar( nLength );
break;
}
nMinExtent = nCurrentExtent;
}
_WrapToolBar( _CalcSize(FALSE).cx );
}
int CExtToolControlBar::_WrapToolBar(int nWidth, int nHeight /*= 32767*/)
{
bool bVerticallyDocked =
((m_dwStyle & CBRS_ORIENT_HORZ) == 0)
? true : false;
bool bFloating = IsFloating() ? true : false;
CClientDC dc( this );
CFont* pOldFont = (CFont*)
dc.SelectObject(
bVerticallyDocked ?
&(g_PaintManager->m_FontNormalVert)
:
&(g_PaintManager->m_FontNormal)
);
ASSERT( pOldFont != NULL );
CRect rcClient;
GetClientRect( &rcClient );
CPoint ptCurrent( 0, rcClient.top );
if( !bFloating
&& !bVerticallyDocked
&& m_pRightBtn != NULL
)
nWidth -=
m_pRightBtn->CalculateLayout(
dc, _GetDefButtonSize(), TRUE ).cx;
int nCountOfRows = 1;
int nCountOfButtons = _GetButtonsCountImpl();
CExtBarButton * pPrevButton = NULL;
for( int nBtnIdx = 0; nBtnIdx < nCountOfButtons; nBtnIdx++ )
{
CExtBarButton * pTBB = _GetButtonPtr( nBtnIdx );
ASSERT_VALID( pTBB );
pTBB->SetWrap( FALSE );
if( nBtnIdx == (nCountOfButtons-1)
&& m_pRightBtn != NULL
)
{
ASSERT_VALID( m_pRightBtn );
ASSERT( m_pRightBtn == pTBB );
break;
}
if( pTBB->GetStyle() & TBBS_HIDDEN )
continue;
CSize sizeTBB =
pTBB->CalculateLayout(
dc,
_GetDefButtonSize(),
!bVerticallyDocked
);
if( ptCurrent.x == 0 && pTBB->IsSeparator() )
sizeTBB = CSize(0, 0);
if( pPrevButton != NULL
&& (bFloating || ptCurrent.y + sizeTBB.cy < nHeight)
&& ptCurrent.x + sizeTBB.cx > nWidth
&& !pTBB->IsSeparator()
)
{
ASSERT_VALID( pPrevButton );
pPrevButton->SetWrap();
ptCurrent.x = 0;
ptCurrent.y += sizeTBB.cy + __TB_LINE_OFFSET;
nCountOfRows++;
}
ptCurrent.x += sizeTBB.cx;
pPrevButton = pTBB;
} // for( int nBtnIdx = 0; nBtnIdx < nCountOfButtons; nBtnIdx++ )
dc.SelectObject( pOldFont );
return nCountOfRows;
}
void CExtToolControlBar::GetButtonInfo(int nIndex, UINT& nID, UINT& nStyle) const
{
ASSERT_VALID(this);
CExtBarButton * pTBB =
_GetButtonPtr(nIndex);
if( pTBB == NULL )
{
ASSERT( FALSE );
nID = 0;
nStyle = 0;
return;
}
ASSERT_VALID( pTBB );
nID = pTBB->GetCmdID();
nStyle = pTBB->GetStyle();
}
void CExtToolControlBar::SetButtonInfo(int nIndex, UINT nID, UINT nStyle)
{
ASSERT_VALID(this);
CExtBarButton * pTBB =
_GetButtonPtr(nIndex);
if( pTBB == NULL )
{
ASSERT( FALSE );
return;
}
ASSERT_VALID( pTBB );
pTBB->SetCmdID( nID );
pTBB->SetStyle( nStyle );
_InvalidateButton(nIndex);
UpdateWindow();
}
void CExtToolControlBar::DoPaint(CDC* pDC)
{
ASSERT_VALID(this);
ASSERT_VALID(pDC);
CExtPaintManager::stat_ExcludeChildAreas(
*pDC,
*this
);
CRect rcClient;
GetClientRect( &rcClient );
CExtMemoryDC dc( pDC, &rcClient );
ASSERT( dc.GetSafeHdc() != NULL );
if( dc.GetSafeHdc() != NULL )
pDC = &dc;
pDC->FillSolidRect(
&rcClient,
g_PaintManager->GetColor(
CExtPaintManager::CLR_3DFACE_OUT
)
);
pDC->SetTextColor(
g_PaintManager->GetColor(CExtPaintManager::CLR_TEXT_OUT)
);
pDC->SetBkMode( TRANSPARENT );
CFont * pOldFont =
pDC->SelectObject(
( m_dwStyle & CBRS_ORIENT_HORZ )
? &g_PaintManager->m_FontNormal
: &g_PaintManager->m_FontNormalVert
);
ASSERT( pOldFont != NULL );
int nCountOfButtons = _GetButtonsCountImpl();
for( int nBtnIdx = 0; nBtnIdx < nCountOfButtons; nBtnIdx++ )
{
CExtBarButton * pTBB = _GetButtonPtr( nBtnIdx );
ASSERT_VALID( pTBB );
if( pTBB->GetStyle() & TBBS_HIDDEN )
continue;
if( !pTBB->IsVisible() )
continue;
CRect rcTBB = *pTBB;
if( !pDC->RectVisible( &rcTBB ) )
continue;
if( !pTBB->IsSeparator() )
{
pTBB->Paint(
*pDC,
( m_dwStyle & CBRS_ORIENT_HORZ ) ? true : false
);
continue;
}
bool bHorzSeparator =
( m_dwStyle & CBRS_ORIENT_HORZ ) ? true : false;
CRect rectSeparator( rcTBB );
if( pTBB->IsWrap() && ( m_dwStyle & CBRS_ORIENT_HORZ ) )
{
rectSeparator.left = rcClient.left;
rectSeparator.right = rcClient.right;
rectSeparator.top = rcTBB.bottom;
rectSeparator.bottom =
rectSeparator.top + __TB_LINE_OFFSET;
bHorzSeparator = false;
}
rectSeparator.DeflateRect(
bHorzSeparator ? 0 : 1,
bHorzSeparator ? 1 : 0
);
g_PaintManager->PaintSeparator(
*pDC, rectSeparator, bHorzSeparator
);
} // for( int nBtnIdx = 0; nBtnIdx < nCountOfButtons; nBtnIdx++ )
pDC->SelectObject( pOldFont );
}
void CExtToolControlBar::_InvalidateButton(int nIndex)
{
ASSERT_VALID(this);
CRect rect;
GetButtonRect(nIndex, &rect);
if( rect.IsRectEmpty() )
return;
InvalidateRect( &rect );
}
int CExtToolControlBar::OnToolHitTest(CPoint point, TOOLINFO* pTI) const
{
ASSERT_VALID( this );
if( CExtToolControlBar::g_bMenuTracking
|| CExtPopupMenuWnd::IsMenuTracking()
)
return -1;
int nToolTipHit =
CExtControlBar::OnToolHitTest(
point,
pTI
);
if( nToolTipHit != -1 )
return nToolTipHit;
nToolTipHit =
((CExtToolControlBar*)this)->
HitTest(point);
if( nToolTipHit < 0 )
return -1;
CExtBarButton * pTBB =
_GetButtonPtr( nToolTipHit );
ASSERT_VALID( pTBB );
if( pTBB == NULL )
return -1;
nToolTipHit = pTBB->OnToolHitTest( point, pTI );
return nToolTipHit;
}
int CExtToolControlBar::_HitTestImpl(
CPoint point,
UINT nButtonStyleInclude, // = 0, // button must have style
UINT nButtonStyleExclude // = 0 // button must have not style
) const
{
int nCountOfButtons = _GetButtonsCountImpl();
for( int nBtnIdx = 0; nBtnIdx < nCountOfButtons; nBtnIdx++ )
{
CExtBarButton * pTBB =
_GetButtonPtr(nBtnIdx);
ASSERT_VALID( pTBB );
if( pTBB->GetStyle() & TBBS_HIDDEN )
continue;
if( !(pTBB->IsVisible()) )
continue;
if( (pTBB->GetStyle() & nButtonStyleInclude)
!= nButtonStyleInclude
)
continue;
if( (pTBB->GetStyle() & nButtonStyleExclude)
!= 0
)
continue;
CRect rect = *pTBB;
if( rect.PtInRect(point) )
return nBtnIdx;
}
return -1; // nowhere
}
int CExtToolControlBar::HitTest(
CPoint point // in window relative coords
) const
{
return
_HitTestImpl(
point,
0,
TBBS_SEPARATOR
);
}
/////////////////////////////////////////////////////////////////////////////
// CExtToolControlBar message handlers
BEGIN_MESSAGE_MAP(CExtToolControlBar, CExtControlBar)
//{{AFX_MSG_MAP(CExtToolControlBar)
ON_WM_LBUTTONDOWN()
ON_WM_MOUSEMOVE()
ON_WM_LBUTTONUP()
ON_WM_LBUTTONDBLCLK()
ON_WM_CANCELMODE()
ON_WM_SETTINGCHANGE()
ON_WM_SIZE()
ON_WM_WINDOWPOSCHANGING()
ON_WM_TIMER()
ON_WM_CAPTURECHANGED()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
void CExtToolControlBar::OnLButtonDown(UINT nFlags, CPoint point)
{
if( m_bRowResizing || m_bRowRecalcing || m_bDragging )
{
CExtControlBar::OnLButtonDown(nFlags, point);
return;
}
_ActivateOnClick();
if( (m_nBtnIdxCapture = HitTest(point)) < 0 ) // nothing hit
{
CExtControlBar::OnLButtonDown(nFlags, point);
return;
}
CExtBarButton* pTBB =
_GetButtonPtr(m_nBtnIdxCapture);
ASSERT_VALID( pTBB );
ASSERT( !(pTBB->IsSeparator()) );
// update the button before checking for disabled status
_UpdateButton(m_nBtnIdxCapture);
if( pTBB->IsDisabled()
|| m_nBtnIdxMenuTracking == m_nBtnIdxCapture
)
{
m_nBtnIdxCapture = -1;
return; // don't press it
}
pTBB->ModifyStyle( TBBS_PRESSED );
_InvalidateButton( m_nBtnIdxCapture );
UpdateWindow(); // immediate feedback
CWnd * pCtrlTBB = pTBB->CtrlGet();
pTBB->OnClick( point, true );
if( !g_bMenuTracking )
{
if( pCtrlTBB == NULL
|| (pCtrlTBB->GetStyle() & WS_VISIBLE) == 0
)
SetCapture();
else
m_nBtnIdxCapture = -1;
}
else
m_nBtnIdxCapture = -1;
}
void CExtToolControlBar::OnMouseMove(UINT nFlags, CPoint point)
{
if( CExtPopupMenuWnd::IsMenuTracking()
&& !CExtToolControlBar::g_bMenuTracking
)
return;
if( IsFloating() &&
CExtMiniDockFrameWnd::g_bAutoMakeTopmostOnMouseEvent
)
{
CFrameWnd * pParentFrame = GetParentFrame();
if( pParentFrame != NULL )
pParentFrame->BringWindowToTop();
}
if( m_bRowResizing || m_bRowRecalcing || m_bDragging )
{
CExtControlBar::OnMouseMove(nFlags, point);
return;
}
if( m_nBtnIdxCapture >= 0 )
{
CExtBarButton* pTBB =
_GetButtonPtr(m_nBtnIdxCapture);
ASSERT_VALID( pTBB );
ASSERT(!(pTBB->IsSeparator()));
UINT nNewStyle = (pTBB->GetStyle() & ~TBBS_PRESSED);
int nBtnIdxCapture = m_nBtnIdxCapture;
if( GetCapture() != this )
{
m_nBtnIdxCapture = -1; // lost capture
}
else
{
// should be pressed if still hitting the captured button
if( HitTest(point) == m_nBtnIdxCapture )
nNewStyle |= TBBS_PRESSED;
}
SetButtonStyle(nBtnIdxCapture, nNewStyle);
UpdateWindow(); // immediate feedback
return;
} // if( m_nBtnIdxCapture >= 0 )
bool bHoverChanged =
_UpdateHoverButton( point );
if( GetCapture() == this
&& m_nBtnIdxHover < 0
&& m_nBtnIdxMenuTracking < 0
&& m_nBtnIdxCapture < 0
)
{
CPoint ptScreen;
VERIFY( ::GetCursorPos(&ptScreen) );
HWND hWnd = ::WindowFromPoint(ptScreen);
if( hWnd != m_hWnd )
ReleaseCapture();
}
if( bHoverChanged )
return;
CExtControlBar::OnMouseMove(nFlags,point);
}
bool CExtToolControlBar::_UpdateHoverButton(
CPoint point // = CPoint(-1,-1) // default is use ::GetCursorPos()
)
{
if( point.x < 0 || point.y < 0 )
{
VERIFY( ::GetCursorPos(&point) );
ScreenToClient( &point );
}
bool bHoverChanged = false;
int nBtnIdxHoverNew = HitTest(point);
int nBtnIdxHoverOld = m_nBtnIdxHover;
if( nBtnIdxHoverOld != nBtnIdxHoverNew )
{
bHoverChanged = true;
m_nBtnIdxHover = -1;
if( nBtnIdxHoverOld >= 0 )
{
CExtBarButton * pTBB =
_GetButtonPtr(nBtnIdxHoverOld);
ASSERT_VALID( pTBB );
pTBB->SetHover( FALSE );
_InvalidateButton( nBtnIdxHoverOld );
UpdateWindow();
pTBB->OnHover( point, false );
}
m_nBtnIdxHover = nBtnIdxHoverNew;
if( m_nBtnIdxHover >= 0 )
{
CExtBarButton * pTBB =
_GetButtonPtr(m_nBtnIdxHover);
ASSERT_VALID( pTBB );
bool bEnableHoverOnNewBtn = true;
if( pTBB->IsKindOf(RUNTIME_CLASS(CExtBarMdiRightButton))
|| pTBB->IsDisabled()
)
{
if( g_bMenuTracking )
bEnableHoverOnNewBtn = false;
}
if( bEnableHoverOnNewBtn )
{
pTBB->SetHover();
_InvalidateButton( m_nBtnIdxHover );
UpdateWindow();
pTBB->OnHover( point, true );
}
}
} // if( nBtnIdxHoverOld != nBtnIdxHoverNew )
return bHoverChanged;
}
void CExtToolControlBar::OnLButtonUp(UINT nFlags, CPoint point)
{
if( (m_nBtnIdxCapture < 0 && m_nBtnIdxHover < 0)
|| m_bRowResizing || m_bRowRecalcing || m_bDragging )
{
CExtControlBar::OnLButtonUp(nFlags, point);
return; // not captured
}
int nBtnIdxHover = m_nBtnIdxHover;
int nBtnIdxCapture = m_nBtnIdxCapture;
CExtBarButton * pHoverTBB = NULL;
if( m_nBtnIdxHover >= 0 )
{
pHoverTBB =
_GetButtonPtr( m_nBtnIdxHover );
ASSERT_VALID( pHoverTBB );
m_nBtnIdxHover = -1;
} // if( m_nBtnIdxHover >= 0 )
if( m_nBtnIdxCapture >= 0 )
{
m_nBtnIdxCapture = -1;
CExtBarButton * pCaptureTBB = NULL;
UINT nNewStyle = 0;
if( nBtnIdxCapture == HitTest(point) )
{
pCaptureTBB = _GetButtonPtr( nBtnIdxCapture );
ASSERT_VALID( pCaptureTBB );
ASSERT( !(pCaptureTBB->IsSeparator()) );
nNewStyle = ( pCaptureTBB->GetStyle() & ~TBBS_PRESSED );
// give button a chance to update
_UpdateButton( nBtnIdxCapture );
// then check for disabled state
if( !(pCaptureTBB->IsDisabled()) )
{
if( pCaptureTBB->GetStyle() & TBBS_CHECKBOX )
{
// auto check: three state => down
if( nNewStyle & TBBS_INDETERMINATE )
nNewStyle &= ~TBBS_INDETERMINATE;
nNewStyle ^= TBBS_CHECKED;
}
} // if( !(pCaptureTBB->IsDisabled()) )
} // if( nBtnIdxCapture == HitTest(point) )
ReleaseCapture();
if( pCaptureTBB != NULL )
pCaptureTBB->OnClick( point, false );
if( !(::IsWindow(GetSafeHwnd())) )
return;
if( !g_bMenuTracking )
{
SetButtonStyle( nBtnIdxCapture, nNewStyle );
_UpdateButton( nBtnIdxCapture );
} // if( bUpdateBtnState )
} // if( m_nBtnIdxCapture >= 0 )
if( pHoverTBB != NULL )
{
ASSERT_VALID( pHoverTBB );
pHoverTBB->SetHover( FALSE );
pHoverTBB->OnHover( point, false );
_InvalidateButton( nBtnIdxHover );
} // if( pHoverTBB != NULL )
UpdateWindow(); // immediate feedback
}
void CExtToolControlBar::OnLButtonDblClk(UINT nFlags, CPoint point)
{
if( m_bRowResizing || m_bRowRecalcing || m_bDragging )
{
CExtControlBar::OnLButtonDblClk(nFlags, point);
return;
}
int nBtnIdx = _HitTestImpl(point);
if( nBtnIdx >= 0 )
return;
CExtControlBar::OnLButtonDblClk(nFlags,point);
}
void CExtToolControlBar::OnCancelMode()
{
CExtControlBar::OnCancelMode();
// ASSERT( !CExtPopupMenuWnd::IsMenuTracking() );
bool bUpdateState = false;
if( m_nBtnIdxCapture >= 0 )
{
CExtBarButton* pTBB =
_GetButtonPtr(m_nBtnIdxCapture);
ASSERT_VALID( pTBB );
ASSERT( !(pTBB->IsSeparator()) );
if( m_nBtnIdxMenuTracking != m_nBtnIdxCapture )
{
UINT nNewStyle = (pTBB->GetStyle() & ~TBBS_PRESSED);
SetButtonStyle(m_nBtnIdxCapture, nNewStyle);
}
m_nBtnIdxCapture = -1;
bUpdateState = true;
}
if( m_nBtnIdxHover >= 0 )
{
CExtBarButton * pTBB =
_GetButtonPtr(m_nBtnIdxHover);
ASSERT_VALID( pTBB );
pTBB->SetHover( FALSE );
m_nBtnIdxHover = -1;
bUpdateState = true;
CPoint point;
VERIFY( ::GetCursorPos(&point) );
ScreenToClient( &point );
pTBB->OnHover( point, false );
}
if( bUpdateState )
{
if( GetCapture() == this )
ReleaseCapture();
Invalidate();
UpdateWindow();
}
}
void CExtToolControlBar::OnSettingChange(UINT uFlags, LPCTSTR lpszSection)
{
CExtControlBar::OnSettingChange(uFlags,lpszSection);
if( m_bPresubclassDialogMode )
{
_RecalcLayoutImpl();
return;
}
// _RecalcLayoutImpl();
CFrameWnd* pFrame = GetParentFrame();
ASSERT_VALID(pFrame);
// pFrame->RecalcLayout();
pFrame->DelayRecalcLayout();
}
bool CExtToolControlBar::IsRightExpandButton( int nBtnIdx )
{
CExtBarButton * pTBB =
_GetButtonPtr( nBtnIdx );
if( pTBB == NULL )
return false;
ASSERT_VALID( pTBB );
if( pTBB->IsKindOf(RUNTIME_CLASS(CExtBarContentExpandButton)) )
return true;
return false;
}
class CExtToolControlBar::CExtToolControlBarCmdUI : public CCmdUI
{
void _SetCheckImpl(
int nCheck,
bool bUpdaeteInCmdManager
);
public: // re-implementations only
virtual void Enable(BOOL bOn);
virtual void SetRadio(BOOL bOn);
virtual void SetCheck(int nCheck)
{
_SetCheckImpl(nCheck,true);
};
virtual void SetText(LPCTSTR lpszText)
{
lpszText;
// ignore it
};
}; // class CExtToolControlBar::CExtToolControlBarCmdUI
void CExtToolControlBar::CExtToolControlBarCmdUI::_SetCheckImpl(
int nCheck,
bool bUpdaeteInCmdManager
)
{
ASSERT(nCheck >= 0 && nCheck <= 2); // 0=>off, 1=>on, 2=>indeterminate
CExtToolControlBar* pToolBar = (CExtToolControlBar*)m_pOther;
ASSERT(pToolBar != NULL);
ASSERT_KINDOF(CExtToolControlBar, pToolBar);
ASSERT(m_nIndex < m_nIndexMax);
if( pToolBar->IsRightExpandButton(m_nIndex) )
return;
UINT nNewStyle =
pToolBar->GetButtonStyle(m_nIndex)
&
~(TBBS_CHECKED | TBBS_INDETERMINATE);
if( nCheck == 1 )
nNewStyle |= TBBS_CHECKED;
else if( nCheck == 2 )
nNewStyle |= TBBS_INDETERMINATE;
ASSERT( !(nNewStyle & TBBS_SEPARATOR) );
pToolBar->SetButtonStyle(m_nIndex, nNewStyle | TBBS_CHECKBOX);
if( bUpdaeteInCmdManager )
{
CExtCmdManager::cmd_t * p_cmd = g_CmdManager->CmdGetPtr(
g_CmdManager->ProfileNameFromWnd( pToolBar->GetSafeHwnd() ),
pToolBar->GetButtonID(m_nIndex)
);
if( p_cmd != NULL )
{
p_cmd->StateSetCheck(
(nNewStyle &
(TBBS_CHECKED|TBBS_INDETERMINATE)
) ? true : false
);
}
}
}
void CExtToolControlBar::CExtToolControlBarCmdUI::Enable(BOOL bOn)
{
m_bEnableChanged = TRUE;
CExtToolControlBar* pToolBar = (CExtToolControlBar*)m_pOther;
ASSERT(pToolBar != NULL);
ASSERT_KINDOF(CExtToolControlBar, pToolBar);
ASSERT(m_nIndex < m_nIndexMax);
if( pToolBar->IsRightExpandButton(m_nIndex) )
return;
UINT nNewStyle = pToolBar->GetButtonStyle(m_nIndex) & ~TBBS_DISABLED;
if( !bOn )
nNewStyle |= TBBS_DISABLED;
ASSERT(!(nNewStyle & TBBS_SEPARATOR));
pToolBar->SetButtonStyle(m_nIndex, nNewStyle);
CExtCmdManager::cmd_t * p_cmd = g_CmdManager->CmdGetPtr(
g_CmdManager->ProfileNameFromWnd( pToolBar->GetSafeHwnd() ),
pToolBar->GetButtonID(m_nIndex)
);
if( p_cmd != NULL )
p_cmd->StateEnable( bOn ? true : false );
}
void CExtToolControlBar::CExtToolControlBarCmdUI::SetRadio(BOOL bOn)
{
_SetCheckImpl( bOn ? 1 : 0, false );
CExtToolControlBar* pToolBar = (CExtToolControlBar*)m_pOther;
ASSERT(pToolBar != NULL);
ASSERT_KINDOF(CExtToolControlBar, pToolBar);
ASSERT(m_nIndex < m_nIndexMax);
if( pToolBar->IsRightExpandButton(m_nIndex) )
return;
CExtCmdManager::cmd_t * p_cmd = g_CmdManager->CmdGetPtr(
g_CmdManager->ProfileNameFromWnd( pToolBar->GetSafeHwnd() ),
pToolBar->GetButtonID(m_nIndex)
);
if( p_cmd != NULL )
p_cmd->StateSetRadio( bOn ? true : false );
}
void CExtToolControlBar::OnUpdateCmdUI(CFrameWnd* pTarget, BOOL bDisableIfNoHndler)
{
CWnd * pTargetUpdateWnd = pTarget;
if( !m_bPresubclassDialogMode )
{
CExtControlBar::OnUpdateCmdUI(pTarget, bDisableIfNoHndler);
//if( CExtPopupMenuWnd::IsMenuTracking() )
// return;
if( _DraggingGetBar() != NULL )
return;
} // if( !m_bPresubclassDialogMode )
else
{
if( pTargetUpdateWnd != NULL
&& pTargetUpdateWnd->IsKindOf( RUNTIME_CLASS(CFrameWnd) )
)
return;
//ASSERT( pTargetUpdateWnd == NULL );
// if( pTargetUpdateWnd == NULL )
pTargetUpdateWnd = GetOwner();
if( pTargetUpdateWnd == NULL )
pTargetUpdateWnd = GetParent();
ASSERT( pTargetUpdateWnd != NULL );
}
if( pTargetUpdateWnd == NULL )
return;
ASSERT_VALID( pTargetUpdateWnd );
if( (GetStyle() & WS_VISIBLE) == 0 )
return;
CExtToolControlBarCmdUI state;
state.m_pOther = this;
int nCountOfButtons = _GetButtonsCountImpl();
state.m_nIndexMax = (UINT)nCountOfButtons;
for( state.m_nIndex = 0;
state.m_nIndex < state.m_nIndexMax;
state.m_nIndex++
)
{
CExtBarButton * pTBB =
_GetButtonPtr(state.m_nIndex);
ASSERT_VALID( pTBB );
if( pTBB->IsAbleToTrackMenu() ) // ignore menu drop buttons
continue;
state.m_nID = pTBB->GetCmdID();
if( pTBB->IsSeparator() ) // ignore separators
continue;
state.DoUpdate(pTargetUpdateWnd, bDisableIfNoHndler);
}
// update the dialog controls added to the toolbar
UpdateDialogControls(pTargetUpdateWnd, bDisableIfNoHndler);
}
void CExtToolControlBar::_UpdateButton(int nIndex)
{
// determine target of command update
//CFrameWnd * pTarget = (CFrameWnd*)GetOwner();
// if( pTarget == NULL || !pTarget->IsFrameWnd() )
// pTarget = GetParentFrame();
CWnd * pTarget = GetOwner();
if( pTarget == NULL && (!m_bPresubclassDialogMode) )
pTarget = GetParentFrame();
if( pTarget == NULL )
return;
BOOL bDisableIfNoHandler = TRUE;
if( pTarget->IsKindOf( RUNTIME_CLASS(CFrameWnd) ) )
bDisableIfNoHandler = ((CFrameWnd *)pTarget)->m_bAutoMenuEnable;
CExtBarButton * pTBB =
_GetButtonPtr(nIndex);
ASSERT_VALID( pTBB );
if( pTBB->IsSeparator() )
return;
if( pTBB->IsAbleToTrackMenu() )
return;
// send the update notification
CExtToolControlBarCmdUI state;
state.m_pOther = this;
state.m_nIndex = nIndex;
int nCountOfButtons = _GetButtonsCountImpl();
state.m_nIndexMax = (UINT)nCountOfButtons;
state.m_nID = pTBB->GetCmdID();
state.DoUpdate( pTarget, bDisableIfNoHandler );
}
/////////////////////////////////////////////////////////////////////////////
// CExtToolControlBar diagnostics
#ifdef _DEBUG
void CExtToolControlBar::AssertValid() const
{
CExtControlBar::AssertValid();
}
void CExtToolControlBar::Dump(CDumpContext& dc) const
{
CExtControlBar::Dump(dc);
}
#endif
// input CRect should be client rectangle size
void CExtToolControlBar::_CalcInsideRect(CRect& rect, BOOL bHorz) const
{
ASSERT_VALID(this);
CControlBar::CalcInsideRect(rect,bHorz);
}
void CExtToolControlBar::_RecalcPositionsImpl()
{
if( GetSafeHwnd() == NULL
|| !::IsWindow( GetSafeHwnd() )
)
return;
ASSERT_VALID(this);
int nCountOfButtons = _GetButtonsCountImpl();
if( nCountOfButtons == 0 )
return;
BOOL bHorz = (m_dwStyle & CBRS_ORIENT_HORZ) ? TRUE : FALSE;
BOOL bFloating = IsFloating();
CRect rcInner;
GetClientRect( &rcInner );
//rcInner.DeflateRect( __TB_BUTTON_MARGINE__, __TB_BUTTON_MARGINE__ );
rcInner.DeflateRect(
m_cxLeftBorder,
m_cyTopBorder,
m_cxRightBorder,
m_cyBottomBorder
);
CPoint ptLimitTL = rcInner.TopLeft();
CPoint ptLimitBR = rcInner.BottomRight();
CClientDC dc(this);
CFont* pOldFont = (CFont*)
dc.SelectObject(
bHorz
? &g_PaintManager->m_FontNormal
: &g_PaintManager->m_FontNormalVert
);
ASSERT( pOldFont != NULL );
int nReviewCount = nCountOfButtons;
CSize sizeTBBRight( 0, 0 );
if( m_pRightBtn != NULL )
{
nReviewCount--;
ASSERT_VALID( m_pRightBtn );
ASSERT( m_buttons.GetSize() > 0 );
ASSERT( m_buttons[nReviewCount] == m_pRightBtn );
m_pRightBtn->GetButtons().RemoveAll();
m_pRightBtn->ClearContent();
sizeTBBRight =
m_pRightBtn->CalculateLayout( dc, _GetDefButtonSize(), bHorz );
if( bFloating )
{
m_pRightBtn->Show( FALSE );
m_pRightBtn->SetRect(
CRect( ptLimitTL, sizeTBBRight )
);
if( nReviewCount == 0 )
return;
} // if( bFloating )
else
{
m_pRightBtn->SetRect(
CRect(
ptLimitBR-sizeTBBRight,
sizeTBBRight
)
);
m_pRightBtn->Show( TRUE );
if( bHorz )
rcInner.right -=
sizeTBBRight.cx + __TB_BUTTON_MARGINE__;
else
rcInner.bottom -=
sizeTBBRight.cy + __TB_BUTTON_MARGINE__;
} // else from if( bFloating )
} // if( m_pRightBtn != NULL )
CArray < CRect, CRect > arrBtnRects;
CArray < BOOL, BOOL > arrBtnVisibility;
CArray < BOOL, BOOL > arrBtnSeparators;
//CArray < BOOL, BOOL > arrBtnEnabled;
arrBtnRects.SetSize( nReviewCount );
arrBtnVisibility.SetSize( nReviewCount );
arrBtnSeparators.SetSize( nReviewCount );
// arrBtnEnabled.SetSize( nReviewCount );
CSize sizeLastWrappedRow( 0, 0 );
CPoint ptBtnPosCurr( ptLimitTL );
BOOL bSeparatorPrev = FALSE;
for( int nBtnIdx = 0; nBtnIdx < nReviewCount; nBtnIdx++ )
{
CExtBarButton * pTBB = _GetButtonPtr( nBtnIdx );
ASSERT_VALID( pTBB );
BOOL bVisibleTBB =
( pTBB->GetStyle() & TBBS_HIDDEN ) ? FALSE : TRUE;
arrBtnVisibility.SetAt( nBtnIdx, bVisibleTBB );
if( !bVisibleTBB )
continue;
pTBB->SetVertDocked( !bHorz );
// arrBtnEnabled.SetAt( nBtnIdx, pTBB->IsEnabled() );
BOOL bSeparator = pTBB->IsSeparator();
arrBtnSeparators.SetAt( nBtnIdx, bSeparator );
if( (bSeparatorPrev && bSeparator) || (bSeparator && nBtnIdx == 0) )
{ // remove double separators
arrBtnVisibility.SetAt( nBtnIdx, FALSE );
continue;
} // remove double separators
CSize sizeTBB =
pTBB->CalculateLayout( dc, _GetDefButtonSize(), bHorz );
CRect rcTBB( ptBtnPosCurr, sizeTBB );
if( bFloating && pTBB->IsWrap() )
{
ptBtnPosCurr.x = ptLimitTL.x;
ptBtnPosCurr.y += _GetDefButtonSize().cy + __TB_LINE_OFFSET;
sizeLastWrappedRow = CSize( 0, 0 );
} // if( bFloating && pTBB->IsWrap() )
else
{
bool bResyncVisibleTBB = false;
if( bHorz )
{
ptBtnPosCurr.x += sizeTBB.cx;
if( ptBtnPosCurr.x > rcInner.right )
bResyncVisibleTBB = true;
} // if( bHorz )
else
{
ptBtnPosCurr.y += sizeTBB.cy;
if( ptBtnPosCurr.y > rcInner.bottom )
bResyncVisibleTBB = true;
} // else from if( bHorz )
if( bResyncVisibleTBB )
{
int nSpaceToFind =
bHorz
? ptBtnPosCurr.x - rcInner.right
: ptBtnPosCurr.y - rcInner.bottom;
int nBtnWithNearestWidth = nBtnIdx;
int nNearestMetric = bHorz ? rcTBB.Width() : rcTBB.Height();
int nNearestDiff = nSpaceToFind - nNearestMetric;
// hide nearest by size reviewed visible
for( int nBtnIdx2 = nBtnIdx-1; nBtnIdx2 >= 0; nBtnIdx2-- )
{
if( !arrBtnVisibility[nBtnIdx2] )
continue;
if( arrBtnSeparators[nBtnIdx2] )
continue;
#ifdef _DEBUG
CExtBarButton * pTBB2 =
_GetButtonPtr( nBtnIdx2 );
ASSERT( (pTBB2->GetStyle() & TBBS_HIDDEN) == 0 );
#endif // _DEBUG
int nMetric =
bHorz
? arrBtnRects[nBtnIdx2].Width()
: arrBtnRects[nBtnIdx2].Height();
//if( nMetric <= nNearestMetric ) // <<-- widest search algorithm
// continue;
if( nMetric > nSpaceToFind )
continue;
int nDiff = nSpaceToFind - nMetric;
// if( !arrBtnEnabled[nBtnIdx2] )
// { // hide disabled buttons first
// nNearestDiff = nDiff;
// nNearestMetric = nMetric;
// nBtnWithNearestWidth = nBtnIdx2;
// break;
// } // hide disabled buttons first
if( nDiff >= nNearestDiff )
continue;
nNearestDiff = nDiff;
nNearestMetric = nMetric;
nBtnWithNearestWidth = nBtnIdx2;
} // for( int nBtnIdx2 = nBtnIdx-1; nBtnIdx2 >= 0; nBtnIdx2-- )
if( nBtnWithNearestWidth < nBtnIdx )
{
ASSERT( bVisibleTBB );
arrBtnVisibility.SetAt( nBtnWithNearestWidth, FALSE );
if( m_pRightBtn!=NULL && !arrBtnSeparators[nBtnWithNearestWidth] )
{
CExtBarButton * pTBB2 =
_GetButtonPtr( nBtnWithNearestWidth );
ASSERT_VALID( pTBB2 );
m_pRightBtn->GetButtons().Add( pTBB2 );
}
if( nBtnWithNearestWidth > 0 && nBtnWithNearestWidth < nReviewCount-1 )
{ // remove double separators
if( arrBtnSeparators[nBtnWithNearestWidth-1]
&& arrBtnSeparators[nBtnWithNearestWidth+1]
)
{
arrBtnVisibility.SetAt( nBtnWithNearestWidth-1, FALSE );
nNearestMetric +=
bHorz
? arrBtnRects[nBtnWithNearestWidth-1].Width()
: arrBtnRects[nBtnWithNearestWidth-1].Height();
}
} // remove double separators
rcTBB.OffsetRect(
bHorz ? -nNearestMetric : 0,
bHorz ? 0 : -nNearestMetric
);
(bHorz ? ptBtnPosCurr.x : ptBtnPosCurr.y) -= nNearestMetric;
for( nBtnIdx2 = nBtnWithNearestWidth+1; nBtnIdx2 < nBtnIdx; nBtnIdx2++ )
{
if( !arrBtnVisibility[nBtnIdx2] )
continue;
CRect rcTBB2 = arrBtnRects[nBtnIdx2];
rcTBB2.OffsetRect(
bHorz ? -nNearestMetric : 0,
bHorz ? 0 : -nNearestMetric
);
arrBtnRects.SetAt( nBtnIdx2, rcTBB2 );
} // for( nBtnIdx2 = nBtnWithNearestWidth+1; nBtnIdx2 < nBtnIdx; nBtnIdx2++ )
} // if( nBtnWithNearestWidth < nBtnIdx )
else
{
ASSERT( nBtnWithNearestWidth == nBtnIdx );
bVisibleTBB = FALSE;
(bHorz ? ptBtnPosCurr.x : ptBtnPosCurr.y) -=
(bHorz ? sizeTBB.cx : sizeTBB.cy);
} // else from if( nBtnWithNearestWidth < nBtnIdx )
} // if( bResyncVisibleTBB )
} // else from if( bFloating && pTBB->IsWrap() )
arrBtnVisibility.SetAt( nBtnIdx, bVisibleTBB );
arrBtnRects.SetAt( nBtnIdx, rcTBB );
if( bVisibleTBB )
bSeparatorPrev = bSeparator;
if( m_pRightBtn!=NULL && !bVisibleTBB && !bSeparator )
m_pRightBtn->GetButtons().Add( pTBB );
} // for( int nBtnIdx = 0; nBtnIdx < nReviewCount; nBtnIdx++ )
dc.SelectObject( pOldFont );
INT nRowStart = 0;
INT nSizeRow = 0;
for( nBtnIdx = 0; nBtnIdx < nReviewCount; nBtnIdx++ )
{
CExtBarButton * pTBB = _GetButtonPtr( nBtnIdx );
ASSERT_VALID( pTBB );
//BOOL bVis = arrBtnVisibility[nBtnIdx];
//if( bVis )
//{
CSize sizeTBB = *pTBB; // arrBtnRects[nBtnIdx].Size();
INT nSizeBtn =
(bHorz || bFloating)
? sizeTBB.cy : sizeTBB.cx;
nSizeRow = max( nSizeRow, nSizeBtn );
//} // if( bVis )
if( ( bFloating && pTBB->IsWrap() )
|| nBtnIdx == nReviewCount-1
)
{
for( INT nBtnIdx2 = nRowStart; nBtnIdx2 <= nBtnIdx; nBtnIdx2++ )
{
CExtBarButton * pTBB = _GetButtonPtr( nBtnIdx2 );
ASSERT_VALID( pTBB );
BOOL bVis = arrBtnVisibility[nBtnIdx2];
pTBB->Show( bVis );
if( !bVis )
continue;
CRect rcBtn = arrBtnRects[nBtnIdx2];
if( pTBB->IsSeparator() )
{
if( (bHorz || bFloating) )
rcBtn.bottom = rcBtn.top + nSizeRow;
else
rcBtn.right = rcBtn.left + nSizeRow;
}
else
rcBtn.OffsetRect(
(bHorz || bFloating)
? 0
: ( ( nSizeRow - rcBtn.Width() ) / 2 )
,
(bHorz || bFloating)
? ( ( nSizeRow - rcBtn.Height() ) / 2 )
: 0
);
pTBB->SetRect( rcBtn );
}
nRowStart = nBtnIdx+1;
nSizeRow = 0;
}
} // for( nBtnIdx = 0; nBtnIdx < nReviewCount; nBtnIdx++ )
if( m_pRightBtn != NULL && m_bPresubclassDialogMode )
{
if( m_pRightBtn->GetButtons().GetSize() == 0 )
m_pRightBtn->ModifyStyle( TBBS_DISABLED, 0 );
else
m_pRightBtn->ModifyStyle( 0, TBBS_DISABLED );
}
// insert separators into right button
if( bFloating
|| m_pRightBtn == NULL
|| ( m_pRightBtn != NULL
&& m_pRightBtn->GetButtons().GetSize() == 0
)
)
{
return;
}
int nHiddenCount = m_pRightBtn->GetButtons().GetSize();
if( nHiddenCount < 2 )
return;
int nEndMeasure = nHiddenCount-1;
for( int iHidden = 0; iHidden < nEndMeasure; iHidden++ )
{
CExtBarButton * pTbbHidden0 =
m_pRightBtn->GetButtons().GetAt(iHidden);
ASSERT( pTbbHidden0 != NULL );
ASSERT( ! pTbbHidden0->IsSeparator() );
ASSERT( ! pTbbHidden0->IsVisible() );
ASSERT( (pTbbHidden0->GetStyle() & TBBS_HIDDEN) == 0 );
CExtBarButton * pTbbHidden1 =
m_pRightBtn->GetButtons().GetAt(iHidden+1);
ASSERT( pTbbHidden1 != NULL );
ASSERT( ! pTbbHidden1->IsSeparator() );
ASSERT( ! pTbbHidden1->IsVisible() );
ASSERT( (pTbbHidden1->GetStyle() & TBBS_HIDDEN) == 0 );
CExtBarButton * pTbbSeparatorToInsert = NULL;
int nIdx0=-1,nIdx1=-1;
for( nBtnIdx = 0; nBtnIdx < nCountOfButtons; nBtnIdx++ )
{
CExtBarButton * pTBB = _GetButtonPtr( nBtnIdx );
ASSERT_VALID( pTBB );
if( pTBB == pTbbHidden0 )
{
nIdx0 = nBtnIdx;
ASSERT( nIdx1 < 0 );
continue;
}
if( nIdx0 >= 0
&& pTBB->IsSeparator()
&& pTbbSeparatorToInsert == NULL
)
pTbbSeparatorToInsert = pTBB;
if( pTBB == pTbbHidden1 )
{
nIdx1 = nBtnIdx;
ASSERT( nIdx0 >= 0 && nIdx0 < nIdx1 );
break;
}
}
ASSERT(
nIdx0 < nIdx1
&&
nIdx0 >= 0 && nIdx0 < nCountOfButtons
&&
nIdx1 >= 0 && nIdx1 < nCountOfButtons
);
if( (nIdx0+1) == nIdx1 )
continue;
if( pTbbSeparatorToInsert != NULL )
{
nEndMeasure++;
iHidden++;
m_pRightBtn->GetButtons().InsertAt(
iHidden,
pTbbSeparatorToInsert
);
}
} // for( int iHidden = 0; iHidden < nEndMeasure; iHidden++ )
}
DWORD CExtToolControlBar::RecalcDelayShow(AFX_SIZEPARENTPARAMS* lpLayout)
{
DWORD dwRes = CControlBar::RecalcDelayShow( lpLayout );
if( !IsFloating() )
_RecalcPositionsImpl();
return dwRes;
}
void CExtToolControlBar::OnSize(UINT nType, int cx, int cy)
{
CExtControlBar::OnSize(nType, cx, cy);
_RecalcLayoutImpl();
}
void CExtToolControlBar::_RecalcLayoutImpl()
{
if( GetSafeHwnd() == NULL
|| !::IsWindow( GetSafeHwnd() )
)
return;
CExtControlBar::_RecalcLayoutImpl();
_RecalcPositionsImpl();
RedrawWindow(
NULL,
NULL,
RDW_INVALIDATE|RDW_UPDATENOW|RDW_ERASE
|RDW_ALLCHILDREN
);
}
void CExtToolControlBar::OnWindowPosChanging(WINDOWPOS FAR* lpwndpos)
{
CExtControlBar::OnWindowPosChanging(lpwndpos);
/// TO FIX:
/// _RecalcLayoutImpl();
}
void CExtToolControlBar::OnTimer(UINT nIDEvent)
{
CExtControlBar::OnTimer(nIDEvent);
}
void CExtToolControlBar::_SwitchMenuTrackingIndex(
int iNewMenuTrackingIndex // = -1
)
{
if( m_nBtnIdxMenuTracking >= 0 )
{
CExtBarButton * pTBB =
_GetButtonPtr( m_nBtnIdxMenuTracking );
ASSERT_VALID( pTBB );
ASSERT( !(pTBB->IsSeparator()) );
UINT nNewStyle =
pTBB->GetStyle()
&
~(TBBS_PRESSED|TBBS_CHECKED|TBBS_INDETERMINATE);
pTBB->SetStyle( nNewStyle );
_InvalidateButton( m_nBtnIdxMenuTracking );
m_nBtnIdxMenuTracking = -1;
} // if( m_nBtnIdxMenuTracking >= 0 )
if( iNewMenuTrackingIndex >= 0 )
{
m_nBtnIdxMenuTracking = iNewMenuTrackingIndex;
CExtBarButton * pTBB =
_GetButtonPtr( m_nBtnIdxMenuTracking );
ASSERT_VALID( pTBB );
ASSERT( !(pTBB->IsSeparator()) );
UINT nNewStyle =
pTBB->GetStyle()
&
~(TBBS_CHECKED|TBBS_INDETERMINATE);
nNewStyle |= TBBS_PRESSED;
pTBB->SetStyle( nNewStyle );
_InvalidateButton( m_nBtnIdxMenuTracking );
} // if( iNewMenuTrackingIndex >= 0 )
UpdateWindow();
}
CExtToolControlBar * CExtToolControlBar::_GetMenuTrackingBar()
{
for( INT iBar=0; iBar<g_AllBars.GetSize(); ++iBar )
{
CExtControlBar * pBar = g_AllBars[iBar];
ASSERT_VALID( pBar );
CExtToolControlBar * pToolControlBar =
DYNAMIC_DOWNCAST(CExtToolControlBar,pBar);
if( pToolControlBar == NULL )
continue;
if( pToolControlBar->m_nBtnIdxMenuTracking >= 0 )
return pToolControlBar;
}
return NULL;
}
void CExtToolControlBar::_CloseTrackingMenus()
{
if( CExtPopupMenuWnd::IsKeyPressed(VK_SHIFT) )
{
int i = 10;
i;
}
g_bMenuTracking = false;
for( INT iBar=0; iBar<g_AllBars.GetSize(); ++iBar )
{
CExtControlBar * pBar = g_AllBars[iBar];
ASSERT_VALID( pBar );
CExtToolControlBar * pToolControlBar =
DYNAMIC_DOWNCAST(CExtToolControlBar,pBar);
if( pToolControlBar == NULL )
continue;
pToolControlBar->_SwitchMenuTrackingIndex();
}
CExtPopupMenuWnd::CancelMenuTracking();
// // TOFIX: can be tracked other menu
// ASSERT( !CExtPopupMenuWnd::IsMenuTracking() );
}
void CExtToolControlBar::_CbPaintCombinedContent(
LPVOID pCookie,
CDC & dc,
const CWnd & refWndMenu,
const CRect & rcExcludeArea, // in screen coords
int eCombineAlign // CExtPopupMenuWnd::e_combine_align_t values
)
{
pCookie;
dc;
refWndMenu;
rcExcludeArea;
eCombineAlign;
ASSERT( dc.GetSafeHdc() != NULL );
ASSERT( refWndMenu.GetSafeHwnd() != NULL );
CExtToolControlBar * pBar = (CExtToolControlBar *)pCookie;
ASSERT_VALID( pBar );
ASSERT( pBar->IsKindOf(RUNTIME_CLASS(CExtToolControlBar)) );
ASSERT( eCombineAlign != CExtPopupMenuWnd::__CMBA_NONE );
if( rcExcludeArea.IsRectEmpty() )
return;
if( pBar->m_nBtnIdxMenuTracking < 0 )
return;
ASSERT(
pBar->m_nBtnIdxMenuTracking <
pBar->GetButtonsCount()
);
CExtBarButton * pTBB =
pBar->_GetButtonPtr(
pBar->m_nBtnIdxMenuTracking
);
ASSERT_VALID( pTBB );
UINT nStyle = pTBB->GetStyle();
BOOL bHover = pTBB->IsHover();
pTBB->SetHover( FALSE );
pTBB->ModifyStyle(
0,
TBBS_PRESSED|TBBS_CHECKED|TBBS_CHECKBOX
);
CRect rcClientBar,rcClientExcludeArea;
pBar->GetClientRect( &rcClientBar );
pBar->ClientToScreen( &rcClientBar );
refWndMenu.GetClientRect( &rcClientExcludeArea );
refWndMenu.ClientToScreen( &rcClientExcludeArea );
CPoint ptOffset =
rcClientBar.TopLeft()
- rcClientExcludeArea.TopLeft()
;
CPoint ptViewportOrg = dc.GetViewportOrg();
dc.SetViewportOrg( ptOffset );
bool bHorz = pBar->IsDockedVertically() ? false : true;
pTBB->Paint(dc,bHorz);
dc.SetViewportOrg( ptViewportOrg );
pTBB->SetHover( bHover );
pTBB->SetStyle(nStyle);
}
CExtBarButton * CExtToolControlBar::GetButton( int nIndex )
{
return _GetButtonPtr( nIndex );
}
CExtBarContentExpandButton * CExtToolControlBar::GetRightButton()
{
return m_pRightBtn;
}
void CExtToolControlBar::OnCaptureChanged(CWnd *pWnd)
{
if( pWnd != this &&
(m_nBtnIdxCapture >= 0 || m_nBtnIdxHover >= 0)
)
SendMessage( WM_CANCELMODE );
CExtControlBar::OnCaptureChanged(pWnd);
}
BOOL CExtToolControlBar::InitContentExpandButton()
{
if( m_pRightBtn != NULL )
return TRUE;
m_pRightBtn = OnCreateBarRightBtn();
if( m_pRightBtn == NULL )
return FALSE;
ASSERT_VALID( m_pRightBtn );
ASSERT_KINDOF( CExtBarContentExpandButton, m_pRightBtn );
m_buttons.Add( m_pRightBtn );
return TRUE;
}
bool CExtToolControlBar::_CanDockToInnerCircles() const
{
return false;
}
bool CExtToolControlBar::_CanDockToTabbedContainers() const
{
return false;
}
void CExtToolControlBar::ToggleDocking()
{
ASSERT_VALID( this );
ASSERT_VALID( m_pDockSite );
ASSERT_VALID( m_pDockBar );
#ifdef _DEBUG
if( !IsFloating() )
{
ASSERT_KINDOF( CExtDockBar, m_pDockBar );
}
#endif // _DEBUG
ASSERT( m_pDockContext != NULL );
m_pDockContext->ToggleDocking();
CFrameWnd * pFrame = _GetDockingFrameImpl();
ASSERT_VALID( pFrame );
pFrame->DelayRecalcLayout();
_RecalcNcArea();
}