// XTPDialogBar.cpp : implementation of the CXTPDialogBar 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/XTPSystemHelpers.h" #include "Common/XTPHookManager.h" #include "Common/XTPColorManager.h" #include "Common/XTPDrawHelpers.h" #include "XTPCommandBarsDefines.h" #include "XTPCommandBar.h" #include "XTPToolBar.h" #include "XTPDialogBar.h" #include "XTPControls.h" #include "XTPPaintManager.h" #include "XTPControl.h" #include "XTPControlButton.h" #include "XTPControlPopup.h" #include "XTPPopupBar.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif IMPLEMENT_XTP_COMMANDBAR(CXTPDialogBar, CXTPToolBar) class CXTPDialogBar::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); } }; void CXTPDialogBar::CControlButtonHide::Draw(CDC* pDC) { CFont font; font.CreatePointFont(MulDiv(80, 96, pDC->GetDeviceCaps(LOGPIXELSX)), _T("Marlett")); CFont* pFont = pDC->SelectObject(&font); GetPaintManager()->DrawControlEntry(pDC, this); pDC->SetTextColor(GetPaintManager()->GetControlTextColor(this)); pDC->SetBkMode(TRANSPARENT); pDC->DrawText(_T("r"), 1, m_rcControl, DT_SINGLELINE | DT_CENTER | DT_VCENTER); pDC->SelectObject(pFont); } class CXTPDialogBar::CControlCaptionPopup: public CXTPControlPopup { public: CControlCaptionPopup() { m_dwFlags = xtpFlagLeftPopup | xtpFlagManualUpdate | xtpFlagSkipFocus | xtpFlagNoMovable; m_bCaptionPopup = FALSE; } void Draw(CDC* pDC); void AdjustExcludeRect(CRect& rc, BOOL /*bVertical*/) { GetPaintManager()->AdjustExcludeRect(rc, this, FALSE); } BOOL OnSetPopup(BOOL bPopup) { if (m_bCaptionPopup) return CXTPControlPopup::OnSetPopup(bPopup); return TRUE; } public: BOOL m_bCaptionPopup; }; void CXTPDialogBar::CControlCaptionPopup::Draw(CDC* pDC) { CXTPPaintManager* pPaintManager = GetPaintManager(); CXTPFontDC font(pDC, pPaintManager->GetSmCaptionFont()); CRect rcButton = GetRect(); if (m_bCaptionPopup) { pPaintManager->DrawControlEntry(pDC, this); } pDC->SetTextColor(m_bCaptionPopup ? pPaintManager->GetControlTextColor(this) : GetXtremeColor(COLOR_BTNTEXT)); CRect rcText(rcButton); rcText.DeflateRect(2, 0, m_bCaptionPopup ? 15 : 2, 0); pDC->DrawText(GetCaption(), rcText, DT_SINGLELINE | DT_VCENTER); COLORREF clrText = pDC->GetTextColor(); if (m_bCaptionPopup) { CPoint pt = CPoint(rcButton.right - 9, rcButton.top + rcButton.Height()/2); pPaintManager->Triangle(pDC, CPoint(pt.x -4 , pt.y - 2), CPoint(pt.x + 4, pt.y - 2), CPoint (pt.x, pt.y + 2), clrText); } } class CXTPDialogBar::CCaptionPopupBar: public CXTPPopupBar { public: CCaptionPopupBar() { m_popupFlags = xtpPopupDown; } void UpdateFlags() { CXTPPopupBar::UpdateFlags(); m_popupFlags = xtpPopupDown | xtpPopupLeft; m_ptPopup.x = (m_popupFlags & xtpPopupDown) ? m_rcExclude.left : m_rcExclude.right; m_ptPopup.y = (m_popupFlags & xtpPopupDown) ? m_rcExclude.bottom : m_rcExclude.top; } }; ///////////////////////////////////////////////////////////////////////////// // CXTPDialogBar CXTPDialogBar::CXTPDialogBar() { m_rcBorders = CRect(3, 3, 3, 3); m_bResizable = TRUE; m_bCaptionVisible = TRUE; m_szDockingClient = m_szFloatingClient = CSize(200, 200); m_szMinTrackRect = CSize(50, 50); m_bCaptionPopup = TRUE; m_hwndChild = 0; m_pPopupBar = new CCaptionPopupBar(); m_nCaptionHeight = 0; m_bCustomizable = FALSE; m_bActive = FALSE; EnableAutomation(); } CXTPDialogBar::~CXTPDialogBar() { m_pPopupBar->InternalRelease(); } BEGIN_MESSAGE_MAP(CXTPDialogBar, CXTPToolBar) //{{AFX_MSG_MAP(CXTPDialogBar) ON_WM_NCHITTEST_EX() ON_WM_SIZE() ON_MESSAGE(WM_IDLEUPDATECMDUI, OnIdleUpdateCmdUI) //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CXTPDialogBar message handlers CSize CXTPDialogBar::CalcDockingLayout(int nLength, DWORD dwMode, int /*nWidth*/) { return CalcSize(nLength, dwMode, m_szDockingClient); } CRect CXTPDialogBar::GetMargins() { CRect rcBorder = m_rcBorders; if (m_bCaptionVisible) { CClientDC dc(this); CXTPFontDC font(&dc, GetPaintManager()->GetCommandBarFont(this)); CSize szGripper = GetPaintManager()->DrawCommandBarGripper(&dc, this, FALSE); int nTitleSize = szGripper.cy; rcBorder.top += nTitleSize; } return rcBorder; } CSize CXTPDialogBar::CalcSize(int nLength, DWORD dwMode, CSize szClient) { CRect rcBorder = m_rcBorders; CSize sizeResult = szClient; sizeResult.cx += rcBorder.left + rcBorder.right; sizeResult.cy += rcBorder.top + rcBorder.bottom; if (!m_bCaptionVisible) { m_nCaptionHeight = 0; if (dwMode & LM_STRETCH) { if (dwMode & LM_VERTDOCK) sizeResult.cy = max(nLength, sizeResult.cy); else sizeResult.cx = max(nLength, sizeResult.cx); } return sizeResult; } CClientDC dc(this); CXTPFontDC font(&dc, GetPaintManager()->GetCommandBarFont(this)); CSize szGripper = GetPaintManager()->DrawCommandBarGripper(&dc, this, FALSE); int nTitleSize = szGripper.cy; m_nCaptionHeight = szGripper.cy + rcBorder.top; sizeResult.cy += nTitleSize; if (dwMode & LM_STRETCH) { if (dwMode & LM_VERTDOCK) sizeResult.cy = max(nLength, sizeResult.cy); else sizeResult.cx = max(nLength, sizeResult.cx); } if (dwMode & LM_HORZ) sizeResult.cx = min(nLength, sizeResult.cx); else sizeResult.cy = min(nLength, sizeResult.cy); int nRightBorder = sizeResult.cx - rcBorder.right; CXTPControl* pHide = m_pControls->FindControl(XTP_ID_TOOLBAR_HIDE); if (!pHide && IsCloseable()) { pHide = (CXTPControlPopup*)m_pControls->Add(new CControlButtonHide(), XTP_ID_TOOLBAR_HIDE, _T(""), -1, TRUE); } if (pHide && !IsCloseable()) { pHide->SetHideFlags(xtpHideGeneric); } else if (pHide) { pHide->SetRect(CRect(CPoint(nRightBorder - 16, m_rcBorders.top + nTitleSize/2 - 8), CSize(16, 16))); nRightBorder -= 16; } CControlCaptionPopup* pCaption = (CControlCaptionPopup*)m_pControls->FindControl(XTP_ID_DIALOGBAR_CAPTION); if (!pCaption) { pCaption = (CControlCaptionPopup*)m_pControls->Add(new CControlCaptionPopup(), XTP_ID_DIALOGBAR_CAPTION, _T(""), -1, TRUE); pCaption->SetCommandBar(m_pPopupBar); } pCaption->m_bCaptionPopup = m_bCaptionPopup && (m_pPopupBar->GetControlCount() != 0); int nCaptionHeight = 16; int nCaptionTop = m_rcBorders.top + nTitleSize/2 - nCaptionHeight / 2; pCaption->SetRect(CRect(m_rcBorders.left + szGripper.cx, nCaptionTop, nRightBorder, nCaptionTop + nCaptionHeight)); pCaption->SetCaption(m_strCaption.IsEmpty() ? GetTitle() : m_strCaption); return sizeResult; } CSize CXTPDialogBar::CalcDynamicLayout(int /*nLength*/, DWORD dwMode) { return CalcSize(32000, dwMode, m_szFloatingClient); } LRESULT CXTPDialogBar::OnNcHitTest(CPoint point) { if (!m_bResizable) return CXTPCommandBar::OnNcHitTest(point); CRect rectWindow; GetWindowRect(&rectWindow); rectWindow.InflateRect(-3, -3); if (m_barPosition != xtpBarFloating) { if (m_barPosition == xtpBarBottom) { if (point.y <= rectWindow.top) return HTTOP; } else { if ((point.y >= rectWindow.bottom) && (((m_dwFlags & xtpFlagStretched) == 0) || !IsVerticalPosition(GetPosition()))) return HTBOTTOM; } if (m_barPosition == xtpBarRight) { if (point.x <= rectWindow.left) return HTLEFT; } else { if ((point.x >= rectWindow.right) && (((m_dwFlags & xtpFlagStretched) == 0) || IsVerticalPosition(GetPosition()))) return HTRIGHT; } } else { if ((point.y < rectWindow.top) && (point.x < rectWindow.left)) return HTTOPLEFT; if ((point.y < rectWindow.top) && (point.x >= rectWindow.right)) return HTTOPRIGHT; if ((point.y >= rectWindow.bottom) && (point.x < rectWindow.left)) return HTBOTTOMLEFT; if ((point.y >= rectWindow.bottom) && (point.x >= rectWindow.right)) return HTBOTTOMRIGHT; 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 CXTPDialogBar::OnResize(CRect rcWindow, int nHitTest) { CRect rcMargins = GetMargins(); if (rcWindow.Width() < m_szMinTrackRect.cx || rcWindow.Height() < m_szMinTrackRect.cy) return; if (GetPosition() == xtpBarFloating) { m_szFloatingClient = CSize(rcWindow.Width() - rcMargins.left - rcMargins.right, rcWindow.Height() - rcMargins.top - rcMargins.bottom); CalcDynamicLayout(0, 0); MoveWindow(rcWindow); Redraw(); } else { CSize szDockingClient = CSize(rcWindow.Width() - rcMargins.left - rcMargins.right, rcWindow.Height() - rcMargins.top - rcMargins.bottom); if (nHitTest == HTRIGHT || nHitTest == HTLEFT) m_szDockingClient.cx = szDockingClient.cx; else m_szDockingClient.cy = szDockingClient.cy; OnRecalcLayout(); } } int CXTPDialogBar::OnMouseHitTest(CPoint pt) { CXTPWindowRect rc(this); rc.bottom = rc.top + m_nCaptionHeight; return rc.PtInRect(pt) ? HTCLIENT : HTERROR; } void CXTPDialogBar::MoveChildWindow(CRect rc) { if (m_hwndChild) { CRect rcMargins = GetMargins(); CRect rcChild(rcMargins.left, rcMargins.top, rc.Width() - rcMargins.right, rc.Height() - rcMargins.bottom); ::SetWindowPos(m_hwndChild, 0, rcChild.left, rcChild.top, rcChild.Width(), rcChild.Height(), SWP_NOZORDER | SWP_NOACTIVATE); ::InvalidateRect(m_hwndChild, 0, FALSE); } } void CXTPDialogBar::OnSize(UINT nType, int cx, int cy) { CXTPToolBar::OnSize(nType, cx, cy); MoveChildWindow(CRect(0, 0, cx, cy)); } void CXTPDialogBar::SetChild(CWnd* pChildWnd) { m_hwndChild = pChildWnd->m_hWnd; MoveChildWindow(CXTPClientRect(this)); DelayLayout(); } void CXTPDialogBar::SetCaption(LPCTSTR strCaption) { m_strCaption = strCaption; DelayLayout(); } void CXTPDialogBar::SetCaptionPopup(int nMenuResourceID) { CMenu menu; VERIFY(menu.LoadMenu(nMenuResourceID)); m_pPopupBar->LoadMenu(menu.GetSubMenu(0)); } void CXTPDialogBar::SetSize(CSize sz) { m_szDockingClient = m_szFloatingClient = sz; DelayLayout(); } CString CXTPDialogBar::GetCaption() const { return m_strCaption; } void CXTPDialogBar::SetCaptionVisible(BOOL bVisible) { m_bCaptionVisible = bVisible; DelayLayout(); } LRESULT CXTPDialogBar::OnIdleUpdateCmdUI(WPARAM wParam, LPARAM lParam) { CWnd* pFocus = GetFocus(); BOOL bActive = (pFocus->GetSafeHwnd() && (pFocus == this || IsChild(pFocus) || (pFocus->GetOwner()->GetSafeHwnd() && IsChild(pFocus->GetOwner())))); if (bActive != m_bActive) { m_bActive = bActive; Redraw(); } return CXTPToolBar::OnIdleUpdateCmdUI(wParam, lParam); }