// XTPToolBar.cpp : implementation of the CXTPToolBar class. // // This file is a part of the XTREME COMMANDBARS MFC class library. // (c)1998-2012 Codejock Software, All Rights Reserved. // // THIS SOURCE FILE IS THE PROPERTY OF CODEJOCK SOFTWARE AND IS NOT TO BE // RE-DISTRIBUTED BY ANY MEANS WHATSOEVER WITHOUT THE EXPRESSED WRITTEN // CONSENT OF CODEJOCK SOFTWARE. // // THIS SOURCE CODE CAN ONLY BE USED UNDER THE TERMS AND CONDITIONS OUTLINED // IN THE XTREME TOOLKIT PRO LICENSE AGREEMENT. CODEJOCK SOFTWARE GRANTS TO // YOU (ONE SOFTWARE DEVELOPER) THE LIMITED RIGHT TO USE THIS SOFTWARE ON A // SINGLE COMPUTER. // // CONTACT INFORMATION: // support@codejock.com // http://www.codejock.com // ///////////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "Resource.h" #include "Common/XTPResourceManager.h" #include "Common/XTPImageManager.h" #include "Common/XTPColorManager.h" #include "Common/XTPDrawHelpers.h" #include "Common/XTPToolTipContext.h" #include "Common/XTPSystemHelpers.h" #include "Common/XTPHookManager.h" #include "XTPCommandBarsDefines.h" #include "XTPCommandBars.h" #include "XTPCommandBar.h" #include "XTPToolBar.h" #include "XTPPopupBar.h" #include "XTPControls.h" #include "XTPControl.h" #include "XTPControlButton.h" #include "XTPControlPopup.h" #include "XTPPaintManager.h" #include "XTPMouseManager.h" #include "XTPDockContext.h" #include "XTPShortcutManager.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif #define _XTP_CBRS_ALL 0x0040FFFFL IMPLEMENT_XTP_COMMANDBAR(CXTPToolBar, CXTPCommandBar) class CXTPToolBar::CControlButtonHide: public CXTPControlButton { public: CControlButtonHide() { m_dwFlags = xtpFlagManualUpdate | xtpFlagSkipFocus | xtpFlagNoMovable; } void Draw(CDC* pDC); void SetBeginGroup(BOOL /*bBeginGroup*/) { } void OnExecute() { ASSERT(m_pParent); if (m_pParent) ((CXTPToolBar*)m_pParent)->SetVisible(FALSE); } virtual BOOL IsCustomizeMovable() const { return FALSE; } }; void CXTPToolBar::CControlButtonHide::Draw(CDC* pDC) { GetPaintManager()->DrawSpecialControl(pDC, xtpButtonHideFloating, this, m_pParent, TRUE, NULL); } class CXTPToolBar::CControlButtonCustomize: public CXTPControlButton { public: CControlButtonCustomize() { m_pControl = NULL; m_pToolBar = NULL; } virtual void OnExecute() { ASSERT(m_pParent); if (!m_pParent) return; CXTPCommandBars* pCommandBars = m_pParent->GetCommandBars(); ASSERT(pCommandBars); if (!pCommandBars) return; pCommandBars->GetCommandBarsOptions()->bDirtyState = TRUE; if (m_pControl) { if (m_pControl->GetHideFlags() & xtpHideCustomize) m_pControl->SetHideFlag(xtpHideCustomize, FALSE); else m_pControl->SetHideFlag(xtpHideCustomize, TRUE); SetChecked((m_pControl->GetHideFlags() & xtpHideCustomize) == 0); m_pControl->GetParent()->OnRecalcLayout(); m_pParent->InvalidateParents(); } if (m_pToolBar) { pCommandBars->ClosePopups(); m_pToolBar->Reset(TRUE); } } CXTPControl* m_pControl; CXTPToolBar* m_pToolBar; }; class CXTPToolBar::CControlButtonExpand: public CXTPControlPopup { public: CControlButtonExpand() { m_controlType = xtpControlButtonPopup; m_bHiddenExists = FALSE; m_dwFlags = xtpFlagLeftPopup | xtpFlagManualUpdate | xtpFlagNoMovable; m_pCommandBar = CXTPPopupBar::CreatePopupBar(0); } void Draw(CDC* pDC); BOOL OnSetPopup(BOOL bPopup); void SetRect(CRect rcControl) { m_rcControl = rcControl; m_bHiddenExists = IsHiddenExists(); }; void SetBeginGroup(BOOL /*bBeginGroup*/) { } BOOL IsHiddenExists(); virtual BOOL IsCaptionVisible() const { return FALSE; } virtual BOOL IsCustomizeMovable() const { return FALSE; } private: BOOL m_bHiddenExists; }; BOOL CXTPToolBar::CControlButtonExpand::IsHiddenExists() { for (int i = 0; i < m_pParent->GetControlCount(); i++) { if (m_pParent->GetControl(i)->GetHideFlags() == xtpHideWrap) return TRUE; } return FALSE; } void CXTPToolBar::CControlButtonExpand::Draw(CDC* pDC) { GetPaintManager()->DrawSpecialControl(pDC, m_pParent->GetPosition() == xtpBarFloating ? xtpButtonExpandFloating: xtpButtonExpandToolbar, this, m_pParent, TRUE, &m_bHiddenExists); } BOOL CXTPToolBar::CControlButtonExpand::OnSetPopup(BOOL bPopup) { m_bPopup = bPopup; if (bPopup) { if (m_pCommandBar) m_pCommandBar->InternalRelease(); m_pCommandBar = NULL; CWnd* pSite = m_pParent->GetSite(); if (pSite) { XTP_COMMANDBARS_CREATEBAR cs; ZeroMemory(&cs, sizeof(cs)); cs.bExpandBar = TRUE; if (pSite->SendMessage(WM_XTP_CREATECOMMANDBAR, 0, (LPARAM)&cs) != 0) { m_pCommandBar = DYNAMIC_DOWNCAST(CXTPPopupBar, cs.pCommandBar); } } if (m_pCommandBar == NULL) m_pCommandBar = CXTPPopupToolBar::CreatePopupToolBar(m_pParent->GetCommandBars()); m_pCommandBar->EnableCustomization(FALSE); CXTPCommandBars* pCommandBars = m_pParent->GetCommandBars(); if (pCommandBars && ((CXTPToolBar*)m_pParent)->m_pDockContext) { pCommandBars->GetHiddenControls((CXTPToolBar*)m_pParent, m_pCommandBar); if (pCommandBars->GetCommandBarsOptions()->bShowExpandButtonAlways || pCommandBars->IsCustomizeAvail()) { CXTPControlPopup* pControl = (CXTPControlPopup*)m_pCommandBar->GetControls()->Add(xtpControlPopup, XTP_ID_CUSTOMIZE_ADDORREMOVE); pControl->SetFlags(xtpFlagManualUpdate); pControl->SetBeginGroup(m_pCommandBar->GetControlCount() > 1); pCommandBars->GetAddOrRemovePopup((CXTPToolBar*)m_pParent, pControl->GetCommandBar()); XTPResourceManager()->AssertValid(!pControl->GetCaption().IsEmpty()); } } else { ((CXTPToolBar*)m_pParent)->_GetHiddenControls(m_pCommandBar); } m_pCommandBar->Popup(this, IsKeyboardSelected(GetSelected())); } else { ASSERT(m_pCommandBar); if (m_pCommandBar) m_pCommandBar->SetTrackingMode(FALSE); } RedrawParent(); return TRUE; } CXTPToolBar::CXTPToolBar() { m_bVisible = TRUE; m_pDockBar = 0; m_pDockContext = 0; m_bBuiltIn = TRUE; m_bTearOff = FALSE; m_bCloseable = TRUE; m_bTemporary = FALSE; m_bShowExpandButton = TRUE; m_bPreviewMode = m_bPreviewVisible = FALSE; m_bContextMenuPresent = TRUE; m_bInRecalcLayout = FALSE; m_pDockContext = new CXTPDockContext(this); m_dwFlags = xtpFlagAlignAny | xtpFlagFloating | xtpFlagHideWrap; CXTPDrawHelpers::RegisterWndClass(0, _T("XTPToolBar"), CS_DBLCLKS); } BOOL CXTPToolBar::CreateToolBar(DWORD dwStyle, CWnd* pParentWnd, UINT nID) { m_dwStyle = dwStyle & _XTP_CBRS_ALL; dwStyle = dwStyle & ~_XTP_CBRS_ALL; dwStyle = dwStyle | WS_CLIPCHILDREN | WS_CLIPSIBLINGS; if (!CWnd::CreateEx(0, _T("XTPToolBar"), NULL, dwStyle, CRect(0, 0, 0, 0), pParentWnd, nID)) return FALSE; m_barPosition = xtpBarTop; SAFE_DELETE(m_pDockContext); m_dwFlags &= ~ (xtpFlagAlignAny | xtpFlagFloating | xtpFlagHideWrap); if ((m_dwStyle & CBRS_TOOLTIPS) && m_pCommandBars == 0) EnableToolTips(); return TRUE; } void CXTPToolBar::EnableDocking(DWORD dwFlags) { ASSERT(m_pCommandBars); m_dwFlags = dwFlags; } CXTPToolBar::~CXTPToolBar() { SAFE_DELETE(m_pDockContext) } BOOL CXTPCommandBar::SetButtons(UINT* pButtons, int nCount) { m_pControls->RemoveAll(); BOOL bSeparator = FALSE; CWnd* pSite = GetSite(); for (int i = 0; i < nCount; i++) { if (pButtons[i] == 0) bSeparator = TRUE; else { XTPControlType controlType = xtpControlButton; XTPButtonStyle buttonStyle = xtpButtonAutomatic; CXTPControl* pControl = NULL; UINT nID = pButtons[i]; XTP_COMMANDBARS_CREATECONTROL cs; if (pSite) { cs.nID = nID; cs.pControl = NULL; cs.bToolBar = TRUE; cs.pMenu = NULL; cs.nIndex = i; cs.strCaption = GetTitle(); cs.controlType = controlType; cs.pCommandBar = this; cs.buttonStyle = buttonStyle; if (pSite->SendMessage(WM_XTP_BEFORECREATECONTROL, 0, (LPARAM)&cs) != 0) { pControl = cs.pControl; controlType = cs.controlType; buttonStyle = cs.buttonStyle; nID = cs.nID; } } if (pControl == NULL) { pControl = m_pControls->Add(controlType, nID); if (pControl) { pControl->SetStyle(buttonStyle); if (controlType == xtpControlPopup) pControl->SetIconId(nID); } } else m_pControls->Add(pControl, nID); if (bSeparator) { pControl->SetBeginGroup(TRUE); bSeparator = FALSE; } if (pSite) { cs.pControl = pControl; pSite->SendMessage(WM_XTP_AFTERCREATECONTROL, 0, (LPARAM)&cs); } } } return TRUE; } BOOL CXTPToolBar::LoadToolBar(UINT nIDResource, BOOL bLoadIcons) { m_nBarID = nIDResource; if (!CXTPCommandBar::LoadToolBar(nIDResource, bLoadIcons)) return FALSE; m_pControls->CreateOriginalControls(); return TRUE; } BOOL CXTPCommandBar::LoadToolBar(UINT nIDResource, BOOL bLoadIcons) { LPCTSTR lpszResourceName = MAKEINTRESOURCE(nIDResource); struct CToolBarData { WORD wVersion; WORD wWidth; WORD wHeight; WORD wItemCount; WORD* items() { return (WORD*)(this + 1); } }; m_pControls->RemoveAll(); ASSERT(GetControlCount() == 0); ASSERT_VALID(this); ASSERT(lpszResourceName != NULL); if (!lpszResourceName) return FALSE; // determine location of the bitmap in resource fork HINSTANCE hInst = AfxFindResourceHandle(lpszResourceName, RT_TOOLBAR); if (!hInst) return FALSE; HRSRC hRsrc = ::FindResource(hInst, lpszResourceName, RT_TOOLBAR); if (hRsrc == NULL) return FALSE; HGLOBAL hGlobal = LoadResource(hInst, hRsrc); if (hGlobal == NULL) return FALSE; CToolBarData* pData = (CToolBarData*)LockResource(hGlobal); if (pData == NULL) return FALSE; ASSERT(pData->wVersion == 1); int i; UINT* pItems = new UINT[pData->wItemCount]; for (i = 0; i < pData->wItemCount; i++) pItems[i] = pData->items()[i]; BOOL bResult = SetButtons(pItems, pData->wItemCount); if (bLoadIcons) { CXTPImageManager* pImageManager = GetImageManager(); if (!pImageManager->SetIcons(nIDResource, pItems, pData->wItemCount, CSize(pData->wWidth, pData->wHeight))) bResult = FALSE; if (pData->wWidth != 16) { SetIconSize(CSize(pData->wWidth, pData->wHeight)); } } delete[] pItems; UnlockResource(hGlobal); FreeResource(hGlobal); return bResult; } BOOL CXTPToolBar::SetPosition(XTPBarPosition barPosition) { CXTPCommandBars* pCommandBars = GetCommandBars(); if (!pCommandBars) return FALSE; if (IsDockingPosition(barPosition)) { if (!pCommandBars->DockCommandBar(this, barPosition)) return FALSE; } else if (barPosition == xtpBarFloating) { if (!pCommandBars->FloatCommandBar(this)) return FALSE; } else return FALSE; ASSERT(m_barPosition == barPosition); return TRUE; } BEGIN_MESSAGE_MAP(CXTPToolBar, CXTPCommandBar) ON_WM_SETCURSOR() ON_WM_RBUTTONDOWN() ON_WM_NCCREATE() ON_WM_NCACTIVATE() ON_MESSAGE(WM_FLOATSTATUS, OnFloatStatus) ON_WM_MOUSEACTIVATE() ON_WM_LBUTTONDOWN() ON_WM_NCHITTEST_EX() ON_WM_NCLBUTTONDOWN() ON_WM_SETFOCUS() ON_WM_CLOSE() ON_MESSAGE(WM_SIZEPARENT, OnSizeParent) ON_WM_LBUTTONDBLCLK() END_MESSAGE_MAP() BOOL CXTPToolBar::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message) { if (GetShowGripper() && (IsDockingPosition(GetPosition())) && m_pDockContext && ((m_dwFlags & (xtpFlagAlignAny | xtpFlagFloating)) != 0)) { CXTPClientRect rcGripper(this); CRect rcBorder = GetPaintManager()->GetCommandBarBorders(this); CSize szGripper = GetPaintManager()->DrawCommandBarGripper(NULL, this, FALSE); if (IsDialogBar()) { rcGripper.right = rcGripper.left + rcBorder.left + szGripper.cx; rcGripper.left += 3; rcGripper.bottom = rcGripper.top + rcBorder.top + szGripper.cy; } else if (IsVerticalPosition(GetPosition())) { rcGripper.bottom = rcGripper.top + rcBorder.top + szGripper.cy; } else { rcGripper.right = rcGripper.left + rcBorder.left + szGripper.cx; } POINT pt; GetCursorPos(&pt); ScreenToClient(&pt); if (rcGripper.PtInRect(pt)) { SetCursor(AfxGetApp()->LoadStandardCursor(IDC_SIZEALL)); return TRUE; } } return CXTPCommandBar::OnSetCursor(pWnd, nHitTest, message); } INT_PTR CXTPCommandBar::OnToolHitTest(CPoint point, TOOLINFO* pTI) const { ASSERT_VALID(this); ASSERT(::IsWindow(m_hWnd)); if (IsTrackingMode() == TRUE_POPUP && GetPosition() != xtpBarPopup) return -1; if (m_nPopuped != -1) return -1; BOOL bToolBarAccelTips = FALSE; CXTPCommandBars* pCommandBars = GetCommandBars(); CXTPMouseManager* pMouseManager = pCommandBars->GetMouseManager(); if (pMouseManager->IsMouseLocked() || pMouseManager->IsTrackedLock(this)) return -1; if (pCommandBars) { if (!pCommandBars->GetCommandBarsOptions()->bToolBarScreenTips) return -1; bToolBarAccelTips = pCommandBars->GetCommandBarsOptions()->bToolBarAccelTips; } CXTPControl* pControl = m_pControls->HitTest(point); if (!pControl) return -1; if (m_barType == xtpBarTypePopup && (!pCommandBars || (!pCommandBars->GetCommandBarsOptions()->bShowPopupBarToolTips && ((pControl->GetFlags() & xtpFlagShowPopupBarTip) == 0)))) { return -1; } INT_PTR nHit = pControl->OnToolHitTest(point, pTI); if (nHit != -1) { if (pTI->hwnd != m_hWnd) return -1; if (pTI != NULL && pTI->cbSize == sizeof(XTP_TOOLTIP_TOOLINFO_EX)) { if (((XTP_TOOLTIP_TOOLINFO_EX*)pTI)->pToolInfo != NULL) ((XTP_TOOLTIP_TOOLINFO_EX*)pTI)->pToolInfo->pObject = pControl; } return nHit; } nHit = pControl->GetIconId(); CRect rect = pControl->GetRect(); CString strTip = pControl->GetTooltip(); if (strTip.GetLength() == 0) return -1; CString strShortcut = pControl->m_strShortcutText; if (pCommandBars && bToolBarAccelTips) { if (strShortcut.IsEmpty()) { strShortcut = pControl->m_strShortcutTextAuto; if (!pCommandBars->GetShortcutManager()->FindDefaultAccelerator((UINT)pControl->GetID(), strShortcut)) strShortcut.Empty(); } if ((strShortcut.GetLength() > 0) && (strTip[0] != '<')) { strTip += _T(" (") + strShortcut +_T(")"); } } CXTPToolTipContext::FillInToolInfo(pTI, m_hWnd, rect, nHit, strTip, strTip, pControl->GetDescription(), GetImageManager()); if (pTI != NULL && pTI->cbSize == sizeof(XTP_TOOLTIP_TOOLINFO_EX)) { if (((XTP_TOOLTIP_TOOLINFO_EX*)pTI)->pToolInfo != NULL) ((XTP_TOOLTIP_TOOLINFO_EX*)pTI)->pToolInfo->pObject = pControl; } // found matching rect, return the ID of the button return nHit != 0 ? nHit : -1; } void CXTPToolBar::OnRButtonDown(UINT nFlags, CPoint point) { CXTPControl* pControl = m_pControls->HitTest(point); if (pControl && pControl->OnRButtonDown(point)) return; CXTPCommandBars* pCommandBars = GetCommandBars(); if (!pCommandBars) return; if (IsCustomizeMode()) { CXTPCommandBar::OnRButtonDown(nFlags, point); return; } SetTrackingMode(FALSE); SetSelected(-1); Redraw(); ClientToScreen(&point); pCommandBars->ContextMenu(this, point); } BOOL CXTPToolBar::Create(CWnd* pParentWnd, BOOL bFloat) { if (!IsWindow(m_hWnd)) { DWORD dwStyle = (bFloat ? WS_POPUP : WS_CHILD) | MFS_SYNCACTIVE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS; CPoint pt = m_pDockContext ? m_pDockContext->m_ptMRUFloatPos : CPoint(100, 100); CXTPCommandBars* pCommandBars = GetCommandBars(); int nLayoutRTL = pCommandBars && pCommandBars->IsLayoutRTL() ? WS_EX_LAYOUTRTL : 0; if (!CWnd::CreateEx(nLayoutRTL, _T("XTPToolBar"), m_strTitle, dwStyle, CRect(pt, CSize(0, 0)), pParentWnd, 0)) return FALSE; SetDlgCtrlID(0); ShowWindow(SW_SHOWNA); } if (!bFloat) { ModifyStyle(WS_POPUP, WS_CHILD); } else { SetWindowLongPtr(m_hWnd, GWLP_HWNDPARENT, (LONG_PTR)0); ModifyStyle(WS_CHILD, WS_POPUP | MFS_SYNCACTIVE); SetWindowLongPtr(m_hWnd, GWLP_HWNDPARENT, (LONG_PTR)pParentWnd->m_hWnd); if (pParentWnd->GetExStyle() & WS_EX_TOPMOST) { SetWindowPos(&CWnd::wndTopMost, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOOWNERZORDER | SWP_NOACTIVATE); } } return TRUE; } CRect CXTPToolBar::GetBorders() { if (GetPosition() == xtpBarFloating) { return CRect(3, 3, 3, 3); } CRect rcBorder = GetPaintManager()->GetCommandBarBorders(this); if (GetShowGripper()) rcBorder.TopLeft() += GetPaintManager()->DrawCommandBarGripper(NULL, this, FALSE); return rcBorder; } CSize CXTPToolBar::CalcDockingLayout(int nLength, DWORD dwMode, int nWidth) { CClientDC dc(this); CXTPFontDC font(&dc, GetPaintManager()->GetCommandBarFont(this)); CXTPControlPopup* pPopupExp = NULL; CRect rcBorder(GetBorders()); CXTPControl* pHide = m_pControls->FindControl(XTP_ID_TOOLBAR_HIDE); if (pHide) { pHide->SetHideFlags(xtpHideGeneric); } BOOL bShowExpandButtonAlways = FALSE; CXTPCommandBars* pCommandBars = GetCommandBars(); if (pCommandBars) bShowExpandButtonAlways = pCommandBars->GetCommandBarsOptions()->bShowExpandButtonAlways; BOOL bCommit = TRUE; CSize sz = 0; if (m_bShowExpandButton) { pPopupExp = (CXTPControlPopup*)m_pControls->FindControl(XTP_ID_TOOLBAR_EXPAND); if (!pPopupExp) { pPopupExp = (CXTPControlPopup*)m_pControls->Add(new CControlButtonExpand(), XTP_ID_TOOLBAR_EXPAND, _T(""), -1, TRUE); } pPopupExp->SetHideFlags(xtpHideGeneric); if (bShowExpandButtonAlways) { if (dwMode & LM_HORZDOCK) rcBorder.right += 11; else rcBorder.bottom += 11; } else { if (dwMode & LM_COMMIT) { sz = m_pControls->CalcDynamicSize(&dc, nLength, dwMode, rcBorder, nWidth); if (((CControlButtonExpand*)pPopupExp)->IsHiddenExists()) { if (dwMode & LM_HORZDOCK) rcBorder.right += 11; else rcBorder.bottom += 11; } else { bCommit = FALSE; pPopupExp = NULL; } } else { sz = m_pControls->CalcDynamicSize(&dc, nLength, dwMode, rcBorder, nWidth); CSize szMin = m_pControls->CalcDynamicSize(&dc, 1, dwMode, rcBorder, nWidth); if (m_pControls->GetVisibleCount() > 1) { if (dwMode & LM_HORZDOCK) sz.cx = max(sz.cx, szMin.cx + 11); else sz.cy = max(sz.cy, szMin.cy + 11); } pPopupExp = NULL; bCommit = FALSE; } } } if (bCommit) sz = m_pControls->CalcDynamicSize(&dc, nLength, dwMode, rcBorder, nWidth); if (pPopupExp) { pPopupExp->SetHideFlags(xtpNoHide); GetPaintManager()->DrawSpecialControl(0, xtpButtonExpandToolbar, pPopupExp, this, FALSE, &sz); } if ((m_nIdleFlags & xtpIdleLayout) && (dwMode & LM_COMMIT)) { m_nIdleFlags &= ~xtpIdleLayout; Redraw(); } return sz; } CSize CXTPToolBar::CalcDynamicLayout(int nLength, DWORD nMode) { ASSERT(!(nMode & LM_HORZDOCK || nMode & LM_VERTDOCK)); CClientDC dc(this); CXTPFontDC font(&dc, GetPaintManager()->GetCommandBarFont(this)); int nTitleSize = GetPaintManager()->DrawCommandBarGripper(&dc, this, FALSE).cy; CRect rcBorder(GetBorders()); rcBorder.top += nTitleSize + 1; CXTPControlPopup* pPopupExp = NULL; CXTPControl* pHide = NULL; if (IsCloseable()) { pHide = m_pControls->FindControl(XTP_ID_TOOLBAR_HIDE); if (!pHide) { pHide = (CXTPControlPopup*)m_pControls->Add(new CControlButtonHide(), XTP_ID_TOOLBAR_HIDE, _T(""), -1, TRUE); } pHide->SetHideFlags(xtpHideGeneric); } if (m_bShowExpandButton && m_pCommandBars) { pPopupExp = (CXTPControlPopup*)m_pControls->FindControl(XTP_ID_TOOLBAR_EXPAND); if (!pPopupExp) { pPopupExp = (CXTPControlPopup*)m_pControls->Add(new CControlButtonExpand(), XTP_ID_TOOLBAR_EXPAND, _T(""), -1, TRUE); } pPopupExp->SetHideFlags(xtpHideGeneric); } CSize sz; if (m_barType == xtpBarTypePopup) { UpdateShortcuts(); sz = m_pControls->CalcPopupSize(&dc, 0, 0, rcBorder); } else sz = m_pControls->CalcDynamicSize(&dc, nLength, nMode, rcBorder); int nLeft = sz.cx - 3; if (pHide) { pHide->SetHideFlags(xtpNoHide); pHide->SetRect(CRect(nLeft - nTitleSize, 3, nLeft, 3 + nTitleSize)); nLeft -= nTitleSize; if (pPopupExp) pPopupExp->SetWrap(TRUE); } BOOL bShowExpandButtonAlways = TRUE; CXTPCommandBars* pCommandBars = GetCommandBars(); if (pCommandBars) bShowExpandButtonAlways = pCommandBars->GetCommandBarsOptions()->bShowExpandButtonAlways; if (pPopupExp && nLeft - nTitleSize > 0 && bShowExpandButtonAlways) { pPopupExp->SetWrap(TRUE); pPopupExp->SetHideFlags(xtpNoHide); pPopupExp->SetRect(CRect(nLeft - nTitleSize, 3, nLeft, 3 + nTitleSize)); } if ((m_nIdleFlags & xtpIdleLayout) && (nMode & LM_COMMIT)) { m_nIdleFlags &= ~xtpIdleLayout; Redraw(); } return sz; } void CXTPToolBar::OnRecalcLayout() { if (!GetSafeHwnd()) return; if (!IsVisible()) return; if (m_bInRecalcLayout) return; m_bInRecalcLayout = TRUE; if (m_barPosition != xtpBarFloating) { CXTPCommandBars* pCommandBars = GetCommandBars(); if (pCommandBars) { pCommandBars->RecalcFrameLayout(); } else { CWnd* pSite = GetSite(); CXTPClientRect rc(pSite); if (pSite) pSite->SendMessage(WM_SIZE, 0, MAKELPARAM(rc.Width(), rc.Height())); } } else if (IsVisible()) { CSize sz = CalcDynamicLayout(-1, LM_MRUWIDTH | LM_HORZ | LM_COMMIT); CRect rc; GetWindowRect(&rc); MoveWindow(rc.left, rc.top, sz.cx, sz.cy, TRUE); } Redraw(); m_bInRecalcLayout = FALSE; } BOOL CXTPToolBar::OnNcCreate(LPCREATESTRUCT lpCreateStruct) { if (!CXTPCommandBar::OnNcCreate(lpCreateStruct)) return FALSE; if (GetStyle() & MFS_SYNCACTIVE) { // syncronize activation state with top level parent CWnd* pParentWnd = GetTopLevelParent(); ASSERT(pParentWnd != NULL); if (!pParentWnd) return FALSE; CWnd* pActiveWnd = GetForegroundWindow(); BOOL bActive = (pParentWnd == pActiveWnd) || (pParentWnd->GetLastActivePopup() == pActiveWnd && pActiveWnd->SendMessage(WM_FLOATSTATUS, FS_SYNCACTIVE) != 0); // the WM_FLOATSTATUS does the actual work SendMessage(WM_FLOATSTATUS, bActive ? FS_ACTIVATE : FS_DEACTIVATE); } return TRUE; } LRESULT CXTPToolBar::OnFloatStatus(WPARAM wParam, LPARAM) { // FS_SYNCACTIVE is used to detect MFS_SYNCACTIVE windows LRESULT lResult = ((GetStyle() & MFS_SYNCACTIVE) && (wParam & FS_SYNCACTIVE)); if (m_barPosition != xtpBarFloating || !m_bVisible) return lResult; BOOL bSyncActivate = TRUE; CXTPCommandBars* pCommandBars = GetCommandBars(); if (pCommandBars) bSyncActivate = pCommandBars->GetCommandBarsOptions()->bSyncFloatingBars; if (bSyncActivate) { if ((wParam & FS_DEACTIVATE) && !IsTopParentActive()) { SetWindowPos(NULL, 0, 0, 0, 0, SWP_HIDEWINDOW | SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE); } if ((wParam & FS_ACTIVATE) && !IsWindowVisible() && IsTopParentActive()) { // check if parent invisible or minimized window DWORD dwStyle = ::GetWindowLong(::GetForegroundWindow(), GWL_STYLE); if ((dwStyle & WS_VISIBLE) && !(dwStyle & WS_MINIMIZE)) SetWindowPos(NULL, 0, 0, 0, 0, SWP_SHOWWINDOW | SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE); } } if (wParam & (FS_SHOW | FS_HIDE)) { SetWindowPos(NULL, 0, 0, 0, 0, ((wParam & FS_SHOW) ? SWP_SHOWWINDOW : SWP_HIDEWINDOW) | SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE); } if (wParam & (FS_ENABLE | FS_DISABLE)) EnableWindow((wParam & FS_ENABLE) != 0); return lResult; } BOOL CXTPToolBar::IsFloatingFrameFocused() const { if (!IsTopParentActive()) return FALSE; CWnd* pWnd = CWnd::GetFocus(); while (pWnd && IsWindow(pWnd->GetSafeHwnd())) { pWnd = pWnd->GetParentFrame(); if (DYNAMIC_DOWNCAST(CMiniFrameWnd, pWnd)) return TRUE; } return FALSE; } int CXTPToolBar::OnMouseActivate(CWnd* pDesktopWnd, UINT nHitTest, UINT message) { if (m_barPosition == xtpBarFloating || IsFloatingFrameFocused() || IsCustomizeMode()) return MA_NOACTIVATE; return CWnd::OnMouseActivate(pDesktopWnd, nHitTest, message); } BOOL CXTPToolBar::OnNcActivate(BOOL bActive) { return bActive ? FALSE : CWnd::OnNcActivate(bActive); } void CXTPToolBar::OnLButtonDown(UINT nFlags, CPoint point) { if (m_barPosition == xtpBarFloating) SetWindowPos(&CWnd::wndTop, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE); const CXTPControl *pControl = m_pControls->HitTest(point); int nControlCount = 0; if (NULL != pControl) { CXTPCommandBar *pCommandBar = pControl->GetCommandBar(); CXTPControls *pControls = NULL; if (NULL != pCommandBar) { pControls = pCommandBar->GetControls(); } if (NULL != pControls) { nControlCount = pControls->GetCount(); } } if (NULL == pControl) { m_pCommandBars->ClosePopups(); if (m_pDockContext && ((m_dwFlags & (xtpFlagAlignAny | xtpFlagFloating)) != 0)) { ClientToScreen(&point); m_pDockContext->StartDrag(point); } } else { CXTPCommandBar::OnLButtonDown(nFlags, point); } } void CXTPToolBar::OnLButtonDblClk(UINT nFlags, CPoint point) { if (m_pControls->HitTest(point) == NULL) { if (m_pDockContext) { m_pDockContext->ToggleDocking(); return; } } CXTPCommandBar::OnLButtonDblClk(nFlags, point); } LRESULT CXTPToolBar::OnNcHitTest(CPoint point) { if (m_barPosition != xtpBarFloating) return CXTPCommandBar::OnNcHitTest(point); if (m_barType == xtpBarTypePopup) return CXTPCommandBar::OnNcHitTest(point); CRect rectWindow; GetWindowRect(&rectWindow); rectWindow.InflateRect(-3, -3); if (point.y < rectWindow.top) return HTTOP; if (point.y >= rectWindow.bottom) return HTBOTTOM; if (point.x < rectWindow.left) return HTLEFT; if (point.x >= rectWindow.right) return HTRIGHT; return CXTPCommandBar::OnNcHitTest(point); } void CXTPToolBar::OnNcLButtonDown(UINT nHitTest, CPoint point) { if (!m_pDockContext) return; if (nHitTest >= HTSIZEFIRST && nHitTest <= HTSIZELAST) { ActivateTopParent(); SetWindowPos(&CWnd::wndTop, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE); m_pCommandBars->ClosePopups(); m_pDockContext->StartResize(nHitTest, point); return; } CXTPCommandBar::OnNcLButtonDown(nHitTest, point); } void CXTPToolBar::OnClose() { } BOOL CXTPToolBar::IsWindowVisible() const { return GetSafeHwnd() && IsVisible() && CWnd::IsWindowVisible() && !CXTPWindowRect(this).IsRectEmpty(); } void CXTPToolBar::SetVisible(BOOL bVisible) { if (m_bVisible == bVisible) return; m_bVisible = bVisible; if (!bVisible) { SetTrackingMode(FALSE); } ShowWindow(bVisible ? SW_SHOWNA : SW_HIDE); CXTPCommandBars* pCommandBars = GetCommandBars(); if (bVisible) { OnRecalcLayout(); } else if (IsDockingPosition(m_barPosition)) { if (pCommandBars) { pCommandBars->RecalcFrameLayout(); } else { CWnd* pSite = GetSite(); CXTPClientRect rc(pSite); if (pSite) pSite->SendMessage(WM_SIZE, 0, MAKELPARAM(rc.Width(), rc.Height())); } } if (pCommandBars) { BOOL bRemove = m_bTearOff && !bVisible; pCommandBars->GetSite()->SendMessage(WM_XTP_TOOLBARVISIBLECHANGED, (WPARAM)this, (LPARAM)m_bVisible); if (bRemove) pCommandBars->Remove(this); pCommandBars->GetCommandBarsOptions()->bDirtyState = TRUE; } } LRESULT CXTPToolBar::OnSizeParent(WPARAM, LPARAM lParam) { AFX_SIZEPARENTPARAMS* lpLayout = (AFX_SIZEPARENTPARAMS*)lParam; if (GetStyle() & WS_VISIBLE) { // align the control bar CRect rect; rect.CopyRect(&lpLayout->rect); CSize sizeAvail = rect.Size(); // maximum size available // get maximum requested size DWORD dwMode = LM_HORZDOCK | LM_HORZ | LM_COMMIT; if (GetFlags() & xtpFlagStretched) dwMode |= LM_STRETCH; if (GetFlags() & xtpFlagHideWrap) dwMode |= LM_HIDEWRAP; if (lpLayout->hDWP == NULL) dwMode &= ~LM_COMMIT; CSize size = CalcDockingLayout(sizeAvail.cx, dwMode); size.cx = min(size.cx, sizeAvail.cx); size.cy = min(size.cy, sizeAvail.cy); lpLayout->sizeTotal.cy += size.cy; lpLayout->sizeTotal.cx = max(lpLayout->sizeTotal.cx, size.cx); lpLayout->rect.top += size.cy; rect.right = rect.left + size.cx; rect.bottom = rect.top + size.cy; // only resize the window if doing layout and not just rect query if (lpLayout->hDWP != NULL) AfxRepositionWindow(lpLayout, m_hWnd, &rect); Redraw(); } return 0; } CSize CXTPCommandBar::GetAutoIconSize(BOOL bLarge) const { return GetPaintManager()->GetAutoIconSize(bLarge); } CSize CXTPCommandBar::GetIconSize() const { if (m_szIcons != CSize(0)) return m_szIcons; CXTPCommandBars* pCommandBars = GetCommandBars(); if (!pCommandBars) return CSize(16, 16); CXTPCommandBarsOptions* pOptions = pCommandBars->GetCommandBarsOptions(); if (GetType() == xtpBarTypePopup) { return pOptions->szPopupIcons != CSize(0) ? pOptions->szPopupIcons : GetAutoIconSize(FALSE); } CSize sz = pOptions->szIcons != CSize(0) ? pOptions->szIcons : GetAutoIconSize(FALSE); if (pOptions->bLargeIcons && m_szButtons == CSize(0)) { sz = pOptions->szLargeIcons != CSize(0) ? pOptions->szLargeIcons : GetAutoIconSize(TRUE); } return sz; } CSize CXTPCommandBar::GetLargeIconSize(BOOL bAutoSize) const { CXTPCommandBars* pCommandBars = GetCommandBars(); if (!pCommandBars) return m_szIcons != CSize(0) ? CSize(2 * m_szIcons.cx, 2 * m_szIcons.cy) : CSize(32, 32); CSize sz = m_szIcons != CSize(0) ? m_szIcons: (pCommandBars->m_pOptions->szIcons != CSize(0) ? pCommandBars->m_pOptions->szIcons : CSize(16, 16)); if (m_szButtons == CSize(0)) { sz = pCommandBars->m_pOptions->szLargeIcons != CSize(0) ? pCommandBars->m_pOptions->szLargeIcons : (bAutoSize ? GetAutoIconSize(TRUE) : CSize(sz.cx * 2, sz.cy * 2)); } return sz; } CSize CXTPCommandBar::GetButtonSize() const { if (m_szButtons != CSize(0)) return m_szButtons; CSize szIcon = GetIconSize(); return CSize(szIcon.cx + 6, szIcon.cy + 6); } void CXTPCommandBar::ShowTextBelowIcons(BOOL bTextBelow) { m_bTextBelow = bTextBelow; DelayLayout(); } BOOL CXTPCommandBar::IsTextBelowIcons() const { if (m_bTextBelow != XTP_BOOL_DEFAULT) return m_bTextBelow; CXTPCommandBars* pCommandBars = GetCommandBars(); if (pCommandBars) { return pCommandBars->m_pOptions->bShowTextBelowIcons; } return FALSE; } int CXTPToolBar::_FindNearest(CXTPControls* pControls, CXTPControl* pFind, int nPos, BOOL /*bVisible*/) const { if (pFind == NULL) return -1; int nResult = -1; for (int i = nPos; i < pControls->GetCount(); i++) { CXTPControl* pControl = pControls->GetAt(i); if (pControl->GetID() == pFind->GetID() && pControl->GetType() == pFind->GetType()) { return i; } } return nResult; } void CXTPToolBar::Reset(BOOL bShowWarningMessage) { if (m_bBuiltIn && m_nBarID != 0 && IsCustomizable()) { if (bShowWarningMessage) { CString strMessage, strTitle = GetTitle(), strReset; CXTPResourceManager::AssertValid(XTPResourceManager()->LoadString(&strReset, XTP_IDS_CONFIRM_RESET)); strMessage.Format(strReset, (LPCTSTR)strTitle); CXTPPushRoutingFrame push(GetFrameSite()); if (XTPResourceManager()->ShowMessageBox(strMessage, MB_ICONWARNING | MB_OKCANCEL) != IDOK) return; } if (m_pControls->m_pOriginalControls != NULL) { m_pControls->RemoveAll(); CXTPControls* pControls = m_pControls->m_pOriginalControls; for (int i = 0; i < pControls->GetCount(); i++) { CXTPControl* pControl = pControls->GetAt(i); if (!pControl->m_bTemporary) m_pControls->AddClone(pControl, -1, TRUE); } } else { LoadToolBar(m_nBarID, FALSE); } CWnd* pWnd = GetSite(); if (pWnd && ::IsWindow(pWnd->m_hWnd)) pWnd->SendMessage(WM_XTP_CUSTOMIZATION_RESETTOOLBAR, 0, (LPARAM)this); OnInitialUpdate(); OnRecalcLayout(); } } void CXTPToolBar::BeforeCustomizeControlAdd(CXTPControl* /*pControl*/) { } void CXTPToolBar::BuildCustomizePopup(CXTPCommandBar* pExpandBar) { CXTPCommandBars* pCommandBars = GetCommandBars(); if (!pCommandBars) return; CXTPControls* pOriginalControls = m_pControls->m_pOriginalControls ? m_pControls->m_pOriginalControls->Duplicate(FALSE) : new CXTPControls(); ASSERT(pOriginalControls); int nOriginal = 0; int nToolBar = 0; while (nToolBar < GetControlCount()) { if ((GetControl(nToolBar)->GetHideFlags() & xtpHideCustomize) != 0) { int nSelected = m_nSelected; int nPopuped = m_nPopuped; GetControls()->Remove(nToolBar); if (nPopuped != -1) m_nPopuped = nPopuped + (nToolBar < nPopuped ? - 1 : 0); if (nSelected != -1) m_nSelected = nSelected + (nToolBar < nSelected ? - 1 : 0); } else nToolBar++; } nToolBar = 0; while (nOriginal < pOriginalControls->GetCount() || nToolBar < GetControlCount()) { CXTPControl* pOriginal = nOriginal < pOriginalControls->GetCount() ? pOriginalControls->GetAt(nOriginal) : NULL; CXTPControl* pControl = nToolBar < GetControlCount() ? m_pControls->GetAt(nToolBar) : NULL; int nNearest = _FindNearest(m_pControls, pOriginal, nToolBar, TRUE); int nNearestOriginal = _FindNearest(pOriginalControls, pControl, nOriginal); if (nNearest == -1 && pOriginal) { int nSelected = m_nSelected; int nPopuped = m_nPopuped; pControl = m_pControls->AddClone(pOriginal, nToolBar); if (nPopuped != -1) m_nPopuped = nPopuped + (nToolBar <= nPopuped ? 1 : 0); if (nSelected != -1) m_nSelected = nSelected + (nToolBar <= nSelected ? 1 : 0); nNearestOriginal = nToolBar; pControl->SetHideFlag(xtpHideCustomize, TRUE); nOriginal++; nToolBar++; } else { if (nNearest == nToolBar) nOriginal++; else if (nNearestOriginal != -1) pOriginalControls->Remove(nNearestOriginal); nToolBar++; } ASSERT(pControl); if (!pControl) { continue; } if (pControl->GetID() == XTP_ID_TOOLBAR_HIDE || pControl->GetID() == XTP_ID_TOOLBAR_EXPAND) { continue; } if (pControl->GetAction() && !pControl->GetAction()->IsVisible()) continue; BeforeCustomizeControlAdd(pControl); if ((pControl->GetHideFlags() & (xtpHideGeneric | xtpHideDocTemplate | xtpHideRibbonTab)) != 0) { continue; } if (!pControl->IsCustomizeMovable()) { continue; } CControlButtonCustomize* pButton = (CControlButtonCustomize*)pExpandBar->GetControls()->Add(new CControlButtonCustomize(), 0); pButton->SetCaption(pControl->GetCaption()); XTPControlType controlType = pControl->GetType(); if ((controlType == xtpControlPopup) || (controlType == xtpControlButtonPopup) || (controlType == xtpControlSplitButtonPopup) || (controlType == xtpControlButton)) pButton->SetIconId(pControl->GetIconId()); CString strShortcut = pControl->m_strShortcutText; if (strShortcut.IsEmpty()) pCommandBars->GetShortcutManager()->FindDefaultAccelerator(pControl->GetID(), strShortcut); pButton->SetShortcutText(strShortcut); pButton->SetEnabled(nNearestOriginal != -1); pButton->SetChecked((pControl->GetHideFlags() & xtpHideCustomize) == 0); pButton->m_pControl = pControl; } pOriginalControls->InternalRelease(); if (m_pControls->m_pOriginalControls && !m_bTearOff && m_bBuiltIn) { CControlButtonCustomize* pButton = (CControlButtonCustomize*)pExpandBar->GetControls()->Add(new CControlButtonCustomize(), XTP_ID_CUSTOMIZE_RESET); pButton->SetFlags(xtpFlagManualUpdate); pButton->SetBeginGroup(TRUE); pButton->m_pToolBar = this; } } void CXTPToolBar::OnSetPreviewMode(BOOL bPreview) { if (m_bPreviewMode == bPreview) return; m_bPreviewMode = bPreview; if (bPreview) { m_bPreviewVisible = m_bVisible; if (m_bVisible) { m_bVisible = FALSE; ShowWindow(SW_HIDE); } } else if (m_bPreviewVisible) { m_bVisible = TRUE; ShowWindow(SW_SHOWNA); if (GetType() == xtpBarTypeMenuBar) { CFrameWnd* pFrameWnd = GetFrameSite(); if (pFrameWnd && pFrameWnd->GetSafeHwnd()) pFrameWnd->OnUpdateFrameMenu(0); } } } void CXTPToolBar::Copy(CXTPCommandBar* pCommandBar, BOOL bRecursive) { CXTPCommandBar::Copy(pCommandBar, bRecursive); m_bBuiltIn = ((CXTPToolBar*)pCommandBar)->m_bBuiltIn; m_bTearOff = ((CXTPToolBar*)pCommandBar)->m_bTearOff; m_bCloseable = ((CXTPToolBar*)pCommandBar)->m_bCloseable; } BOOL CXTPToolBar::OnHookKeyDown(UINT nChar, LPARAM lParam) { if (m_pDockContext == NULL && nChar == VK_TAB && GetParent()) { CWnd* pWndNext = GetParent()->GetNextDlgTabItem(this, (GetKeyState(VK_SHIFT) < 0)); if (pWndNext != NULL && pWndNext != this) { pWndNext->SetFocus(); SetTrackingMode(FALSE); return TRUE; } } return CXTPCommandBar::OnHookKeyDown(nChar, lParam); } void CXTPToolBar::OnSetFocus(CWnd* pOldWnd) { if (!m_hwndFocus && pOldWnd) m_hwndFocus = pOldWnd->GetSafeHwnd(); CXTPCommandBar::OnSetFocus(pOldWnd); if (m_pDockContext == NULL) { SetTrackingMode(TRUE, TRUE); } } BOOL CXTPToolBar::ShouldSerializeBar() { if (!IsCustomizable()) return FALSE; if (GetControls()->GetOriginalControls() && !GetControls()->IsChanged()) return FALSE; return TRUE; }