/** * @file XTPMarkupStatic.cpp * * @copyright * (c) 1998-2025 Codejock Software, All Rights Reserved. * * This source file is the property of Codejock Software and must not be * redistributed by any means without the explicit written permission of * Codejock Software. * * The use of this source code is governed by the terms and conditions specified * in the Toolkit Pro license agreement. Codejock Software grants you, as a * single software developer, the limited right to use this software on one * computer only. * * Contact Information: * support@codejock.com * http://www.codejock.com * */ #include "stdafx.h" #ifdef _XTP_INCLUDE_MARKUP # include "GraphicLibrary/GdiPlus/XTPGdiPlus.h" # include "Common/XTPTypeId.h" # include "Common/XTPCasting.h" # include "Common/XTPFramework.h" # include "Common/XTPSystemHelpers.h" # include "Common/XTPSynchro.h" # include "Common/XTPApplication.h" # include "Common/XTPSingleton.h" # include "Common/XTPGdiObjects.h" # include "Common/XTPDrawHelpers.h" # include "Common/XTPColorManager.h" # include "Common/Base/Types/XTPSize.h" # include "Common/XTPMarkupRender.h" # include "Common/XTPResourceManager.h" # include # include "Markup/XTPMarkupContext.h" # include "Markup/XTPMarkupObject.h" # include "Markup/XTPMarkupInputElement.h" # include "Markup/XTPMarkupUIElement.h" # include "Markup/XTPMarkupDrawingContext.h" # include "Controls/Static/XTPMarkupStatic.h" # include "Common/Base/Diagnostic/XTPDisableNoisyWarnings.h" # ifdef _DEBUG # define new DEBUG_NEW # undef THIS_FILE static char THIS_FILE[] = __FILE__; # endif ///////////////////////////////////////////////////////////////////////////// // CXTPMarkupStatic CXTPMarkupStatic::CXTPMarkupStatic() { m_pUIElement = NULL; m_pMarkupContext = XTPMarkupCreateContext(NULL, TRUE); m_bIgnoreRTL = FALSE; } CXTPMarkupStatic::~CXTPMarkupStatic() { MARKUP_RELEASE(m_pUIElement); XTPMarkupReleaseContext(m_pMarkupContext, TRUE); } BEGIN_MESSAGE_MAP(CXTPMarkupStatic, CStatic) //{{AFX_MSG_MAP(CXTPMarkupStatic) ON_WM_PAINT() //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CXTPMarkupStatic message handlers template AFX_INLINE BOOL XTPStrPushChr(T*& pStr, T ch, SIZE_T& nPos, SIZE_T& nSize) { if (NULL == pStr) { nSize = 0x100; pStr = (T*)malloc(nSize * sizeof(T)); if (NULL == pStr) return FALSE; *pStr = T('\0'); nPos = 0; } pStr[nPos] = ch; if (++nPos == nSize) { nSize *= 2; pStr = (T*)realloc(pStr, nSize); if (NULL == pStr) return FALSE; pStr[nPos] = T('\0'); } return TRUE; } template AFX_INLINE T* XTPEscapeMarkupFormatPlaceholders(const T* pFormat) { _ASSERTE(NULL != pFormat); SIZE_T si = 0, di = 0, nSize = 0; T* p = NULL; BOOL bPatched = FALSE; for (;;) { T ch = pFormat[si++]; if (T('\0') == ch) { if (!XTPStrPushChr(p, ch, di, nSize)) return NULL; return p; } if (T('%') == ch) { if (!XTPStrPushChr(p, ch, di, nSize)) return NULL; T ch2 = pFormat[si]; if (T('\0') == ch2) { if (!XTPStrPushChr(p, ch2, di, nSize)) return NULL; return p; } if (T('s') == ch2) { if (!bPatched) { if (!XTPStrPushChr(p, ch2, di, nSize)) return NULL; bPatched = TRUE; ++si; continue; } } if (!XTPStrPushChr(p, ch, di, nSize)) return NULL; if (!XTPStrPushChr(p, ch2, di, nSize)) return NULL; if (T('%') == ch2) if (!XTPStrPushChr(p, ch2, di, nSize)) return NULL; ++si; continue; } if (!XTPStrPushChr(p, ch, di, nSize)) return NULL; } } void CXTPMarkupStatic::SetMarkupTextEx(LPCSTR lpszMarkup, UINT nCodePage /*= CP_UTF8*/) { MARKUP_RELEASE(m_pUIElement); if (lpszMarkup && strstr(lpszMarkup, "%s") != NULL) { char* pMarkupFormatEscaped = XTPEscapeMarkupFormatPlaceholders(lpszMarkup); if (!XTP_ASSERT_CHECK(NULL != pMarkupFormatEscaped)) return; CString strCaption; GetWindowText(strCaption); # ifndef _UNICODE UNREFERENCED_PARAMETER(nCodePage); CString strMarkup; strMarkup.Format(pMarkupFormatEscaped, (LPCTSTR)strCaption); m_pUIElement = m_pMarkupContext->Parse(strMarkup); # else /*!_UNICODE*/ CXTPResourceManager::CXTPW2A strCaptionA(strCaption, -1, nCodePage); CArray strMarkup; strMarkup.SetSize( XTPToIntPtrChecked(strCaptionA.GetLength() + strlen(pMarkupFormatEscaped) + 1)); wsprintfA(strMarkup.GetData(), pMarkupFormatEscaped, strCaptionA.operator LPCSTR()); m_pUIElement = m_pMarkupContext->Parse(strMarkup.GetData()); # endif /*_UNICODE*/ free(pMarkupFormatEscaped); } else { m_pUIElement = m_pMarkupContext->Parse(lpszMarkup); } if (m_hWnd) Invalidate(FALSE); } void CXTPMarkupStatic::SetMarkupTextEx(LPCWSTR lpszMarkup, UINT nCodePage /*= CP_UTF8*/) { MARKUP_RELEASE(m_pUIElement); if (lpszMarkup && wcsstr(lpszMarkup, L"%s") != NULL) { wchar_t* pMarkupFormatEscaped = XTPEscapeMarkupFormatPlaceholders(lpszMarkup); if (!XTP_ASSERT_CHECK(NULL != pMarkupFormatEscaped)) return; CString strCaption; GetWindowText(strCaption); # ifdef _UNICODE UNREFERENCED_PARAMETER(nCodePage); CString strMarkup; strMarkup.Format(pMarkupFormatEscaped, (LPCWSTR)strCaption); m_pUIElement = m_pMarkupContext->Parse(strMarkup); # else /*_UNICODE*/ CXTPResourceManager::CXTPA2W strCaptionW(strCaption, -1, nCodePage); CArray strMarkup; strMarkup.SetSize(XTPToIntPtr(strCaptionW.GetLength() + wcslen(lpszMarkup) + 1)); wsprintfW(strMarkup.GetData(), pMarkupFormatEscaped, strCaptionW.operator LPCWSTR()); m_pUIElement = m_pMarkupContext->Parse(strMarkup.GetData()); # endif /*!_UNICODE*/ free(pMarkupFormatEscaped); } else { m_pUIElement = m_pMarkupContext->Parse(lpszMarkup); } if (m_hWnd) Invalidate(FALSE); } void CXTPMarkupStatic::SetMarkupText(LPCSTR lpszMarkup) { MARKUP_RELEASE(m_pUIElement); m_pUIElement = m_pMarkupContext->Parse(lpszMarkup); if (m_hWnd) Invalidate(FALSE); } void CXTPMarkupStatic::SetMarkupText(LPCWSTR lpszMarkup) { MARKUP_RELEASE(m_pUIElement); m_pUIElement = m_pMarkupContext->Parse(lpszMarkup); if (m_hWnd) Invalidate(FALSE); } void CXTPMarkupStatic::OnPaint() { CPaintDC dcPaint(this); BOOL bRTL = XTPDrawHelpers()->IsContextRTL(dcPaint); if (bRTL && m_bIgnoreRTL) XTPDrawHelpers()->SetContextRTL(dcPaint, !bRTL); CXTPBufferDC dcBuffer(dcPaint); CXTPClientRect rc(this); HBRUSH hBrush = (HBRUSH)GetParent()->SendMessage(WM_CTLCOLORSTATIC, (WPARAM)dcBuffer.GetSafeHdc(), (LPARAM)m_hWnd); if (hBrush) { ::FillRect(dcBuffer.GetSafeHdc(), rc, hBrush); } else { dcBuffer.FillSolidRect(rc, GetXtremeColor(COLOR_3DFACE)); } if (m_pUIElement) { CXTPMarkupDrawingContext dc(dcBuffer); m_pUIElement->Measure(&dc, rc.Size()); m_pUIElement->Arrange(rc); m_pUIElement->Render(&dc); } } BOOL CXTPMarkupStatic::OnWndMsg(UINT message, WPARAM wParam, LPARAM lParam, LRESULT* pResult) { if (!m_pMarkupContext->IsDpiAware()) { m_pMarkupContext->SetDpiAware(TRUE, *this); } // To Handle Hyperlinks: if (m_pUIElement) { m_pMarkupContext->SetContextWindow(m_hWnd); if (m_pMarkupContext->OnWndMsg(m_pUIElement, message, wParam, lParam, pResult)) return TRUE; } return CStatic::OnWndMsg(message, wParam, lParam, pResult); } #endif