// XTPShortcutBarItem.cpp : implementation of the CXTPShortcutBar class. // // This file is a part of the XTREME SHORTCUTBAR 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/Resource.h" #include "Common/XTPResourceManager.h" #include "Common/XTPDrawHelpers.h" #include "Common/XTPToolTipContext.h" #include "Common/XTPImageManager.h" #include "Common/XTPSystemHelpers.h" #include "Common/XTPColorManager.h" #include "Common/XTPHookManager.h" #ifdef _XTP_INCLUDE_COMMANDBARS #include "CommandBars/Resource.h" #include "CommandBars/XTPCommandBarsDefines.h" #include "CommandBars/XTPCommandBar.h" #include "CommandBars/XTPToolBar.h" #include "CommandBars/XTPCommandBars.h" #include "CommandBars/XTPPopupBar.h" #include "CommandBars/XTPControls.h" #include "CommandBars/XTPControl.h" #include "CommandBars/XTPControlButton.h" #include "CommandBars/XTPControlPopup.h" #include "CommandBars/XTPMouseManager.h" #endif #include "XTPShortcutBarPaintManager.h" #include "XTPShortcutBarPane.h" #include "XTPShortcutBar.h" #include "XTPShortcutBarPopup.h" #include "XTPShortcutBarAnimation.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif #define XTP_ID_SHORTCUT_SELECTED 8000 #define XTP_ID_SHORTCUT_CUSTOMIZE 8001 CXTPShortcutBarItem::CXTPShortcutBarItem(CXTPShortcutBar* pShortcutBar, int nID, CWnd* pWnd) { CString strCaption; if (nID > 0 && strCaption.LoadString((UINT)nID)) { m_strCaption = m_strTooltip = strCaption; int nShortCutPos = strCaption.Find ('\n'); if (nShortCutPos != -1) { m_strTooltip = strCaption.Mid(nShortCutPos + 1); m_strCaption = strCaption.Left (nShortCutPos); } } m_pShortcutBar = pShortcutBar; m_bVisible = TRUE; m_rcItem.SetRectEmpty(); m_hwndChild = pWnd ? pWnd->GetSafeHwnd() : NULL; m_nID = nID; m_bExpandButton = FALSE; m_dwData = 0; m_bSelected = FALSE; m_nIconId = -1; m_bExpanded = FALSE; m_bHidden = FALSE; m_bEnabled = TRUE; m_bNavigateButton = FALSE; EnableAutomation(); } CXTPImageManagerIcon* CXTPShortcutBarItem::GetImage(int nWidth) const { return m_pShortcutBar->GetImageManager()->GetImage(GetIconId(), nWidth); } void CXTPShortcutBarItem::SetClientWindow(CWnd* pWnd) { if (m_hwndChild) { ::ShowWindow(m_hwndChild, SW_HIDE); } m_hwndChild = pWnd->GetSafeHwnd(); m_pShortcutBar->Reposition(); } void CXTPShortcutBarItem::SetCaption(LPCTSTR lpszCaption) { CString strCaption(lpszCaption); if (m_strCaption != strCaption) { m_strCaption = strCaption; m_pShortcutBar->RedrawControl(); } } int CXTPShortcutBarItem::GetIconId() const { return m_nIconId <= 0 ? m_nID: m_nIconId; } void CXTPShortcutBarItem::SetIconId(int nId) { if (m_nIconId != nId) { m_nIconId = nId; m_pShortcutBar->RedrawControl(); } } void CXTPShortcutBarItem::SetTooltip(LPCTSTR strTooltip) { m_strTooltip = strTooltip; m_pShortcutBar->Reposition(); } void CXTPShortcutBarItem::SetID(int nID) { m_nID = nID; } int CXTPShortcutBarItem::GetID() const { return m_nID; } BOOL CXTPShortcutBarItem::IsSelected() const { if (m_pShortcutBar->IsSingleSelection()) return m_pShortcutBar->GetSelectedItem() == this; return m_bSelected; } void CXTPShortcutBarItem::SetSelected(BOOL bSelected) { if (m_pShortcutBar->IsSingleSelection()) { if (bSelected) { m_pShortcutBar->SelectItem(this); } } else { m_bSelected = bSelected; m_pShortcutBar->RedrawControl(); } } void CXTPShortcutBarItem::SetVisible(BOOL bVisible) { if (m_bVisible != bVisible) { m_bVisible = bVisible; m_pShortcutBar->Reposition(); } } BOOL CXTPShortcutBarItem::IsVisible() const { return m_bVisible; } BOOL CXTPShortcutBarItem::IsHidden() const { return m_bHidden; } BOOL CXTPShortcutBarItem::IsEnabled() const { return m_bEnabled; } void CXTPShortcutBarItem::SetEnabled(BOOL bEnabled) { if (m_bEnabled != bEnabled) { m_bEnabled = bEnabled; m_pShortcutBar->RedrawControl(); } } ///////////////////////////////////////////////////////////////////////////// // CXTPShortcutBar CXTPShortcutBar::CXTPShortcutBar() { m_pPaintManager = new CXTPShortcutBarOffice2003Theme; m_pPaintManager->RefreshMetrics(); m_paintTheme = xtpShortcutThemeOffice2003; m_nExpandedLines = 1; m_nDesiredExpandedLinesHeight = 0; m_szItem = CSize(22, 32); m_rcClient.SetRectEmpty(); // Add expand button m_arrItems.Add(CreateConfigureButton()); m_pNavigationPaneItem = CreateNavigationItem(); m_hSizeCursor = AfxGetApp()->LoadStandardCursor(MAKEINTRESOURCE(IDC_SIZENS)); m_bTrackingSize = FALSE; m_pPressedItem = m_pSelectedItem = m_pHotItem = NULL; m_hwndClient = NULL; m_nMinClientHeight = 200; m_bAllowResize = TRUE; m_bClientPaneVisible = TRUE; m_pImageManager = NULL; m_bSingleSelection = TRUE; m_bShowActiveItemOnTop = FALSE; m_bAllowFreeResize = FALSE; m_bAllowCollapse = TRUE; m_bShowGripper = TRUE; m_hHandCursor = AfxGetApp()->LoadStandardCursor(MAKEINTRESOURCE(32649)); if (m_hHandCursor == 0) m_hHandCursor = XTPResourceManager()->LoadCursor(XTP_IDC_HAND); m_pToolTipContext = new CXTPToolTipContext; m_bPreSubclassWindow = TRUE; m_pAnimation = new CXTPShortcutBarAnimation(this); m_bAllowMinimize = FALSE; m_nMinimizedWidth = 32; m_bMinimized = FALSE; m_bShowMinimizeButton = FALSE; m_pActivePopup = NULL; RegisterWindowClass(); } CXTPShortcutBar::~CXTPShortcutBar() { CMDTARGET_RELEASE(m_pPaintManager); for (int i = 0; i < m_arrItems.GetSize(); i++) { m_arrItems[i]->InternalRelease(); } CMDTARGET_RELEASE(m_pImageManager); CMDTARGET_RELEASE(m_pToolTipContext); CMDTARGET_RELEASE(m_pNavigationPaneItem); delete m_pAnimation; } BOOL CXTPShortcutBar::RegisterWindowClass(HINSTANCE hInstance /*= NULL*/) { return XTPDrawHelpers()->RegisterWndClass(hInstance, _T("XTPShortcutBar"), 0); } void CXTPShortcutBar::RedrawControl(LPCRECT lpRect, BOOL bAnimate) { if (m_hWnd) { m_pAnimation->RedrawRect(lpRect, bAnimate); } } CXTPShortcutBarItem* CXTPShortcutBar::CreateNavigationItem() { CXTPShortcutBarItem* pItem = new CXTPShortcutBarItem(this, -1, 0); pItem->m_bNavigateButton = TRUE; CXTPResourceManager::AssertValid(XTPResourceManager()->LoadString(&pItem->m_strCaption, XTP_IDS_SHORTCUT_NAVIGATIONPANE)); return pItem; } CXTPShortcutBarItem* CXTPShortcutBar::CreateConfigureButton() { CXTPShortcutBarItem* pItem = new CXTPShortcutBarItem(this, -1, 0); pItem->m_bExpandButton = TRUE; CXTPResourceManager::AssertValid(XTPResourceManager()->LoadString(&pItem->m_strCaption, XTP_IDS_SHORTCUT_CONFIGURE)); pItem->m_strTooltip = pItem->m_strCaption; return pItem; } void CXTPShortcutBar::ShowExpandButton(BOOL bShow) { ASSERT(GetItemCount() > 0); ASSERT(GetItem(GetItemCount() - 1)->IsItemExpandButton()); if (GetItemCount() > 0) { GetItem(GetItemCount() - 1)->SetVisible(bShow); Reposition(); } } BOOL CXTPShortcutBar::IsExpandButtonVisible() const { ASSERT(GetItemCount() > 0); ASSERT(GetItem(GetItemCount() - 1)->IsItemExpandButton()); return GetItemCount() > 0 && GetItem(GetItemCount() - 1)->IsVisible(); } CXTPImageManager* CXTPShortcutBar::GetImageManager() const { return m_pImageManager ? m_pImageManager : XTPImageManager(); } void CXTPShortcutBar::SetImageManager(CXTPImageManager* pImageManager) { if (m_pImageManager) m_pImageManager->InternalRelease(); m_pImageManager = pImageManager; Reposition(); } BOOL CXTPShortcutBar::Create(DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID) { if (!CreateEx(0, _T("XTPShortcutBar"), NULL, dwStyle, rect, pParentWnd, nID)) { return FALSE; } return TRUE; } BOOL CXTPShortcutBar::PreCreateWindow(CREATESTRUCT& cs) { if (!CWnd::PreCreateWindow(cs)) return FALSE; // // PreCreateWindow is called when a control is dynamically // created. We want to set m_bPreSubclassWindow to FALSE // here so the control is initialized from CWnd::Create and // not CWnd::PreSubclassWindow. // m_bPreSubclassWindow = FALSE; return TRUE; } void CXTPShortcutBar::PreSubclassWindow() { CWnd::PreSubclassWindow(); if (m_bPreSubclassWindow) Reposition(); } void CXTPShortcutBar::SetTheme(XTPShortcutBarPaintTheme paintTheme) { CMDTARGET_RELEASE(m_pPaintManager); if (paintTheme == xtpShortcutThemeOfficeXP) m_pPaintManager = new CXTPShortcutBarOfficeXPTheme(); else if (paintTheme == xtpShortcutThemeOffice2003) m_pPaintManager = new CXTPShortcutBarOffice2003Theme(); else if (paintTheme == xtpShortcutThemeOffice2007) m_pPaintManager = new CXTPShortcutBarOffice2007Theme(); else if (paintTheme == xtpShortcutThemeNativeWinXP) m_pPaintManager = new CXTPShortcutBarNativeWinXPTheme(); else m_pPaintManager = new CXTPShortcutBarOffice2000Theme(); m_paintTheme = paintTheme; m_pPaintManager->RefreshMetrics(); if (m_hWnd) { Reposition(); RedrawControl(); SetWindowPos(0, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE | SWP_FRAMECHANGED); } } BOOL CXTPShortcutBar::IsShortcutBarMinimized() const { return m_bMinimized; } void CXTPShortcutBar::SetCustomTheme(CXTPShortcutBarPaintManager* pPaintManager) { if (!pPaintManager) return; CMDTARGET_RELEASE(m_pPaintManager); m_pPaintManager = pPaintManager; m_pPaintManager->RefreshMetrics(); Reposition(); RedrawControl(); } void CXTPShortcutBar::SetExpandedLinesCount(int nLinesCount) { m_nDesiredExpandedLinesHeight = nLinesCount * m_szItem.cy; Reposition(); } void CXTPShortcutBar::SetExpandedLinesHeight(int nHeight) { m_nDesiredExpandedLinesHeight = nHeight; Reposition(); } CXTPShortcutBarItem* CXTPShortcutBar::AddItem(UINT nID, CWnd* pWnd) { CXTPShortcutBarItem* pItem = new CXTPShortcutBarItem(this, nID, pWnd); m_arrItems.InsertAt(m_arrItems.GetSize() - 1, pItem); Reposition(); return pItem; } int CXTPShortcutBar::GetVisibleItemsCount() const { int nCount = 0; for (int i = 0; i < m_arrItems.GetSize(); i++) { if (m_arrItems[i]->m_bVisible) nCount++; } return nCount; } int CXTPShortcutBar::GetCollapsedItemsCount() const { int nCount = 0; for (int i = 0; i < m_arrItems.GetSize(); i++) { if (m_arrItems[i]->m_bVisible && !m_arrItems[i]->m_bHidden && !m_arrItems[i]->m_bExpanded) nCount++; } return nCount; } void CXTPShortcutBar::Reposition() { if (!m_hWnd) return; static BOOL bReposition = FALSE; if (bReposition) return; bReposition = TRUE; CXTPClientRect rcShortcutBar(this); int nWidth = rcShortcutBar.Width(); int nHeight = rcShortcutBar.Height(); int nGripperHeight = m_bShowGripper ? m_pPaintManager->DrawGripper(NULL, this, FALSE) : 0; BOOL bMinimized = m_bAllowMinimize && rcShortcutBar.Width() <= m_nMinimizedWidth; if (bMinimized != m_bMinimized) { m_bMinimized = bMinimized; if (m_bMinimized && m_hwndClient) ::ShowWindow(m_hwndClient, SW_HIDE); if (!m_bMinimized && m_hwndClient) ::ShowWindow(m_hwndClient, SW_SHOW); } for (int nItem = 0; nItem < m_arrItems.GetSize(); nItem++) m_arrItems[nItem]->m_bHidden = FALSE; int nVisibleItemsCount = GetVisibleItemsCount(); BOOL bShowActiveItemOnTop = m_bShowActiveItemOnTop && m_bClientPaneVisible; int nExpandedItem = 0; if (!m_bClientPaneVisible) { m_nExpandedLines = nVisibleItemsCount; nGripperHeight = 0; m_rcGripper.SetRectEmpty(); m_rcClient.SetRectEmpty(); nHeight = min(nHeight, m_nExpandedLines * m_szItem.cy); if (nHeight - m_nExpandedLines * m_szItem.cy < 0) { m_nExpandedLines = nHeight/ m_szItem.cy; nHeight = m_nExpandedLines * m_szItem.cy; } nHeight--; } else { int nTopItemHeight = 0; if (bShowActiveItemOnTop) { for (; nExpandedItem < m_arrItems.GetSize(); nExpandedItem++) { CXTPShortcutBarItem* pItem = GetItem(nExpandedItem); if (!pItem->m_bVisible) continue; pItem->m_bExpanded = TRUE; pItem->m_rcItem.SetRect(0, nTopItemHeight, nWidth, nTopItemHeight + m_szItem.cy); nVisibleItemsCount--; nTopItemHeight += m_szItem.cy; if (m_pSelectedItem == pItem) break; } } int nClientHeight = 0; int nMinClientHeight = m_nMinClientHeight; CXTPShortcutBarPane* pPaneClient = DYNAMIC_DOWNCAST(CXTPShortcutBarPane, CWnd::FromHandle(m_hwndClient)); if (pPaneClient) nMinClientHeight = max(nMinClientHeight, pPaneClient->GetMinimumClientHeight()); if (bShowActiveItemOnTop && m_hwndClient == NULL) { nGripperHeight = 0; nClientHeight = nTopItemHeight; nMinClientHeight = 0; m_nExpandedLines = (nHeight - nClientHeight - nGripperHeight) / m_szItem.cy; if (m_nExpandedLines > nVisibleItemsCount) { m_nExpandedLines = nVisibleItemsCount; } if ((m_nExpandedLines < nVisibleItemsCount) && !m_bAllowCollapse) { nClientHeight = nHeight - nGripperHeight - m_szItem.cy * nVisibleItemsCount; m_nExpandedLines = nVisibleItemsCount; } if (m_nExpandedLines < 1) { nClientHeight = nHeight - nGripperHeight - m_szItem.cy; m_nExpandedLines = 1; } } else if (m_bAllowFreeResize) { nClientHeight = nHeight - m_nDesiredExpandedLinesHeight - nGripperHeight; if (nClientHeight - nTopItemHeight < nMinClientHeight) { nClientHeight = nMinClientHeight + nTopItemHeight; } m_nExpandedLines = (nHeight - nClientHeight - nGripperHeight) / m_szItem.cy; if (m_nExpandedLines > nVisibleItemsCount) { m_nExpandedLines = nVisibleItemsCount; } if ((m_nExpandedLines < nVisibleItemsCount) && !m_bAllowCollapse) { nClientHeight = nHeight - nGripperHeight - m_szItem.cy * nVisibleItemsCount; m_nExpandedLines = nVisibleItemsCount; } if (m_nExpandedLines < 1) { nClientHeight = nHeight - nGripperHeight - m_szItem.cy; m_nExpandedLines = 1; } } else { m_nExpandedLines = m_nDesiredExpandedLinesHeight / m_szItem.cy; if (nHeight - nTopItemHeight - m_nExpandedLines * m_szItem.cy - nGripperHeight < nMinClientHeight) { m_nExpandedLines = (nHeight - nTopItemHeight - nGripperHeight - nMinClientHeight) / m_szItem.cy; } if (m_nExpandedLines > nVisibleItemsCount || !m_bAllowCollapse) m_nExpandedLines = nVisibleItemsCount; if (m_nExpandedLines < 1) m_nExpandedLines = 1; nClientHeight = nHeight - m_nExpandedLines * m_szItem.cy - nGripperHeight; } m_rcGripper.SetRect(0, nClientHeight, nWidth, nClientHeight + nGripperHeight); m_rcClient.SetRect(0, nTopItemHeight, nWidth, nClientHeight); if (bShowActiveItemOnTop && nVisibleItemsCount == 0) { m_rcClient.SetRect(0, nTopItemHeight, nWidth, nHeight); m_rcGripper.SetRectEmpty(); } } BOOL bExpandButtonVisible = IsExpandButtonVisible(); int nExpandedLines = m_nExpandedLines; for (; nExpandedItem < m_arrItems.GetSize(); nExpandedItem++) { CXTPShortcutBarItem* pItem = GetItem(nExpandedItem); if (!pItem->m_bVisible) continue; if (m_pSelectedItem == pItem && bShowActiveItemOnTop) continue; if ((!(nExpandedLines == 1 && !bExpandButtonVisible && nVisibleItemsCount == 1)) && (nExpandedLines < 2)) break; pItem->m_bExpanded = TRUE; int nItemTop = m_rcGripper.bottom + (m_nExpandedLines - nExpandedLines) * m_szItem.cy; pItem->m_rcItem.SetRect(0, nItemTop, nWidth, nItemTop + m_szItem.cy); nExpandedLines--; nVisibleItemsCount--; } int nCollapsedCount = min(nVisibleItemsCount, nWidth / m_szItem.cx) - 1; int nCollapsedPos = nWidth - m_szItem.cx * (nCollapsedCount + 1); for (int nCollapsedItem = nExpandedItem; nCollapsedItem < m_arrItems.GetSize(); nCollapsedItem++) { CXTPShortcutBarItem* pItem = GetItem(nCollapsedItem); if (!pItem->m_bVisible) continue; if (m_pSelectedItem == pItem && bShowActiveItemOnTop) continue; pItem->m_bExpanded = FALSE; if (pItem->IsItemExpandButton()) pItem->m_rcItem.SetRect(nWidth - m_szItem.cx, rcShortcutBar.Height() - m_szItem.cy, nWidth, rcShortcutBar.Height()); else if ((nCollapsedCount > 0) || ((nCollapsedCount == 0) && !bExpandButtonVisible)) pItem->m_rcItem.SetRect(nCollapsedPos, rcShortcutBar.Height() - m_szItem.cy, nCollapsedPos + m_szItem.cx, rcShortcutBar.Height()); else pItem->m_bHidden = TRUE; nCollapsedPos += m_szItem.cx; nCollapsedCount--; } if (m_hwndClient && !m_bMinimized) { ::MoveWindow(m_hwndClient, m_rcClient.left, m_rcClient.top, m_rcClient.Width(), m_rcClient.Height(), TRUE); } if (m_bMinimized) { m_pNavigationPaneItem->m_rcItem = m_rcClient; m_pNavigationPaneItem->m_bVisible = TRUE; } else { m_pNavigationPaneItem->m_rcItem.SetRectEmpty(); m_pNavigationPaneItem->m_bVisible = FALSE; } RedrawControl(); bReposition = FALSE; OnRepositionDone(); } void CXTPShortcutBar::OnRepositionDone() { } INT_PTR CXTPShortcutBar::OnToolHitTest(CPoint point, TOOLINFO* pTI) const { ASSERT_VALID(this); ASSERT(::IsWindow(m_hWnd)); // check child windows first by calling CControlBar INT_PTR nHit = CWnd::OnToolHitTest(point, pTI); if (nHit != -1) return nHit; #if !defined(_XTP_ACTIVEX) && defined(_XTP_INCLUDE_COMMANDBARS) if (XTPMouseManager()->IsTrackedLock(NULL) || XTPMouseManager()->IsMouseLocked()) return -1; #endif CXTPShortcutBarItem* pItem = HitTest(point); if (!pItem) return -1; CClientDC dc(CWnd::FromHandle(m_hWnd)); BOOL bShowToolTip = !pItem->IsExpanded() || GetPaintManager()->IsShortcutItemTruncated(&dc, pItem); if (bShowToolTip) { nHit = pItem->GetID(); if (pItem->IsItemExpandButton()) nHit = XTP_IDS_SHORTCUT_CONFIGURE; CString strTip = pItem->GetTooltip(); if (strTip.GetLength() == 0) return -1; CXTPToolTipContext::FillInToolInfo(pTI, m_hWnd, pItem->GetItemRect(), nHit, strTip, pItem->GetCaption(), strTip, GetImageManager()); return nHit; } return -1; } CXTPShortcutBarItem* CXTPShortcutBar::HitTest(CPoint pt) const { if (m_pNavigationPaneItem->m_bVisible && m_pNavigationPaneItem->m_rcItem.PtInRect(pt)) return m_pNavigationPaneItem; for (int i = 0; i < m_arrItems.GetSize(); i++) { CXTPShortcutBarItem* pItem = m_arrItems[i]; if (pItem->m_bVisible && pItem->IsEnabled() && !pItem->m_bHidden && pItem->m_rcItem.PtInRect(pt)) return m_arrItems[i]; } return NULL; } void CXTPShortcutBar::SetHotItem(CXTPShortcutBarItem* pItem) { if (m_pHotItem == pItem) return; CXTPShortcutBarItem* pHotItem = m_pHotItem; m_pHotItem = pItem; if (pHotItem) RedrawControl(pHotItem->GetItemRect(), TRUE); if (m_pHotItem) RedrawControl(m_pHotItem->GetItemRect(), FALSE); if (m_pHotItem) { TRACKMOUSEEVENT tme = { sizeof(TRACKMOUSEEVENT), TME_LEAVE, m_hWnd, 0 }; _TrackMouseEvent(&tme); } } void CXTPShortcutBar::SelectItem(CXTPShortcutBarItem* pItem) { if (!pItem) return; if (pItem->IsItemExpandButton()) { OnExpandButtonDown(pItem); return; } if (pItem->m_bNavigateButton) { OnNavigateButtonDown(pItem); return; } if ((m_pSelectedItem == pItem) && m_bSingleSelection) return; if (GetOwner()->SendMessage(XTPWM_SHORTCUTBAR_NOTIFY, XTP_SBN_SELECTION_CHANGING, (LPARAM)pItem) == -1) return; if (pItem->m_hwndChild != m_hwndClient) { if (m_hwndClient) { ::ShowWindow(m_hwndClient, SW_HIDE); } m_hwndClient = pItem->m_hwndChild; if (m_hwndClient && !m_bMinimized) { ::ShowWindow(m_hwndClient, SW_SHOW); } } if (m_bSingleSelection) { m_pSelectedItem = pItem; } else { pItem->m_bSelected = !pItem->m_bSelected; } Reposition(); GetOwner()->SendMessage(XTPWM_SHORTCUTBAR_NOTIFY, XTP_SBN_SELECTION_CHANGED, (LPARAM)pItem); } void CXTPShortcutBar::OnNavigateButtonDown(CXTPShortcutBarItem* pNavigateButton) { if (m_pActivePopup) return; SetHotItem(NULL); CXTPShortcutBarItem* pItem = GetSelectedItem(); if (!pItem) return; HWND hwndChild = pItem->m_hwndChild; if (!hwndChild) return; pNavigateButton->m_bExpanded = TRUE; RedrawControl(); m_pActivePopup = new CXTPShortcutBarPopup(this, hwndChild); m_pActivePopup->DoModal(); SAFE_DELETE(m_pActivePopup); pNavigateButton->m_bExpanded = FALSE; RedrawControl(); } void CXTPShortcutBar::OnExpandButtonDown(CXTPShortcutBarItem* pExpandButton) { #ifdef _XTP_INCLUDE_COMMANDBARS CXTPPopupBar* pPopup = CXTPPopupBar::CreatePopupBar(NULL); if (m_bClientPaneVisible) { pPopup->GetControls()->Add(xtpControlButton, XTP_ID_SHORTCUT_SHOW_MORE); pPopup->GetControls()->Add(xtpControlButton, XTP_ID_SHORTCUT_SHOW_FEWER); } CXTPControlPopup* pControlAddOrRemove = (CXTPControlPopup*)pPopup->GetControls()->Add(xtpControlPopup, XTP_ID_CUSTOMIZE_ADDORREMOVE); pControlAddOrRemove->SetFlags(xtpFlagManualUpdate); for (int j = 0; j < m_arrItems.GetSize() - 1; j++) { CXTPShortcutBarItem* pItem = m_arrItems[j]; CXTPControl* pControl = pControlAddOrRemove->GetCommandBar()->GetControls()->Add(xtpControlButton, XTP_ID_SHORTCUT_CUSTOMIZE); pControl->SetIconId(pItem->GetID()); pControl->SetCaption(pItem->GetCaption()); pControl->SetTag((DWORD_PTR)pItem); pControl->SetChecked(pItem->m_bVisible); pControl->SetFlags(xtpFlagManualUpdate); } BOOL bBeginGroup = TRUE; for (int i = 0; i < m_arrItems.GetSize(); i++) { CXTPShortcutBarItem* pItem = m_arrItems[i]; if (pItem->m_bVisible && pItem->m_bHidden) { CXTPControl* pControl = pPopup->GetControls()->Add(xtpControlButton, XTP_ID_SHORTCUT_SELECTED); pControl->SetIconId(pItem->GetID()); pControl->SetCaption(pItem->GetCaption()); pControl->SetTag((DWORD_PTR)pItem); pControl->SetFlags(xtpFlagManualUpdate); pControl->SetBeginGroup(bBeginGroup); bBeginGroup = FALSE; } } CPoint pt(pExpandButton->GetItemRect().right, pExpandButton->GetItemRect().CenterPoint().y); ClientToScreen(&pt); CXTPCommandBars::TrackPopupMenu(pPopup, 0, pt.x, pt.y, this); pPopup->InternalRelease(); SetHotItem(NULL); #else CMenu menu; menu.CreatePopupMenu(); if (m_bClientPaneVisible) { CString str; XTPResourceManager()->LoadString(&str, XTP_ID_SHORTCUT_SHOW_MORE); menu.AppendMenu(MF_STRING, XTP_ID_SHORTCUT_SHOW_MORE, str); if (GetVisibleItemsCount() == m_nExpandedLines) menu.EnableMenuItem(XTP_ID_SHORTCUT_SHOW_MORE, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED); XTPResourceManager()->LoadString(&str, XTP_ID_SHORTCUT_SHOW_FEWER); menu.AppendMenu(MF_STRING, XTP_ID_SHORTCUT_SHOW_FEWER, str); if (m_nExpandedLines <= 1) menu.EnableMenuItem(XTP_ID_SHORTCUT_SHOW_FEWER, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED); } BOOL bBeginGroup = m_bClientPaneVisible; for (int i = 0; i < m_arrItems.GetSize(); i++) { CXTPShortcutBarItem* pItem = m_arrItems[i]; if (pItem->m_bVisible && pItem->m_bHidden) { if (bBeginGroup) { menu.AppendMenu(MF_SEPARATOR); } menu.AppendMenu(MF_STRING, i + 1, pItem->GetCaption()); bBeginGroup = FALSE; } } CPoint pt(pExpandButton->GetItemRect().right, pExpandButton->GetItemRect().CenterPoint().y); ClientToScreen(&pt); int nCmd = menu.TrackPopupMenu(TPM_RETURNCMD, pt.x, pt.y, this); if (nCmd > 0) { if (nCmd > m_arrItems.GetSize()) SendMessage(WM_COMMAND, nCmd); else { SelectItem(m_arrItems[nCmd - 1]); } } #endif } BEGIN_MESSAGE_MAP(CXTPShortcutBar, CWnd) //{{AFX_MSG_MAP(CXTPShortcutBar) ON_WM_PAINT() ON_MESSAGE(WM_PRINTCLIENT, OnPrintClient) ON_WM_ERASEBKGND() ON_WM_SIZE() ON_WM_CREATE() ON_WM_TIMER() ON_WM_NCPAINT() ON_WM_NCCALCSIZE() ON_WM_SETCURSOR() ON_WM_MOUSEMOVE() ON_WM_LBUTTONDOWN() ON_WM_LBUTTONUP() ON_WM_CAPTURECHANGED() ON_MESSAGE_VOID(WM_MOUSELEAVE, OnMouseLeave) ON_WM_SYSCOLORCHANGE() ON_COMMAND(XTP_ID_SHORTCUT_SHOW_MORE, OnShowMoreButtons) ON_COMMAND(XTP_ID_SHORTCUT_SHOW_FEWER, OnShowFewerButtons) ON_UPDATE_COMMAND_UI(XTP_ID_SHORTCUT_SHOW_MORE, OnUpdateShowMoreButtons) ON_UPDATE_COMMAND_UI(XTP_ID_SHORTCUT_SHOW_FEWER, OnUpdateShowFewerButtons) ON_WM_RBUTTONDOWN() ON_WM_RBUTTONUP() ON_WM_DESTROY() ON_WM_SETFOCUS() //}}AFX_MSG_MAP #ifdef _XTP_INCLUDE_COMMANDBARS ON_MESSAGE(WM_XTP_COMMAND, OnExpandPopupExecute) #endif END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CXTPShortcutBar message handlers void CXTPShortcutBar::OnPaint() { CPaintDC paintDC(this); m_pAnimation->OnPaint(paintDC); } LRESULT CXTPShortcutBar::OnPrintClient(WPARAM wParam, LPARAM /*lParam*/) { CDC* pDC = CDC::FromHandle((HDC)wParam); if (pDC) { OnDraw(pDC, CXTPClientRect(this)); } return TRUE; } void CXTPShortcutBar::OnDraw(CDC* pDC, CRect /*rcClipBox*/) { CXTPClientRect rc(this); m_pPaintManager->FillShortcutBar(pDC, this); if (m_bClientPaneVisible && m_bShowGripper && !m_rcGripper.IsRectEmpty()) m_pPaintManager->DrawGripper(pDC, this, TRUE); if (m_pNavigationPaneItem->m_bVisible) { m_pPaintManager->DrawNavigationItem(pDC, m_pNavigationPaneItem); } for (int i = 0; i < m_arrItems.GetSize(); i++) { CXTPShortcutBarItem* pItem = m_arrItems[i]; if (!pItem->m_bVisible || pItem->m_bHidden) continue; m_pPaintManager->DrawShortcutItem(pDC, pItem); } } BOOL CXTPShortcutBar::OnEraseBkgnd(CDC* /*pDC*/) { return TRUE; } void CXTPShortcutBar::OnSize(UINT nType, int cx, int cy) { CWnd::OnSize(nType, cx, cy); Reposition(); } void CXTPShortcutBar::OnTimer(UINT_PTR nIDEvent) { switch (nIDEvent) { case XTP_TID_ANIMATION: m_pAnimation->OnAnimate(); return; } CWnd::OnTimer(nIDEvent); } void CXTPShortcutBar::OnDestroy() { m_pAnimation->OnDestroy(); CWnd::OnDestroy(); } int CXTPShortcutBar::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (CWnd::OnCreate(lpCreateStruct) == -1) return -1; Reposition(); return 0; } void CXTPShortcutBar::OnNcCalcSize(BOOL /*bCalcValidRects*/, NCCALCSIZE_PARAMS* lpncsp) { if (m_pPaintManager->m_bShowBorder) { RECT& rc = lpncsp->rgrc[0]; rc.left += 1; rc.top += 1; rc.right -= 1; rc.bottom -= 1; } } void CXTPShortcutBar::OnNcPaint() { CWindowDC dc(this); // device context for painting if (m_pPaintManager->m_bShowBorder) { m_pPaintManager->DrawShortcutBarFrame(&dc, this); } } BOOL CXTPShortcutBar::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message) { CPoint pt; GetCursorPos(&pt); ScreenToClient(&pt); if ((m_bTrackingSize || m_rcGripper.PtInRect(pt)) && m_bAllowResize && m_bShowGripper) { ::SetCursor(m_hSizeCursor); return TRUE; } if (m_pHotItem != NULL && m_hHandCursor) { ::SetCursor(m_hHandCursor); return TRUE; } return CWnd::OnSetCursor(pWnd, nHitTest, message); } void CXTPShortcutBar::OnMouseMove(UINT nFlags, CPoint point) { #ifdef _XTP_INCLUDE_COMMANDBARS if (XTPMouseManager()->IsTrackedLock(0)) return; #endif if (m_bTrackingSize) { CXTPClientRect rc(this); SetExpandedLinesHeight(rc.Height() - point.y); } else { CXTPShortcutBarItem* pItem = HitTest(point); if (pItem != m_pHotItem) { SetHotItem(pItem); } } CWnd::OnMouseMove(nFlags, point); } void CXTPShortcutBar::OnLButtonDown(UINT nFlags, CPoint point) { if (m_rcGripper.PtInRect(point) && m_bAllowResize) { m_bTrackingSize = TRUE; SetCapture(); return; } CXTPShortcutBarItem* pItem = HitTest(point); if (pItem) { m_pPressedItem = pItem; RedrawControl(); SetCapture(); return; } CWnd::OnLButtonDown(nFlags, point); } void CXTPShortcutBar::OnLButtonUp(UINT nFlags, CPoint point) { CWnd::OnLButtonUp(nFlags, point); m_bTrackingSize = FALSE; CXTPShortcutBarItem* pPressedItem = m_pPressedItem; m_pPressedItem = NULL; ReleaseCapture(); if (pPressedItem) { if (m_pHotItem == pPressedItem) { SelectItem(pPressedItem); } else { RedrawControl(); } } } void CXTPShortcutBar::OnCaptureChanged(CWnd* pWnd) { m_bTrackingSize = FALSE; if (m_pPressedItem) { m_pPressedItem = NULL; RedrawControl(); } CWnd::OnCaptureChanged(pWnd); } void CXTPShortcutBar::OnRButtonDown(UINT nFlags, CPoint point) { OnMouseMove(nFlags, point); GetOwner()->SendMessage(XTPWM_SHORTCUTBAR_NOTIFY, XTP_SBN_RCLICK, MAKELONG(point.x, point.y)); GetCursorPos(&point); ScreenToClient(&point); OnMouseMove(nFlags, point); CWnd::OnRButtonDown(nFlags, point); } void CXTPShortcutBar::OnRButtonUp(UINT nFlags, CPoint point) { CWnd::OnRButtonUp(nFlags, point); } void CXTPShortcutBar::OnMouseLeave() { #ifdef _XTP_INCLUDE_COMMANDBARS if (!XTPMouseManager()->IsTrackedLock(0)) #endif SetHotItem(NULL); } void CXTPShortcutBar::OnSysColorChange() { CWnd::OnSysColorChange(); m_pPaintManager->RefreshMetrics(); Reposition(); } CXTPShortcutBarItem* CXTPShortcutBar::FindItem(int nID) const { for (int i = 0; i < m_arrItems.GetSize(); i++) { if (m_arrItems[i]->GetID() == nID) return m_arrItems[i]; } return NULL; } void CXTPShortcutBar::LoadState(LPCTSTR lpszProfileName) { m_nDesiredExpandedLinesHeight = AfxGetApp()->GetProfileInt(lpszProfileName, _T("DesiredExpandedLinesHeight"), m_nDesiredExpandedLinesHeight); CDWordArray arrHiddenItems; LPBYTE lpbData; UINT dwDataSize; if (AfxGetApp()->GetProfileBinary(lpszProfileName, _T("Hidden"), &lpbData, &dwDataSize)) { try { CMemFile file(lpbData, dwDataSize); CArchive ar (&file, CArchive::load); arrHiddenItems.Serialize(ar); for (int i = 0; i < arrHiddenItems.GetSize(); i++) { CXTPShortcutBarItem* pItem = FindItem(arrHiddenItems[i]); if (pItem && !pItem->IsItemExpandButton()) pItem->m_bVisible = FALSE; } } catch (CMemoryException* pEx) { pEx->Delete (); } catch (CArchiveException* pEx) { pEx->Delete (); } delete[] lpbData; } Reposition(); } void CXTPShortcutBar::SaveState(LPCTSTR lpszProfileName) { AfxGetApp()->WriteProfileInt(lpszProfileName, _T("DesiredExpandedLinesHeight"), m_nDesiredExpandedLinesHeight); CDWordArray arrHiddenItems; for (int i = 0; i < m_arrItems.GetSize(); i++) { if (!m_arrItems[i]->IsVisible() && !m_arrItems[i]->IsItemExpandButton()) arrHiddenItems.Add(m_arrItems[i]->GetID()); } try { CMemFile file; CArchive ar (&file, CArchive::store); arrHiddenItems.Serialize(ar); ar.Flush (); DWORD dwDataSize = (DWORD)file.GetPosition(); LPBYTE lpbData = file.Detach(); AfxGetApp()->WriteProfileBinary(lpszProfileName, _T("Hidden"), lpbData, dwDataSize); ar.Close(); file.Close(); free (lpbData); } catch (CMemoryException* pEx) { pEx->Delete (); } catch (CArchiveException* pEx) { pEx->Delete (); } } int CXTPShortcutBar::GetItemCount() const { return (int)m_arrItems.GetSize(); } CXTPShortcutBarItem* CXTPShortcutBar::GetItem(int nIndex) const { if (nIndex >= 0 && nIndex < m_arrItems.GetSize()) return m_arrItems[nIndex]; return NULL; } void CXTPShortcutBar::RemoveItem(int nID) { m_pHotItem = NULL; m_pPressedItem = NULL; for (int i = 0; i < m_arrItems.GetSize(); i++) { CXTPShortcutBarItem* pItem = m_arrItems[i]; if (pItem->GetID() == nID) { if (pItem == m_pSelectedItem) m_pSelectedItem = NULL; m_arrItems.RemoveAt(i); pItem->InternalRelease(); Reposition(); return; } } } void CXTPShortcutBar::RemoveAllItems() { m_pHotItem = NULL; m_pPressedItem = NULL; m_pSelectedItem = NULL; for (int i = (int)m_arrItems.GetSize() - 1; i >= 0 ; i--) { CXTPShortcutBarItem* pItem = m_arrItems[i]; if (!pItem->IsItemExpandButton()) { m_arrItems.RemoveAt(i); pItem->InternalRelease(); } } Reposition(); } void CXTPShortcutBar::OnShowMoreButtons() { SetExpandedLinesCount(m_nExpandedLines + 1); } void CXTPShortcutBar::OnShowFewerButtons() { SetExpandedLinesCount(m_nExpandedLines - 1); } void CXTPShortcutBar::EnableAnimation(BOOL bEnable) { m_pAnimation->m_bAnimation = bEnable; RedrawControl(); } void CXTPShortcutBar::OnUpdateShowMoreButtons(CCmdUI* pCmdUI) { pCmdUI->Enable(GetVisibleItemsCount() != m_nExpandedLines); } void CXTPShortcutBar::OnUpdateShowFewerButtons(CCmdUI* pCmdUI) { pCmdUI->Enable(m_nExpandedLines > 1); } CXTPToolTipContext* CXTPShortcutBar::GetToolTipContext() const { return m_pToolTipContext; } BOOL CXTPShortcutBar::OnWndMsg(UINT message, WPARAM wParam, LPARAM lParam, LRESULT* pResult) { if (m_pToolTipContext) { m_pToolTipContext->FilterToolTipMessage(this, message, wParam, lParam); } return CWnd::OnWndMsg(message, wParam, lParam, pResult); } LRESULT CXTPShortcutBar::OnExpandPopupExecute(WPARAM wParam, LPARAM lParam) { #ifdef _XTP_INCLUDE_COMMANDBARS if (wParam == XTP_ID_SHORTCUT_SELECTED) { CXTPControl* pControl = ((NMXTPCONTROL*)lParam)->pControl; SelectItem((CXTPShortcutBarItem*)pControl->GetTag()); return 1; } if (wParam == XTP_ID_SHORTCUT_CUSTOMIZE) { CXTPControl* pControl = ((NMXTPCONTROL*)lParam)->pControl; CXTPShortcutBarItem* pItem = (CXTPShortcutBarItem*)pControl->GetTag(); pItem->m_bVisible = !pItem->m_bVisible; Reposition(); return 1; } #else wParam; lParam; #endif return 0; } void CXTPShortcutBar::SetLayoutRTL(BOOL bRightToLeft) { if (!XTPSystemVersion()->IsLayoutRTLSupported()) return; if (!m_hWnd) return; ModifyStyleEx(bRightToLeft ? 0 : WS_EX_LAYOUTRTL, !bRightToLeft ? 0 : WS_EX_LAYOUTRTL); GetImageManager()->DrawReverted(bRightToLeft); Reposition(); } void CXTPShortcutBar::OnMinimizeButtonClicked() { SetFocus(); GetOwner()->PostMessage(XTPWM_SHORTCUTBAR_NOTIFY, XTP_SBN_MINIMIZEBUTTONCLICKED, 0); } void CXTPShortcutBar::OnSetFocus(CWnd* pWnd) { CWnd::OnSetFocus(pWnd); if (m_pActivePopup) { m_pActivePopup->Close(); } }