// XTPTaskDialogControls.cpp // // This file is a part of the XTREME CONTROLS 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 "Common/Resource.h" #include "Common/XTPDrawHelpers.h" #include "Common/XTPColorManager.h" #include "Common/XTPResourceManager.h" #include "Common/XTPWinThemeWrapper.h" #include "Common/XTPSystemHelpers.h" #include "Common/XTPImageManager.h" #include "Common/XTPMarkupRender.h" #include "../Util/XTPControlTheme.h" #include "../Button/XTPButton.h" #include "../Button/XTPButtonTheme.h" #include "XTPTaskDialogAPI.h" #include "XTPTaskDialogControls.h" #ifndef WM_UPDATEUISTATE #define WM_UPDATEUISTATE 0x0128 #endif #ifndef WM_QUERYUISTATE #define WM_QUERYUISTATE 0x0129 #endif #ifndef UISF_HIDEACCEL #define UISF_HIDEACCEL 0x2 #endif #ifndef UISF_HIDEFOCUS #define UISF_HIDEFOCUS 0x1 #endif #ifndef ODS_NOACCEL #define ODS_NOACCEL 0x0100 #endif #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // CXTPTaskDialogLinkCtrl CXTPTaskDialogLinkCtrl::CXTPTaskDialogLinkCtrl() : m_nFocused(-1) , m_crBack(COLORREF_NULL) , m_crText(GetXtremeColor(COLOR_WINDOWTEXT)) , m_crTextLink(RGB(0x00, 0x66, 0xcc)) , m_hcurHand(NULL) , m_bPreSubclassWindow(TRUE) { // try loading system hand cursor first. m_hcurHand = ::LoadCursor(NULL, MAKEINTRESOURCE(32649)); // if this fails load default. if (m_hcurHand == NULL) { m_hcurHand = XTPResourceManager()->LoadCursor(XTP_IDC_HAND); ASSERT(m_hcurHand != NULL); } } CXTPTaskDialogLinkCtrl::~CXTPTaskDialogLinkCtrl() { RemoveAllLinks(); } void CXTPTaskDialogLinkCtrl::RemoveAllLinks() { for (int i = 0; i < m_arrLinks.GetSize(); i++) { delete m_arrLinks[i]; } m_arrLinks.RemoveAll(); } IMPLEMENT_DYNCREATE(CXTPTaskDialogLinkCtrl, CWnd) BEGIN_MESSAGE_MAP(CXTPTaskDialogLinkCtrl, CWnd) //{{AFX_MSG_MAP(CXTPTaskDialogLinkCtrl) ON_WM_PAINT() ON_WM_ERASEBKGND() ON_WM_SETCURSOR() ON_WM_LBUTTONDOWN() ON_WM_LBUTTONUP() ON_WM_NCHITTEST_EX() ON_WM_SETFOCUS() ON_WM_KILLFOCUS() ON_WM_GETDLGCODE() ON_WM_KEYDOWN() ON_MESSAGE(WM_SETTEXT, OnSetText) ON_MESSAGE(WM_UPDATEUISTATE, OnUpdateUIState) //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CXTPTaskDialogLinkCtrl message handlers CXTPTaskDialogLinkCtrl::LINKITEM* CXTPTaskDialogLinkCtrl::HitTest(CPoint pt) const { for (int i = 0; i < m_arrLinks.GetSize(); i++) { LINKITEM* pItem = m_arrLinks[i]; for (int j = 0; j < pItem->arrParts.GetSize(); j++) { if (::PtInRect(&pItem->arrParts[j], pt)) return pItem; } } return NULL; } void CXTPTaskDialogLinkCtrl::OnPaint() { CPaintDC dc(this); CXTPClientRect rClient(this); CXTPBufferDC memDC(dc); if (m_crBack != COLORREF_NULL) memDC.FillSolidRect(&rClient, m_crBack); else { HBRUSH hBrush = (HBRUSH)GetParent()->SendMessage(WM_CTLCOLORSTATIC, (WPARAM)memDC.GetSafeHdc(), (LPARAM)m_hWnd); if (hBrush) { ::FillRect(memDC.GetSafeHdc(), rClient, hBrush); } else { memDC.FillSolidRect(rClient, GetXtremeColor(COLOR_3DFACE)); } } memDC.SetBkMode(TRANSPARENT); DrawText(&memDC, rClient); } int CXTPTaskDialogLinkCtrl::DrawTextPartText(CDC* pDC, CString strBuffer, int x, int y, LINKITEM* pItem) { if (strBuffer.IsEmpty()) return 0; CSize sz = pDC->GetTextExtent(strBuffer); pDC->DrawText(strBuffer, CRect(x, y, x + sz.cx + 10, y + sz.cy), DT_TOP | DT_LEFT | DT_NOPREFIX | DT_SINGLELINE); CRect rcItem(x, y, x + sz.cx, y + sz.cy); if (pItem) { if (m_nFocused == pItem->nIndex) { COLORREF clr = pDC->SetTextColor(m_crText); pDC->DrawFocusRect(rcItem); pDC->SetTextColor(clr); } pItem->arrParts.Add(rcItem); } return sz.cx; } void CXTPTaskDialogLinkCtrl::DrawTextPart(CDC* pDC, int&x, int&y, int nWidth, CString strBuffer, LINKITEM* pItem) { CXTPFontDC fontDC(pDC, pItem && m_fontUL.GetSafeHandle() ? &m_fontUL : GetFont(), pItem ? m_crTextLink :m_crText); int nTextHeight = pDC->GetTextExtent(_T("XXX"), 3).cy; int nStartPos = 0; int nGoodPos = 0; while (nStartPos < strBuffer.GetLength()) { TCHAR t = strBuffer[nStartPos]; if (t == _T(' ') || t == _T('\t') || t == _T('\n')) { CString strPart = strBuffer.Left(nStartPos); if (x + pDC->GetTextExtent(strPart).cx > nWidth) { if (x == 0 && nGoodPos == 0) nGoodPos = nStartPos - 1; if (nGoodPos > 0) { strPart = strBuffer.Left(nGoodPos); DrawTextPartText(pDC, strPart, x, y, pItem); strBuffer.Delete(0, nGoodPos + 1); nStartPos -= nGoodPos + 1; } else { if (strBuffer[0] == _T(' ')) { strBuffer.Delete(0); nStartPos--; } } x = 0; y += nTextHeight; nGoodPos = 0; if (t != _T('\n')) continue; } else nGoodPos = nStartPos; } if (t == _T('\n')) { CString strPart = strBuffer.Left(nStartPos); DrawTextPartText(pDC, strPart, x, y, pItem); strBuffer.Delete(0, nStartPos + 1); x = 0; y += nTextHeight; nStartPos = nGoodPos = 0; continue; } nStartPos++; } CString strPart = strBuffer; if (x + pDC->GetTextExtent(strPart).cx > nWidth) { if (nGoodPos != 0) { strPart = strBuffer.Left(nGoodPos); DrawTextPartText(pDC, strPart, x, y, pItem); strBuffer.Delete(0, nGoodPos + 1); } x = 0; y += nTextHeight; } int nLength = DrawTextPartText(pDC, strBuffer, x, y, pItem); x += nLength; } void CXTPTaskDialogLinkCtrl::DrawText(CDC* pDC, CRect rClient) { if (m_arrLinks.GetSize() == 0) { CXTPFontDC fontDC(pDC, GetFont(), m_crText); pDC->DrawText(m_strBuffer, rClient, DT_TOP | DT_WORDBREAK | DT_NOPREFIX); return; } int x = 0, y = 0, nWidth = rClient.Width(); CString strBuffer = m_strBuffer; int nPos = 0; for (int i = 0; i < m_arrLinks.GetSize(); i++) { LINKITEM* pItem = m_arrLinks.GetAt(i); int iStart = pItem->nStart; int iCount = pItem->strLabel.GetLength(); pItem->arrParts.RemoveAll(); DrawTextPart(pDC, x, y, nWidth, m_strBuffer.Mid(nPos, iStart - nPos), NULL); DrawTextPart(pDC, x, y, nWidth, m_strBuffer.Mid(iStart, iCount), pItem); nPos = iStart + iCount; } DrawTextPart(pDC, x, y, nWidth, m_strBuffer.Mid(nPos, m_strBuffer.GetLength() - nPos), NULL); } BOOL CXTPTaskDialogLinkCtrl::OnEraseBkgnd(CDC* pDC) { UNREFERENCED_PARAMETER(pDC); return TRUE; } BOOL CXTPTaskDialogLinkCtrl::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 CXTPTaskDialogLinkCtrl::PreSubclassWindow() { CWnd::PreSubclassWindow(); if (m_bPreSubclassWindow) { RemoveAllLinks(); GetWindowText(m_strBuffer); ExtractLinks(m_strBuffer); DefWindowProc(WM_SETTEXT, 0, (LPARAM)(LPCTSTR)m_strBuffer); if (m_arrLinks.GetSize() > 0 && GetFont()) { LOGFONT lf; GetFont()->GetLogFont(&lf); lf.lfUnderline = 1; m_fontUL.DeleteObject(); m_fontUL.CreateFontIndirect(&lf); } Invalidate(FALSE); } } LRESULT CXTPTaskDialogLinkCtrl::OnSetText(WPARAM, LPARAM lParam) { RemoveAllLinks(); m_strBuffer = (LPCTSTR)lParam; ExtractLinks(m_strBuffer); DefWindowProc(WM_SETTEXT, 0, (LPARAM)(LPCTSTR)m_strBuffer); Invalidate(FALSE); return m_strBuffer.GetLength(); } BOOL CXTPTaskDialogLinkCtrl::Create(const CRect& rect, CString& strBuffer, CFont* pFont, CWnd* pParentWnd) { RemoveAllLinks(); if (strBuffer.IsEmpty() || !pFont->GetSafeHandle() || !::IsWindow(pParentWnd->GetSafeHwnd())) return FALSE; m_strBuffer = strBuffer; if (!ExtractLinks(m_strBuffer)) return FALSE; if (!CStatic::Create(0, WS_CHILD | WS_VISIBLE | WS_TABSTOP, rect, pParentWnd, 0)) return FALSE; LOGFONT lf; pFont->GetLogFont(&lf); lf.lfUnderline = 1; m_fontUL.DeleteObject(); m_fontUL.CreateFontIndirect(&lf); SetFont(pFont); DefWindowProc(WM_SETTEXT, 0, (LPARAM)(LPCTSTR)m_strBuffer); strBuffer = m_strBuffer; return TRUE; } DWORD CXTPTaskDialogLinkCtrl::GetLinkPos(CString strBuffer, int iPos /*= 0*/) { strBuffer.MakeLower(); int iStart = strBuffer.Find(_T(""), iValid); if (iEnd == -1) return NULL; return MAKELONG(iStart, (iEnd + 4) - iStart); } BOOL CXTPTaskDialogLinkCtrl::ExtractLinks(CString& strBuffer) { m_arrLinks.RemoveAll(); for (DWORD dwPos = GetLinkPos(strBuffer); dwPos;) { int iStart = LOWORD(dwPos); int iCount = HIWORD(dwPos); LINKITEM* pItem = new LINKITEM(); CString strLink = strBuffer.Mid(iStart,iCount); // extract the link and execute strings from the link. AfxExtractSubString(pItem->strUrl, strLink, 1, '"'); AfxExtractSubString(pItem->strUrl, pItem->strUrl, 0, '"'); AfxExtractSubString(pItem->strLabel, strLink, 1, '>'); AfxExtractSubString(pItem->strLabel, pItem->strLabel, 0, '<'); // reformat text to remove link tags. CString strTemp = strBuffer.Left(iStart); strTemp += pItem->strLabel; strTemp += strBuffer.Right(strBuffer.GetLength()-(iStart + iCount)); strBuffer = strTemp; pItem->nStart = iStart; pItem->nIndex = (int)m_arrLinks.Add(pItem); dwPos = GetLinkPos(strBuffer); } return (m_arrLinks.GetSize() > 0); } LRESULT CXTPTaskDialogLinkCtrl::OnNcHitTest(CPoint point) { ScreenToClient(&point); if (HitTest(point)) { return HTCLIENT; } return (LRESULT)HTTRANSPARENT; } void CXTPTaskDialogLinkCtrl::FocusItem(int iFocusItem) { if (m_nFocused != iFocusItem) { m_nFocused = iFocusItem; Invalidate(FALSE); } } UINT CXTPTaskDialogLinkCtrl::OnGetDlgCode() { const MSG& msg = AfxGetThreadState()->m_lastSentMsg; if (!msg.lParam) return DLGC_UNDEFPUSHBUTTON; LPMSG lpMsg = (LPMSG)msg.lParam; if (lpMsg->message == WM_CHAR) { if (lpMsg->wParam == VK_TAB) return DLGC_WANTTAB; if (lpMsg->wParam == VK_RETURN) return DLGC_WANTCHARS; } if (lpMsg->message == WM_KEYDOWN) { UINT nChar = (UINT)lpMsg->wParam; if ((nChar == VK_RETURN || nChar == VK_SPACE) && (m_nFocused != -1)) return DLGC_WANTALLKEYS; if (nChar == VK_TAB) { if (GetKeyState(VK_SHIFT) >= 0) { if (m_nFocused < m_arrLinks.GetSize() - 1) { FocusItem(m_nFocused + 1); return DLGC_WANTTAB; } } else { if (m_nFocused > 0) { FocusItem(m_nFocused - 1); return DLGC_WANTTAB; } } } } return DLGC_UNDEFPUSHBUTTON; } void CXTPTaskDialogLinkCtrl::OnKeyDown(UINT nChar, UINT /*nRepCnt*/, UINT /*nFlags*/) { if ((nChar == VK_RETURN || nChar == VK_SPACE) && (m_nFocused != -1)) { GetOwner()->SendMessage(WM_COMMAND, MAKEWPARAM(GetDlgCtrlID(), BN_CLICKED), (LPARAM)m_hWnd); } } void CXTPTaskDialogLinkCtrl::OnLButtonDown(UINT /*nFlags*/, CPoint point) { LINKITEM* pItem = HitTest(point); if (pItem) { FocusItem(pItem->nIndex); SetFocus(); } else { FocusItem(-1); } } void CXTPTaskDialogLinkCtrl::OnSetFocus(CWnd* /*pOldWnd*/) { if (m_nFocused == -1) { FocusItem(0); } } void CXTPTaskDialogLinkCtrl::OnKillFocus(CWnd* /*pNewWnd*/) { FocusItem(-1); } CXTPTaskDialogLinkCtrl::LINKITEM* CXTPTaskDialogLinkCtrl::GetFocusedLink() const { return m_nFocused >= 0 && m_nFocused < m_arrLinks.GetSize() ? m_arrLinks[m_nFocused] : NULL; } void CXTPTaskDialogLinkCtrl::OnLButtonUp(UINT /*nFlags*/, CPoint point) { LINKITEM* pItem = HitTest(point); if (pItem && pItem->nIndex == m_nFocused) { GetOwner()->SendMessage(WM_COMMAND, MAKEWPARAM(GetDlgCtrlID(), BN_CLICKED), (LPARAM)m_hWnd ); } } BOOL CXTPTaskDialogLinkCtrl::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message) { if (nHitTest == HTCLIENT && (m_hcurHand != NULL)) { ::SetCursor(m_hcurHand); return TRUE; } return CWnd::OnSetCursor(pWnd, nHitTest, message); } LRESULT CXTPTaskDialogLinkCtrl::OnUpdateUIState(WPARAM wParam, LPARAM lParam) { LRESULT lResult = ::DefWindowProc(m_hWnd, WM_UPDATEUISTATE, wParam, lParam); Invalidate(FALSE); return lResult; } //=========================================================================== // CXTPTaskButtonTheme //=========================================================================== const UINT xtpDluMargin = 5; // non-client margin. CXTPTaskButtonTheme::CXTPTaskButtonTheme(BOOL bThemeReady) { m_bThemeReady = bThemeReady; m_ptMargin = XTPDlu2Pix(xtpDluMargin, xtpDluMargin); m_pFontTitle = NULL; m_bOffsetHiliteText = FALSE; m_nBorderWidth = 3; } CXTPTaskButtonTheme::CXTPTaskButtonTheme() { m_themeButton->OpenThemeData(0, L"BUTTON"); m_bThemeReady = m_themeButton->IsAppThemed(); m_ptMargin = XTPDlu2Pix(xtpDluMargin, xtpDluMargin); m_pFontTitle = NULL; m_bOffsetHiliteText = FALSE; m_nBorderWidth = 3; } void CXTPTaskButtonTheme::DrawButton(CDC* pDC, CXTPButton* pButton) { if (!DrawWinThemeBackground(pDC, pButton)) { DrawButtonThemeBackground(pDC, pButton); } DrawButtonText(pDC, pButton); DrawButtonIcon(pDC, pButton); // Draw the focus rect if style is set and we have focus. if (::GetFocus() == pButton->GetSafeHwnd() && ((pButton->SendMessage(WM_QUERYUISTATE) & UISF_HIDEFOCUS) == 0)) { DrawFocusRect(pDC, pButton); } } BOOL CXTPTaskButtonTheme::DrawButtonThemeBackground(CDC* pDC, CXTPButton* pButton) { CXTPClientRect rcItem(pButton); if (pButton->GetChecked()) pDC->FillSolidRect(rcItem, m_crBorderHilite); else if (pButton->IsPushed() || pButton->IsHighlighted()) { pDC->FillSolidRect(rcItem, m_crBack); } else { HBRUSH hBrush = (HBRUSH)pButton->GetParent()->SendMessage(WM_CTLCOLORBTN, (WPARAM)pDC->GetSafeHdc(), (LPARAM)pButton->GetSafeHwnd()); if (hBrush) { ::FillRect(pDC->GetSafeHdc(), rcItem, hBrush); } else { pDC->FillSolidRect(rcItem, m_crBack); } } if (pButton->IsPushed()) { pDC->Draw3dRect(rcItem, m_crBorder3DShadow, m_crBorder3DHilite); rcItem.DeflateRect(1,1); pDC->Draw3dRect(rcItem, m_crBorderShadow, m_crBorderHilite); } else if (pButton->IsHighlighted()) { pDC->Draw3dRect(rcItem, m_crBorder3DHilite, m_crBorder3DShadow); rcItem.DeflateRect(1,1); pDC->Draw3dRect(rcItem, m_crBorderHilite, m_crBorderShadow); } if (pButton->GetButtonStyle() == BS_DEFPUSHBUTTON) { pDC->Draw3dRect(CXTPClientRect(pButton), m_crBorderActive, m_crBorderActive); } return TRUE; } BOOL CXTPTaskButtonTheme::DrawWinThemeBackground(CDC* pDC, CXTPButton* pButton) { if (m_bThemeReady) { CXTPClientRect rcItem(pButton); HBRUSH hBrush = (HBRUSH)pButton->GetParent()->SendMessage(WM_CTLCOLORBTN, (WPARAM)pDC->GetSafeHdc(), (LPARAM)pButton->GetSafeHwnd()); if (hBrush) { ::FillRect(pDC->GetSafeHdc(), rcItem, hBrush); } else { pDC->FillSolidRect(rcItem, m_crBack); } if (!m_themeButton->ThemeDataOpen()) m_themeButton->OpenThemeData(0, L"BUTTON"); if (m_themeButton->IsAppThemed() && XTPSystemVersion()->IsWinVistaOrGreater()) { CRect rcButton(rcItem); int iStateId = (pButton->IsPushed()) ? PBS_PRESSED : pButton->IsHighlighted() ? PBS_HOT : pButton->GetButtonStyle() == BS_DEFPUSHBUTTON ? PBS_DEFAULTED : PBS_NORMAL; if (!pButton->IsWindowEnabled()) iStateId = PBS_DISABLED; if (SUCCEEDED(m_themeButton->DrawThemeBackground(pDC->GetSafeHdc(), 6, iStateId, &rcButton, NULL))) { return TRUE; } } XTPDrawHelpers()->ExcludeCorners(pDC, rcItem); BOOL bSelected = pButton->IsPushed(); if (bSelected) { pDC->FillSolidRect(rcItem, m_crBackSelected); pDC->Draw3dRect(rcItem, m_crBorderHilite, m_crBorderHilite); rcItem.DeflateRect(1,1); XTPDrawHelpers()->DrawLine(pDC, rcItem.left, rcItem.top, rcItem.Width(), 0, m_crBorder3DShadow); rcItem.top += 1; pDC->Draw3dRect(&rcItem, m_crBorder3DHilite, m_crBorder3DHilite); rcItem.DeflateRect(1,1); pDC->Draw3dRect(&rcItem, m_crBorderShadow, m_crBorderShadow); } else if (pButton->IsHighlighted()) { XTPDrawHelpers()->GradientFill(pDC, &rcItem, m_crBack, m_crBorderShadow, FALSE); pDC->Draw3dRect(rcItem, m_crBorderHilite, m_crBorderHilite); rcItem.DeflateRect(1,1); pDC->Draw3dRect(&rcItem, m_crBack, m_crBack); } if (pButton->GetButtonStyle() == BS_DEFPUSHBUTTON) { if (!bSelected && !pButton->IsHighlighted()) pDC->Draw3dRect(rcItem, m_crBorderActive, m_crBorderActive); } return TRUE; } return FALSE; } void CXTPTaskButtonTheme::DrawButtonIcon(CDC* pDC, CXTPButton* pButton) { CXTPImageManagerIcon* pIcon = pButton->GetIcon(); if (pIcon != NULL) { CXTPFontDC fontDC(pDC, m_pFontTitle ? m_pFontTitle : pButton->GetFont()); CSize size = pDC->GetTextExtent(_T(" "), 1); CPoint point(7, m_ptMargin.y - pIcon->GetHeight() / 2 + size.cy / 2); if (!pButton->IsWindowEnabled()) pIcon->Draw(pDC, point, pIcon->GetDisabledIcon(), pButton->GetImageSize()); else if (pButton->IsHighlighted()) pIcon->Draw(pDC, point, pIcon->GetHotIcon(), pButton->GetImageSize()); else pIcon->Draw(pDC, point, pIcon->GetIcon(), pButton->GetImageSize()); } } CPoint CXTPTaskButtonTheme::GetTextPosition(CDC* /*pDC*/, CSize sizeText, CXTPButton* pButton) { CXTPClientRect rcItem(pButton); CPoint point; point.x = m_ptMargin.x; point.y = rcItem.top + (rcItem.Height()-sizeText.cy)/2; if (pButton->GetIcon()) point.x += pButton->GetImageSize().cx; return point; } void CXTPTaskButtonTheme::DrawButtonText(CDC* pDC, CXTPButton* pButton) { if (m_strButton.IsEmpty()) GetButtonText(pButton); CXTPClientRect rcItem(pButton); CRect rcText = rcItem; rcText.DeflateRect(m_ptMargin.x, m_ptMargin.y); if (pButton->GetIcon()) rcText.left += pButton->GetImageSize().cx; CFont* pFontNote = pButton->GetFont(); CSize sizeNoteText = rcText.Size(); XTPCalcTextSize(m_strNoteText, sizeNoteText, *pFontNote); CSize sizeCaptText = rcText.Size(); XTPCalcTextSize(m_strCaptText, sizeCaptText, m_pFontTitle ? *m_pFontTitle : *pFontNote); if (pButton->GetMarkupUIElement()) { XTPMarkupSetDefaultFont(pButton->GetMarkupContext(), m_pFontTitle ? (HFONT)m_pFontTitle->GetSafeHandle(): (HFONT)pFontNote->GetSafeHandle(), COLORREF_NULL); sizeCaptText = XTPMarkupMeasureElement(pButton->GetMarkupUIElement(), rcText.Width(), INT_MAX); } // get the text size. CXTPEmptySize sizeText; sizeText.cy = sizeCaptText.cy + sizeNoteText.cy; sizeText.cx = __max(sizeCaptText.cx, sizeNoteText.cx); CPoint point = GetTextPosition(pDC, sizeText, pButton); BOOL bSelected = pButton->GetChecked() || pButton->IsPushed(); if (bSelected && m_bOffsetHiliteText) point.Offset(1,1); // Set the draw state flags. pDC->SetTextColor(GetTextColor(pButton)); pDC->SetTextAlign(TA_LEFT); pDC->SetBkMode(TRANSPARENT); if (!m_strCaptText.IsEmpty()) { CRect rcButton(point, sizeCaptText); if (pButton->GetMarkupUIElement()) { XTPMarkupSetDefaultFont(pButton->GetMarkupContext(), m_pFontTitle ? (HFONT)m_pFontTitle->GetSafeHandle(): (HFONT)pFontNote->GetSafeHandle(), pDC->GetTextColor()); XTPMarkupRenderElement(pButton->GetMarkupUIElement(), pDC->GetSafeHdc(), rcButton); } else { CString strCaptText = m_strCaptText; if (pButton->SendMessage(WM_QUERYUISTATE) & UISF_HIDEACCEL) { XTPDrawHelpers()->StripMnemonics(strCaptText); } CXTPFontDC fontDC(pDC, m_pFontTitle ? m_pFontTitle : pFontNote); pDC->DrawText(strCaptText, &rcButton, DT_LEFT | DT_TOP | DT_WORDBREAK); } point.y += sizeCaptText.cy + 1; } if (!m_strNoteText.IsEmpty()) { CString strNoteText = m_strNoteText; CXTPFontDC fontDC(pDC, pFontNote); CRect rcButton(point, sizeNoteText); pDC->DrawText(strNoteText, &rcButton, DT_LEFT | DT_TOP | DT_WORDBREAK | DT_NOPREFIX); } } void CXTPTaskButtonTheme::GetButtonText(CXTPButton* pButton) { if (::IsWindow(pButton->GetSafeHwnd())) { pButton->GetWindowText(m_strButton); m_strCaptText = XTPExtractSubString(m_strButton, 0); m_strNoteText = XTPExtractSubString(m_strButton, 1); } } void CXTPTaskButtonTheme::SetTitleFont(CFont* pFontTitle) { m_pFontTitle = pFontTitle; } CFont* CXTPTaskButtonTheme::GetTitleFont() { return m_pFontTitle; } void CXTPTaskButtonTheme::RefreshMetrics(CXTPButton* pButton) { CXTPButtonTheme::RefreshMetrics(pButton); if (m_bThemeReady) { COLORREF crWindow = GetXtremeColor(COLOR_WINDOW); COLORREF cr3dFace = GetXtremeColor(COLOR_3DFACE); COLORREF cr3dShad = GetXtremeColor(COLOR_3DSHADOW); m_crBack = crWindow; m_crText = RGB(21,28,85); m_crTextHilite = RGB(0x00, 0x4a, 0xe5); m_crBorderActive = RGB(0xa3, 0xed, 0xff); m_crBackSelected = XTPColorManager()->LightColor(crWindow, cr3dFace, 200); m_crBorder3DShadow = XTPColorManager()->LightColor(cr3dFace, cr3dShad, 775); m_crBorder3DHilite = XTPColorManager()->LightColor(cr3dFace, cr3dShad, 875); m_crBorderShadow = XTPColorManager()->LightColor(crWindow, cr3dFace, 0); m_crBorderHilite = XTPColorManager()->LightColor(cr3dFace, cr3dShad, 175); } else { m_crBorderActive = m_crBorder3DShadow; } } COLORREF CXTPTaskButtonTheme::GetTextColor(CXTPButton* pButton) { if (!pButton->IsWindowEnabled()) return GetXtremeColor(COLOR_GRAYTEXT); if (pButton->IsHighlighted()) return m_crTextHilite; return m_crText; } /* CPoint CXTPTaskButtonTheme::CalculateImagePosition(CDC* pDC, UINT nState, CRect& rcItem, bool bHasPushedImage, CXTPButton* pButton) { //CPoint point = CXTPButtonTheme::CalculateImagePosition(pDC, nState, rcItem, bHasPushedImage, pButton); CPoint point = 0; if (!m_strNoteText.IsEmpty()) point.y = m_ptMargin.y; point.x += 2; return point; }*/ //=========================================================================== // CXTPTaskButtonThemeExpando //=========================================================================== CXTPTaskButtonThemeExpando::CXTPTaskButtonThemeExpando() { m_bOffsetHiliteText = FALSE; } void CXTPTaskButtonThemeExpando::DrawButton(CDC* pDC, CXTPButton* pButton) { // define some temporary variables. CXTPClientRect rcItem(pButton); pDC->FillSolidRect(rcItem, GetXtremeColor(COLOR_3DFACE)); // Set the background mode to transparent. pDC->SetBkColor(GetXtremeColor(COLOR_3DFACE)); // select font into device context. CXTPFontDC fontDC(pDC, pButton->GetFont()); CString strText; pButton->GetWindowText(strText); // Remove ampersand if (pButton->SendMessage(WM_QUERYUISTATE) & UISF_HIDEACCEL) { XTPDrawHelpers()->StripMnemonics(strText); } CRect rcText(rcItem); rcText.left += 26; CSize szExtent = pDC->GetTextExtent(strText); if (szExtent.cx < rcItem.Width()) { rcText.top = (rcItem.top + rcItem.bottom - szExtent.cy) / 2; rcText.bottom = rcText.top + szExtent.cy; } pDC->SetTextColor(GetXtremeColor(COLOR_BTNTEXT)); pDC->DrawText(strText, rcText, DT_TOP | DT_WORDBREAK); // Draw the focus rect if style is set and we have focus. if (::GetFocus() == pButton->GetSafeHwnd() && ((pButton->SendMessage(WM_QUERYUISTATE) & UISF_HIDEFOCUS) == 0)) { pDC->DrawText(strText, rcText, DT_TOP | DT_WORDBREAK | DT_CALCRECT); rcText.InflateRect(1, 0); pDC->DrawFocusRect(rcText); } rcItem.right = rcItem.left + 18; rcItem.bottom = rcItem.top + min(20, rcItem.Height()); CPoint pt(rcItem.right / 2 - 1, rcItem.bottom / 2 - 3); BOOL bDrawStandard = TRUE; if (m_themeButton->IsAppThemed()) { CXTPWinThemeWrapper themeTaskDialog; themeTaskDialog.OpenTheme(0, L"TASKDIALOG"); if (themeTaskDialog.IsAppThemed()) { CRect rcButton(0, 0, 19, 21); int iStateId = pButton->IsPushed() ? 3 : pButton->IsHighlighted() ? 2 : 1; if (pButton->GetChecked()) iStateId += 3; if (SUCCEEDED(themeTaskDialog.DrawThemeBackground(pDC->GetSafeHdc(), 13, iStateId, &rcButton, NULL))) { return; } } CRect rc(rcItem); rc.right += 1; int iStateId = pButton->IsPushed() ? PBS_PRESSED : pButton->IsHighlighted() ? PBS_HOT : PBS_NORMAL; if (SUCCEEDED(m_themeButton->DrawThemeBackground(pDC->GetSafeHdc(), BP_PUSHBUTTON, iStateId, &rc, NULL))) { bDrawStandard = FALSE; pt.x += 1; } } if (bDrawStandard) { pDC->DrawFrameControl(&rcItem, DFC_BUTTON, (pButton->IsPushed() ? DFCS_PUSHED : 0) | DFCS_BUTTONPUSH); if (pButton->IsPushed()) pt.Offset(1, 1); } if (!pButton->GetChecked()) XTPDrawHelpers()->Triangle(pDC, pt - CPoint(4, 0), pt + CPoint(4, 0), pt + CPoint(0, 4), GetXtremeColor(COLOR_BTNTEXT)); else XTPDrawHelpers()->Triangle(pDC, pt - CPoint(4, -4), pt + CPoint(4, 4), pt + CPoint(0, 0), GetXtremeColor(COLOR_BTNTEXT)); } ////////////////////////////////////////////////////////////////////////// // CXTPTaskDialogProgressCtrl #ifndef PBS_MARQUEE #define PBS_MARQUEE 0x08 #endif #ifndef PBM_SETMARQUEE #define PBM_SETMARQUEE (WM_USER+10) #endif #ifndef PBM_SETSTATE #define PBM_SETSTATE (WM_USER+16) #endif CXTPTaskDialogProgressCtrl::CXTPTaskDialogProgressCtrl() { m_nState = -1; m_nMarqueePos = 0; m_bMarquee = FALSE; m_nMarqueeDelay = 0; } BEGIN_MESSAGE_MAP(CXTPTaskDialogProgressCtrl, CProgressCtrl) //{{AFX_MSG_MAP(CXTPTaskDialogProgressCtrl) ON_WM_PAINT() ON_MESSAGE(PBM_SETMARQUEE, OnStartMarquee) ON_MESSAGE(PBM_SETSTATE, OnSetState) ON_WM_TIMER() //}}AFX_MSG_MAP END_MESSAGE_MAP() void CXTPTaskDialogProgressCtrl::OnPaint() { if (HIWORD(XTPSystemVersion()->GetComCtlVersion()) > 5) { Default(); return; } if (((GetStyle() & PBS_MARQUEE) == 0) || !m_bMarquee) { Default(); return; } BOOL bVista = XTPSystemVersion()->IsWinVistaOrGreater(); CPaintDC dcPaint(this); CXTPBufferDC dc(dcPaint); CXTPClientRect rcClient(this); dc.FillSolidRect(rcClient, GetXtremeColor(COLOR_3DFACE)); if (m_nState == PBST_ERROR || m_nState == PBST_PAUSED) return; rcClient.DeflateRect(1, 1); CRect rc(rcClient); int dxBlock = rc.Height() * 2 / 3; int nSpace = bVista ? 0 : 2; rc.left = m_nMarqueePos + 1; for (int i = 0; i < 5; i++) { if (rc.left >= rcClient.right) rc.left = 1; rc.right = rc.left + dxBlock; if (rc.right > rcClient.right) rc.right = rcClient.right; dc.FillSolidRect(rc, GetXtremeColor(COLOR_HIGHLIGHT)); rc.left = rc.right + nSpace; } } LRESULT CXTPTaskDialogProgressCtrl::OnSetState(WPARAM wParam, LPARAM /*lParam*/) { m_nState = (int)wParam; Default(); return 1; } LRESULT CXTPTaskDialogProgressCtrl::OnStartMarquee(WPARAM wParam, LPARAM lParam) { m_bMarquee = FALSE; m_nMarqueePos = 0; m_nMarqueeDelay = 0; if (HIWORD(XTPSystemVersion()->GetComCtlVersion()) > 5) return Default(); if (((GetStyle() & PBS_MARQUEE) == 0)) return Default(); m_bMarquee = wParam && (lParam > 0); m_nMarqueePos = 0; KillTimer(101); if (m_bMarquee) { m_nMarqueeDelay = (UINT)lParam; SetTimer(101, m_nMarqueeDelay, NULL); } return 1; } void CXTPTaskDialogProgressCtrl::OnTimer(UINT_PTR nIDEvent) { if (nIDEvent == 101 && m_bMarquee) { CXTPClientRect rcClient(this); BOOL bVista = XTPSystemVersion()->IsWinVistaOrGreater(); int dxBlock = (rcClient.Height() - 2) * 2 / 3; int nSpace = bVista ? 0 : 2; m_nMarqueePos += (dxBlock + nSpace) * (m_nMarqueeDelay > 50 ? 1 : 2); if (m_nMarqueePos > rcClient.right) m_nMarqueePos = 0; Invalidate(FALSE); return; } CWnd::OnTimer(nIDEvent); }