/** * @file XTPMarkupContext.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" #include "Common/Base/Diagnostic/XTPDisableAdvancedWarnings.h" #include #include "Common/Base/Diagnostic/XTPEnableAdvancedWarnings.h" #include "GraphicLibrary/GdiPlus/XTPGdiPlus.h" #include "Common/XTPTypeId.h" #include "Common/Math/XTPMathUtils.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/XTPActiveScriptEngine.h" #include "Common/XTPToolTipContext.h" #include "Common/XTPResourceManager.h" #include "Common/XTPMarkupRender.h" #include "Common/XTPImageManager.h" #include "Common/XTPXMLHelpers.h" #include "Common/XTPDrawHelpers.h" #include "Common/XTPColorManager.h" #include "Common/XTPVC80Helpers.h" #include "Common/Base/Types/XTPPoint2.h" #include "Common/Base/Types/XTPSize.h" #include "Common/Base/Types/XTPRect.h" #include "Common/ScrollBar/XTPScrollBase.h" using namespace Gdiplus; using namespace Gdiplus::DllExports; #include #include "Markup/XTPMarkupTools.h" #include "Markup/XTPMarkupObject.h" #include "Markup/XTPMarkupStyle.h" #include "Markup/XTPMarkupSetter.h" #include "Markup/XTPMarkupString.h" #include "Markup/XTPMarkupContext.h" #include "Markup/XTPMarkupInputElement.h" #include "Markup/XTPMarkupUIElement.h" #include "Markup/XTPMarkupFrameworkElement.h" #include "Markup/XTPMarkupTypedSimpleStack.h" #include "Markup/XTPMarkupBuilder.h" #include "Markup/XTPMarkupParser.h" #include "Markup/XTPMarkupDrawingContext.h" #include "Markup/XTPMarkupKeyboardNavigation.h" #include "Markup/XTPMarkupDelegate.h" #include "Markup/XTPMarkupEventHandlerMap.h" #include "Markup/XTPMarkupRoutedEventArgs.h" #include "Markup/XTPMarkupMouseEventArgs.h" #include "Markup/XTPMarkupMouseButtonEventArgs.h" #include "Markup/XTPMarkupMouseWheelEventArgs.h" #include "Markup/XTPMarkupQueryCursorEventArgs.h" #include "Markup/XTPMarkupFrameworkContentElement.h" #include "Markup/XTPMarkupResourceDictionary.h" #include "Markup/XTPMarkupThickness.h" #include "Markup/XTPMarkupTrigger.h" #include "Markup/XTPMarkupSetterCollection.h" #include "Markup/XTPMarkupTriggerCollection.h" #include "Markup/DeviceContext/XTPMarkupDeviceContext.h" #include "Markup/DeviceContext/XTPMarkupDeviceDependentImage.h" #include "Markup/Transform/XTPMarkupTransform.h" #include "Markup/Transform/XTPMarkupRotateTransform.h" #include "Markup/Transform/XTPMarkupSkewTransform.h" #include "Markup/Transform/XTPMarkupScaleTransform.h" #include "Markup/Transform/XTPMarkupTranslateTransform.h" #include "Markup/Transform/XTPMarkupGdiPlusTransformObject.h" #include "Markup/Transform/XTPMarkupGdiPlusRotateTransform.h" #include "Markup/Transform/XTPMarkupGdiPlusScaleTransform.h" #include "Markup/Transform/XTPMarkupGdiPlusSkewTransform.h" #include "Markup/Transform/XTPMarkupGdiPlusTranslateTransform.h" #include "Markup/Transform/XTPMarkupRenderTransform.h" #include "Markup/Transform/XTPMarkupMatrixTransform.h" #include "Markup/Transform/XTPMarkupGdiPlusMatrixTransform.h" #include "Markup/Shapes/XTPMarkupShape.h" #include "Markup/Shapes/XTPMarkupPath.h" #include "Markup/Shapes/XTPMarkupPolygon.h" #include "Markup/Shapes/XTPMarkupPolyline.h" #include "Markup/Shapes/XTPMarkupLine.h" #include "Markup/Shapes/XTPMarkupEllipse.h" #include "Markup/Shapes/XTPMarkupRectangle.h" #include "Markup/Shapes/XTPMarkupPathGeometry.h" #include "Markup/Shapes/XTPMarkupPathGeometryFigures.h" #include "Markup/Shapes/XTPMarkupPathData.h" #include "Markup/Controls/XTPMarkupDecorator.h" #include "Markup/Controls/XTPMarkupControl.h" #include "Markup/Controls/XTPMarkupPanel.h" #include "Markup/Controls/XTPMarkupBorder.h" #include "Markup/Controls/XTPMarkupViewbox.h" #include "Markup/Controls/XTPMarkupPage.h" #include "Markup/Controls/XTPMarkupImage.h" #include "Markup/Controls/XTPMarkupContentControl.h" #include "Markup/Controls/XTPMarkupButtonBase.h" #include "Markup/Controls/XTPMarkupDockPanel.h" #include "Markup/Controls/XTPMarkupWrapPanel.h" #include "Markup/Controls/XTPMarkupDefinitionBase.h" #include "Markup/Controls/XTPMarkupColumnDefinition.h" #include "Markup/Controls/XTPMarkupRowDefinition.h" #include "Markup/Controls/XTPMarkupStackPanel.h" #include "Markup/Controls/XTPMarkupGrid.h" #include "Markup/Controls/XTPMarkupCanvas.h" #include "Markup/Controls/XTPMarkupTextBlock.h" #include "Markup/Controls/XTPMarkupToggleButton.h" #include "Markup/Controls/XTPMarkupButton.h" #include "Markup/Controls/XTPMarkupScrollViewer.h" #include "Markup/Controls/XTPMarkupUniformGrid.h" #include "Markup/Controls/XTPMarkupCheckbox.h" #include "Markup/Controls/XTPMarkupRadioButton.h" #include "Markup/Controls/XTPMarkupScrollBar.h" #include "Markup/Controls/XTPMarkupScrollViewer.h" #include "Markup/Controls/XTPMarkupColumnDefinitionCollection.h" #include "Markup/Controls/XTPMarkupGridLength.h" #include "Markup/Controls/XTPMarkupRowDefinitionCollection.h" #include "Markup/Text/XTPMarkupTextElement.h" #include "Markup/Text/XTPMarkupInline.h" #include "Markup/Text/XTPMarkupSpan.h" #include "Markup/Text/XTPMarkupRun.h" #include "Markup/Text/XTPMarkupBold.h" #include "Markup/Text/XTPMarkupItalic.h" #include "Markup/Text/XTPMarkupLineBreak.h" #include "Markup/Text/XTPMarkupUnderline.h" #include "Markup/Text/XTPMarkupHyperlink.h" #include "Markup/Text/XTPMarkupInlineUIContainer.h" #include "Markup/Text/XTPMarkupInlineCollection.h" #include "Markup/Extensions/XTPMarkupStaticExtension.h" #include "Markup/Extensions/XTPMarkupSystemColorsStaticExtension.h" #include "Markup/Extensions/XTPMarkupAmbientColorsStaticExtension.h" #include "Markup/Extensions/XTPMarkupExtension.h" #include "Markup/Extensions/XTPMarkupXtpScript.h" #include "Markup/XTPMarkupIIDs.h" #include "Common/Base/Diagnostic/XTPDisableNoisyWarnings.h" #ifdef _DEBUG # undef THIS_FILE static char THIS_FILE[] = __FILE__; # define new DEBUG_NEW #endif #ifndef _XTP_DISABLE_COMPAREELEMENTS_SPECIALIZATION template<> AFX_INLINE BOOL AFXAPI CompareElements(const LPCWSTR* pElement1, const LPCWSTR* pElement2) { return wcscmp(*pElement1, *pElement2) == 0; } #endif ////////////////////////////////////////////////////////////////////////// // CXTPMarkupDelegateMap class CXTPMarkupDelegateMap { public: CXTPMarkupDelegateMap(); ~CXTPMarkupDelegateMap(); public: void RemoveAll(); void Add(LPCWSTR lpszDelegate, CXTPMarkupDelegate* pDelegate); CXTPMarkupDelegate* Lookup(LPCWSTR lpszDelegate) const; protected: CMap m_mapDelegates; public: LPDISPATCH m_lpHandler; }; class CXTPMarkupOleAutoDelegate : public CXTPMarkupDelegate { public: CXTPMarkupOleAutoDelegate(LPWSTR lpName, const CXTPMarkupDelegateMap* pMap) { m_lpName = lpName; m_pMap = pMap; } ~CXTPMarkupOleAutoDelegate() { delete[] m_lpName; } virtual void Execute(CXTPMarkupObject* pSender, CXTPMarkupRoutedEventArgs* pArgs); protected: const CXTPMarkupDelegateMap* m_pMap; LPWSTR m_lpName; }; CXTPMarkupDelegateMap::CXTPMarkupDelegateMap() { m_lpHandler = NULL; } CXTPMarkupDelegateMap::~CXTPMarkupDelegateMap() { RemoveAll(); m_lpHandler = NULL; } void CXTPMarkupDelegateMap::RemoveAll() { POSITION pos = m_mapDelegates.GetStartPosition(); while (pos) { LPCWSTR lpszDelegate; CXTPMarkupDelegate* pDelegate; m_mapDelegates.GetNextAssoc(pos, lpszDelegate, pDelegate); MARKUP_RELEASE(pDelegate); } m_mapDelegates.RemoveAll(); } void CXTPMarkupDelegateMap::Add(LPCWSTR lpszDelegate, CXTPMarkupDelegate* pDelegate) { m_mapDelegates.SetAt(lpszDelegate, pDelegate); } CXTPMarkupDelegate* CXTPMarkupDelegateMap::Lookup(LPCWSTR lpszDelegate) const { CXTPMarkupDelegate* pDelegate = NULL; if (!m_mapDelegates.Lookup(lpszDelegate, pDelegate)) return NULL; return pDelegate; } class CXTPMarkupContext::CInputElementCollection : public CXTPMarkupCollection { public: CInputElementCollection() { m_pElementType = MARKUP_TYPE(CXTPMarkupInputElement); m_bLogicalParent = FALSE; } public: CXTPMarkupInputElement* GetItem(int nIndex) const { return (CXTPMarkupInputElement*)m_arrItems[nIndex]; } CXTPMarkupInputElement* GetTailItem() const { return (CXTPMarkupInputElement*)m_arrItems[GetCount() - 1]; } }; class CXTPMarkupContext::CTooltipContext : public CXTPToolTipContext { public: CTooltipContext(CXTPMarkupContext* pMarkupContext) { m_pMarkupContext = pMarkupContext; } INT_PTR OnToolHitTest(CWnd* /*pWnd*/, CPoint point, TOOLINFO* pToolInfo) { return m_pMarkupContext->OnToolHitTest(point, pToolInfo); } protected: CXTPMarkupContext* m_pMarkupContext; }; ////////////////////////////////////////////////////////////////////////// // CXTPMarkupContext CXTPMarkupContext::CXTPMarkupContext() { CXTPNonClientMetrics ncm; ncm.lfMessageFont.lfCharSet = XTPResourceManager()->GetFontCharset(); #ifndef _XTP_ACTIVEX m_dwRef = 1; #endif m_logFont = ncm.lfMessageFont; // Some fonts defaults have to be overridden. m_logFont.lfWidth = 0; m_logFont.lfEscapement = 0; m_logFont.lfOrientation = 0; m_logFont.lfWeight = FW_DONTCARE; m_logFont.lfItalic = FALSE; m_logFont.lfStrikeOut = FALSE; m_logFont.lfUnderline = FALSE; m_DefaultSmoothingMode = xtpMarkupSmoothingDefault; m_bDefaultTextSmoothing = FALSE; m_clrForeground = 0; m_clrImgColorKey = COLORREF_NULL; m_pImageManager = NULL; m_pMouseOver = NULL; m_pMouseCapture = NULL; m_pActiveElement = NULL; m_hContextWnd = NULL; m_rcContextUpdateRect = CRect(0, 0, 0, 0); m_pHandlers = NULL; m_pDelegates = NULL; m_pFonts = NULL; m_pKeyboardNavigation = new CXTPMarkupKeyboardNavigation(this); m_pToolTipContext = new CTooltipContext(this); m_pToolTipContext->SetStyle(xtpToolTipMarkup); m_bUseCustomToolTipPos = FALSE; m_ptCustomToolTipPos = CPoint(0, 0); m_lpszScriptEngineLanguage = NULL; m_pScriptEngine = NULL; m_pScriptEngineStdRuntime = NULL; m_bEnableGdiPlus = TRUE; m_pDpi = NULL; m_pExtensionRoot = NULL; m_nFreezeUpdatesCounter = 0; m_bContainsPendingUpdates = FALSE; m_pSite = NULL; #ifdef _XTP_ACTIVEX EnableAutomation(); EnableTypeLib(); #else m_xActiveScriptSite.pThis = this; m_pInternalDispatch = NULL; #endif m_pDelegates = new CXTPMarkupDelegateMap(); RegisterClasses(); CXTPMarkupDrawingContext::Register(TRUE); } BOOL CXTPMarkupContext::m_bClassesRegistered = FALSE; void CXTPMarkupContext::RegisterClasses() { if (m_bClassesRegistered) return; m_bClassesRegistered = TRUE; CXTPMarkupType::RegisterAll(); CXTPMarkupType::RegisterType(); CXTPMarkupObject::RegisterType(); CXTPMarkupDependencyProperty::RegisterType(); CXTPMarkupObjectProperty::RegisterType(); CXTPMarkupBorder::RegisterType(); CXTPMarkupViewbox::RegisterType(); CXTPMarkupButton::RegisterType(); CXTPMarkupButtonBase::RegisterType(); CXTPMarkupCanvas::RegisterType(); CXTPMarkupCheckBox::RegisterType(); CXTPMarkupColumnDefinition::RegisterType(); CXTPMarkupColumnDefinitionCollection::RegisterType(); CXTPMarkupContentControl::RegisterType(); CXTPMarkupControl::RegisterType(); CXTPMarkupDefinitionBase::RegisterType(); CXTPMarkupDockPanel::RegisterType(); CXTPMarkupDefinitionCollection::RegisterType(); CXTPMarkupGrid::RegisterType(); CXTPMarkupGridLength::RegisterType(); CXTPMarkupImage::RegisterType(); CXTPMarkupPage::RegisterType(); CXTPMarkupWindowContainer::RegisterType(); CXTPMarkupPanel::RegisterType(); CXTPMarkupRadioButton::RegisterType(); CXTPMarkupRowDefinition::RegisterType(); CXTPMarkupRowDefinitionCollection::RegisterType(); CXTPMarkupScrollBar::RegisterType(); CXTPMarkupScrollBarGripper::RegisterType(); CXTPMarkupScrollViewer::RegisterType(); CXTPMarkupStackPanel::RegisterType(); CXTPMarkupTextBlock::RegisterType(); CXTPMarkupToggleButton::RegisterType(); CXTPMarkupUniformGrid::RegisterType(); CXTPMarkupWrapPanel::RegisterType(); CXTPMarkupExtension::RegisterType(); CXTPMarkupXtpScript::RegisterType(); CXTPMarkupEllipse::RegisterType(); CXTPMarkupLine::RegisterType(); CXTPMarkupPath::RegisterType(); CXTPMarkupPathData::RegisterType(); CXTPMarkupPathGeometry::RegisterType(); CXTPMarkupPathGeometryFigures::RegisterType(); CXTPMarkupPolygon::RegisterType(); CXTPMarkupPolyline::RegisterType(); CXTPMarkupRectangle::RegisterType(); CXTPMarkupShape::RegisterType(); CXTPMarkupBold::RegisterType(); CXTPMarkupHyperlink::RegisterType(); CXTPMarkupInline::RegisterType(); CXTPMarkupInlineCollection::RegisterType(); CXTPMarkupInlineUIContainer::RegisterType(); CXTPMarkupItalic::RegisterType(); CXTPMarkupLineBreak::RegisterType(); CXTPMarkupRun::RegisterType(); CXTPMarkupSpan::RegisterType(); CXTPMarkupTextElement::RegisterType(); CXTPMarkupUnderline::RegisterType(); CXTPMarkupGdiPlusMatrixTransform::RegisterType(); CXTPMarkupGdiPlusRotateTransform::RegisterType(); CXTPMarkupGdiPlusScaleTransform::RegisterType(); CXTPMarkupGdiPlusSkewTransform::RegisterType(); CXTPMarkupGdiPlusTranslateTransform::RegisterType(); CXTPMarkupRenderTransform::RegisterType(); CXTPMarkupTransform::RegisterType(); CXTPMarkupRotateTransform::RegisterType(); CXTPMarkupScaleTransform::RegisterType(); CXTPMarkupSkewTransform::RegisterType(); CXTPMarkupTranslateTransform::RegisterType(); CXTPMarkupGradientStop::RegisterType(); CXTPMarkupGradientStops::RegisterType(); CXTPMarkupGradientBrush::RegisterType(); CXTPMarkupLinearGradientBrush::RegisterType(); CXTPMarkupSolidColorBrush::RegisterType(); CXTPMarkupFrameworkContentElement::RegisterType(); CXTPMarkupFrameworkElement::RegisterType(); CXTPMarkupKeyboardNavigation::RegisterType(); CXTPMarkupCollection::RegisterType(); CXTPMarkupDoubleCollection::RegisterType(); CXTPMarkupResourceDictionary::RegisterType(); CXTPMarkupSetter::RegisterType(); CXTPMarkupSetterCollection::RegisterType(); CXTPMarkupStyle::RegisterType(); CXTPMarkupTrigger::RegisterType(); CXTPMarkupTriggerCollection::RegisterType(); CXTPMarkupBrush::RegisterType(); CXTPMarkupBrushKey::RegisterType(); CXTPMarkupScrollBarGripper::RegisterType(); CXTPMarkupUIElement::RegisterType(); CXTPMarkupVisual::RegisterType(); CXTPMarkupInputElement::RegisterType(); CXTPMarkupInt::RegisterType(); CXTPMarkupDouble::RegisterType(); CXTPMarkupEnum::RegisterType(); CXTPMarkupBool::RegisterType(); CXTPMarkupColor::RegisterType(); CXTPMarkupString::RegisterType(); CXTPMarkupColorKey::RegisterType(); CXTPMarkupPoint::RegisterType(); CXTPMarkupPointCollection::RegisterType(); CXTPMarkupScrollBar::RegisterType(); CXTPMarkupThickness::RegisterType(); } void CXTPMarkupContext::UnregisterClasses() { if (!m_bClassesRegistered) return; m_bClassesRegistered = FALSE; CXTPMarkupType::UnregisterAll(); } CXTPMarkupContext::~CXTPMarkupContext() { Shutdown(); MARKUP_RELEASE(m_pKeyboardNavigation); SAFE_DELETE(m_pDelegates); CMDTARGET_RELEASE(m_pToolTipContext); #ifndef _XTP_ACTIVEX CMDTARGET_RELEASE(m_pInternalDispatch); #endif CXTPMarkupDrawingContext::Register(FALSE); SAFE_DELETE(m_pDpi); } void CXTPMarkupContext::Shutdown() { Cleanup(); ResetScriptEngine(TRUE); if (NULL != m_pExtensionRoot) { delete m_pExtensionRoot; m_pExtensionRoot = NULL; } CMDTARGET_RELEASE(m_pImageManager); m_pMouseOver = NULL; _ASSERTE(m_pFonts == NULL || m_pFonts->IsEmpty()); SAFE_DELETE(m_pFonts); SAFE_DELETE(m_pHandlers); } CXTPMarkupStaticExtension* CXTPMarkupContext::GetExtensionRoot() { if (NULL == m_pExtensionRoot) { class CRootStaticExtension : public CXTPMarkupStaticExtension { public: CRootStaticExtension() : CXTPMarkupStaticExtension(L"__root__", FALSE) { } }; m_pExtensionRoot = new CRootStaticExtension(); m_pExtensionRoot->Extend(new CXTPMarkupSystemColorsStaticExtension()); m_pExtensionRoot->Extend(new CXTPMarkupAmbientColorsStaticExtension()); } return m_pExtensionRoot; } int CXTPMarkupContext::ScaleX(int x) const { return NULL != m_pDpi ? m_pDpi->ScaleX(x) : x; } int CXTPMarkupContext::ScaleY(int y) const { return NULL != m_pDpi ? m_pDpi->ScaleY(y) : y; } float CXTPMarkupContext::ScaleX(float x) const { return NULL != m_pDpi ? m_pDpi->ScaleX(x) : x; } float CXTPMarkupContext::ScaleY(float y) const { return NULL != m_pDpi ? m_pDpi->ScaleY(y) : y; } double CXTPMarkupContext::ScaleX(double x) const { return NULL != m_pDpi ? m_pDpi->ScaleX(x) : x; } double CXTPMarkupContext::ScaleY(double y) const { return NULL != m_pDpi ? m_pDpi->ScaleY(y) : y; } CSize CXTPMarkupContext::Scale(const SIZE& size) const { return NULL != m_pDpi ? CSize(ScaleX(static_cast(size.cx)), ScaleY(static_cast(size.cy))) : size; } double CXTPMarkupContext::UnscaleX(double x) const { return NULL != m_pDpi ? m_pDpi->UnscaleX(x) : x; } double CXTPMarkupContext::UnscaleY(double y) const { return NULL != m_pDpi ? m_pDpi->UnscaleY(y) : y; } CXTPMarkupObject* CXTPMarkupContext::CreateMarkupObject(CXTPMarkupType* pType) { CXTPMarkupObject* pObject = pType->CreateObject(this); if (NULL != pObject) { #ifdef _XTP_ACTIVEX InternalAddRef(); #else AddRef(); #endif } return (CXTPMarkupObject*)pObject; } void CXTPMarkupContext::Cleanup() { FreeCachedImages(); m_pMouseOver = NULL; m_pActiveElement = NULL; if (m_pMouseCapture) { m_pMouseCapture = NULL; ReleaseCapture(); } if (NULL != m_pFonts) { CXTPMarkupFont* pFont = m_pFonts->RemoveHead(); while (NULL != pFont) { MARKUP_RELEASE(pFont); pFont = m_pFonts->RemoveHead(); } } } void CXTPMarkupContext::FinalizeMarkupObject(CXTPMarkupObject* pObject) { if (pObject == m_pMouseOver) m_pMouseOver = NULL; if (pObject == m_pActiveElement) m_pActiveElement = NULL; if (pObject == m_pMouseCapture) { m_pMouseCapture = NULL; ReleaseCapture(); } Release(); } CXTPMarkupUIElement* CXTPMarkupContext::Parse(LPCSTR lpszBuffer) { Cleanup(); if (!lpszBuffer) return NULL; CXTPMarkupUIElement* pRootElement = NULL; CXTPMarkupParser sc; if (sc.SetBuffer(lpszBuffer, lpszBuffer + strlen(lpszBuffer))) { CXTPMarkupBuilder builder(this); pRootElement = builder.Parse(&sc); } return pRootElement; } CXTPMarkupUIElement* CXTPMarkupContext::Parse(LPCWSTR lpszBuffer) { Cleanup(); if (!lpszBuffer) return NULL; CXTPMarkupUIElement* pRootElement = NULL; CXTPMarkupParser sc; if (sc.SetBuffer(lpszBuffer, lpszBuffer + wcslen(lpszBuffer))) { CXTPMarkupBuilder builder(this); pRootElement = builder.Parse(&sc); } return pRootElement; } template static CString DoValidateXML(CharPtr lpszBuffer, SIZE_T cch, CXTPMarkupContext* pCtx) { _ASSERTE(NULL != pCtx); if (NULL == lpszBuffer) { return _T("Done."); } CString strMessage; CXTPMarkupParser sc; if (!sc.SetBuffer(lpszBuffer, lpszBuffer + cch)) { return sc.FormatErrorMessage(); } CXTPMarkupBuilder builder(pCtx); CXTPMarkupUIElement* pUIElement = builder.Parse(&sc); if (NULL == pUIElement) { return builder.GetLastError(); } MARKUP_RELEASE(pUIElement); return _T("Done."); } CString CXTPMarkupContext::ValidateXML(LPCSTR lpszBuffer) { Cleanup(); return DoValidateXML(lpszBuffer, (NULL != lpszBuffer ? strlen(lpszBuffer) : 0), this); } CString CXTPMarkupContext::ValidateXML(LPCWSTR lpszBuffer) { Cleanup(); return DoValidateXML(lpszBuffer, (NULL != lpszBuffer ? wcslen(lpszBuffer) : 0), this); } BOOL CXTPMarkupContext::CompareFont(LOGFONT* pLogFont1, LOGFONT* pLogFont2) { if (pLogFont1->lfHeight != pLogFont2->lfHeight) return FALSE; if (pLogFont1->lfWeight != pLogFont2->lfWeight) return FALSE; if (pLogFont1->lfItalic != pLogFont2->lfItalic) return FALSE; if (pLogFont1->lfQuality != pLogFont2->lfQuality) return FALSE; if (pLogFont1->lfEscapement != pLogFont2->lfEscapement) return FALSE; if (pLogFont1->lfOrientation != pLogFont2->lfOrientation) return FALSE; if (_tcscmp(pLogFont1->lfFaceName, pLogFont2->lfFaceName) != 0) return FALSE; return TRUE; } void CXTPMarkupContext::Redraw(LPCRECT pRect /*= NULL*/, BOOL bPending /*= FALSE*/) { if (NULL == m_hContextWnd || !::IsWindow(m_hContextWnd)) return; CRect rc = (NULL != pRect ? *pRect : CRect(0, 0, 0, 0)); if (rc.IsRectNull()) rc = m_rcContextUpdateRect; pRect = (!rc.IsRectNull() ? &rc : NULL); if (bPending) { ::InvalidateRect(m_hContextWnd, pRect, FALSE); } else if (FALSE == ::SendMessage(m_hContextWnd, XTP_WM_MARKUPREDRAW, 0, XTPToLPARAM(pRect))) { ::InvalidateRect(m_hContextWnd, pRect, FALSE); ::UpdateWindow(m_hContextWnd); } } void CXTPMarkupContext::SetContextWindow(HWND hWnd, LPCRECT pUpdateRect /*= NULL*/) { m_hContextWnd = hWnd; m_rcContextUpdateRect = (NULL != pUpdateRect ? *pUpdateRect : CRect(0, 0, 0, 0)); } void CXTPMarkupContext::LoadScriptCodeChunk(CXTPMarkupBuilder* pBuilder, LPCWSTR lpszLanguage, LPCWSTR lpszCode, LPCWSTR lpszRequires /*= NULL*/) { _ASSERTE(NULL != pBuilder); _ASSERTE(NULL != lpszLanguage); _ASSERTE(NULL != lpszCode); if (NULL == m_pScriptEngine) { // Initialize scripting engine. m_pScriptEngine = new CXTPActiveScriptEngine(); HRESULT hr = m_pScriptEngine->Initialize(lpszLanguage, &m_xActiveScriptSite); if (FAILED(hr)) { ResetScriptEngine(); pBuilder->ThrowBuilderException(hr); } // Add standard runtime extension. hr = m_pScriptEngine->AddNamedItem(L"__XTPActiveScriptStdRuntime", NULL, SCRIPTITEM_GLOBALMEMBERS); if (FAILED(hr)) { ResetScriptEngine(); pBuilder->ThrowBuilderException(hr); } // Add custom global objects. CList namedItems; GetScriptNamedItemNames(namedItems); POSITION posNamedItem = namedItems.GetHeadPosition(); while (NULL != posNamedItem) { LPCWSTR lpszName = namedItems.GetNext(posNamedItem); hr = m_pScriptEngine->AddNamedItem(lpszName, NULL, SCRIPTITEM_ISVISIBLE | SCRIPTITEM_GLOBALMEMBERS | SCRIPTITEM_ISSOURCE); if (FAILED(hr)) { ResetScriptEngine(); pBuilder->ThrowBuilderException(hr); } } m_lpszScriptEngineLanguage = _wcsdup(lpszLanguage); } else if (0 != wcscmp(m_lpszScriptEngineLanguage, lpszLanguage)) { CString message; message.Format(_T("'%ls' script engine is not allowed to use when '%ls' is already used."), lpszLanguage, m_lpszScriptEngineLanguage); pBuilder->ThrowBuilderException(message); } m_ScriptCodeChunks.AddTail(new CCodeChunk(lpszCode, lpszRequires)); } void CXTPMarkupContext::RunScriptEngine(CXTPMarkupBuilder* pBuilder) { _ASSERTE(NULL != pBuilder); if (NULL != m_pScriptEngine) { // Load code chunks. POSITION posChunk = m_ScriptCodeChunks.GetHeadPosition(); while (NULL != posChunk) { HRESULT hr; CCodeChunk* pChunk = m_ScriptCodeChunks.GetNext(posChunk); if (NULL == m_pSite) { hr = m_pScriptEngine->LoadCode(pChunk->GetCode()); } else { LPCWSTR pCode = pChunk->GetCode(); LPWSTR pNewCode = m_pSite->PrepareCodeChunk(pCode, pChunk->GetRequirements()); hr = m_pScriptEngine->LoadCode(NULL != pNewCode ? pNewCode : pCode); if (NULL != pNewCode && pNewCode != pCode) free(pNewCode); } if (FAILED(hr)) ThrowScriptEngineException(pBuilder, hr); } // Run engine script. HRESULT hr = m_pScriptEngine->Run(); if (FAILED(hr)) ThrowScriptEngineException(pBuilder, hr); } } void CXTPMarkupContext::AddCustomScriptItem(LPCWSTR lpName, LPDISPATCH pDisp) { CCustomScriptItem*& pItem = m_CustomScriptItems[XTP_CW2CT(lpName)]; pItem = new CCustomScriptItem(lpName, pDisp); } void CXTPMarkupContext::RemoveCustomScriptItem(LPCWSTR lpName) { CString strName = XTP_CW2CT(lpName); CCustomScriptItem* pItem = NULL; if (!m_CustomScriptItems.Lookup(strName, pItem)) return; if (NULL != pItem) { delete pItem; pItem = NULL; } m_CustomScriptItems.RemoveKey(strName); } void CXTPMarkupContext::ResetScriptEngine(BOOL bFinal /*= FALSE*/) { if (bFinal) { POSITION pos = m_CustomScriptItems.GetStartPosition(); while (NULL != pos) { CString strName; CCustomScriptItem* pItem = NULL; m_CustomScriptItems.GetNextAssoc(pos, strName, pItem); _ASSERTE(NULL != pItem); delete pItem; } m_CustomScriptItems.RemoveAll(); } while (!m_ScriptCodeChunks.IsEmpty()) delete m_ScriptCodeChunks.RemoveTail(); if (NULL != m_lpszScriptEngineLanguage) { free(m_lpszScriptEngineLanguage); m_lpszScriptEngineLanguage = NULL; } if (NULL != m_pScriptEngineStdRuntime) m_pScriptEngineStdRuntime->Shutdown(); if (NULL != m_pScriptEngine) { m_pScriptEngine->Uninitialize(); CMDTARGET_RELEASE(m_pScriptEngine); } CMDTARGET_RELEASE(m_pScriptEngineStdRuntime); } void CXTPMarkupContext::RegisterScriptNamedObjects(CXTPMarkupBuilder* pBuilder, CXTPMarkupObject* pObject) { _ASSERTE(NULL != pBuilder); _ASSERTE(NULL != pObject); if (NULL != m_pScriptEngine) { LPCWSTR lpszName = pObject->GetName(); if (NULL != lpszName) { HRESULT hr = m_pScriptEngine->AddNamedItem(lpszName, pObject, SCRIPTITEM_ISVISIBLE); if (FAILED(hr)) { pBuilder->ThrowBuilderException(hr); } } int nChildrenCount = pObject->GetLogicalChildrenCount(); for (int i = 0; i < nChildrenCount; i++) { CXTPMarkupObject* pChildObject = pObject->GetLogicalChild(i); RegisterScriptNamedObjects(pBuilder, pChildObject); } } } void CXTPMarkupContext::GetScriptNamedItemNames(CList& names) { names.AddTail(L"MarkupContext"); POSITION pos = m_CustomScriptItems.GetStartPosition(); while (NULL != pos) { CString strName; CCustomScriptItem* pItem = NULL; m_CustomScriptItems.GetNextAssoc(pos, strName, pItem); _ASSERTE(NULL != pItem); names.AddTail(pItem->GetName()); } } HRESULT CXTPMarkupContext::GetScriptNamedItem(LPCWSTR lpszName, IUnknown** ppiunkItem) { _ASSERTE(NULL != lpszName); _ASSERTE(NULL != ppiunkItem); *ppiunkItem = NULL; if (0 == wcscmp(lpszName, L"MarkupContext")) return AccessInternalDispatch()->GetControllingUnknown()->QueryInterface(ppiunkItem); POSITION pos = m_CustomScriptItems.GetStartPosition(); while (NULL != pos) { CString strName; CCustomScriptItem* pItem = NULL; m_CustomScriptItems.GetNextAssoc(pos, strName, pItem); _ASSERTE(NULL != pItem); if (0 == wcscmp(lpszName, pItem->GetName())) { *ppiunkItem = pItem->GetDispatch(); (*ppiunkItem)->AddRef(); return S_OK; } } return E_NOINTERFACE; } void CXTPMarkupContext::ThrowScriptEngineException(CXTPMarkupBuilder* pBuilder, HRESULT hr) { _ASSERTE(NULL != pBuilder); _ASSERTE(FAILED(hr)); _ASSERTE(NULL != m_pScriptEngine); const CXTPActiveScriptEngine::ExceptionData* pExcepData = m_pScriptEngine->GetExceptionData(); if (NULL != pExcepData) { CString message; if (NULL != pExcepData->strCodeLine) { message.Format(_T("Script error [0x%08X]: %ls (at %u:%i '%ls')"), (0 != pExcepData->info.wCode ? pExcepData->info.wCode : pExcepData->info.scode), (NULL != pExcepData->info.bstrDescription ? pExcepData->info.bstrDescription : L""), pExcepData->nLine, pExcepData->nCharPos, pExcepData->strCodeLine); } else if (0 != pExcepData->nLine || 0 != pExcepData->nCharPos) { message.Format(_T("Script error [0x%08X]: %ls (at %u:%i)"), (0 != pExcepData->info.wCode ? pExcepData->info.wCode : pExcepData->info.scode), (NULL != pExcepData->info.bstrDescription ? pExcepData->info.bstrDescription : L""), pExcepData->nLine, pExcepData->nCharPos); } else { message.Format(_T("Script error [0x%08X]: %ls"), (0 != pExcepData->info.wCode ? pExcepData->info.wCode : pExcepData->info.scode), (NULL != pExcepData->info.bstrDescription ? pExcepData->info.bstrDescription : L"")); } pBuilder->ThrowBuilderException(message); } else { pBuilder->ThrowBuilderException(hr); } } CXTPMarkupFont* CXTPMarkupContext::GetFont(LOGFONT* pLogFont) { if (m_pFonts == NULL) m_pFonts = new CXTPMarkupTypedSimpleStack(); CXTPMarkupFont* pFont; for (pFont = m_pFonts->GetHead(); pFont != NULL; pFont = pFont->m_pNextChain) { if (NULL != pFont->m_Font.GetSafeHandle()) { LOGFONT lf; pFont->m_Font.GetLogFont(&lf); if (CompareFont(&lf, pLogFont)) { pFont->AddRef(); return pFont; } } } pFont = new CXTPMarkupFont(); m_pFonts->AddTail(pFont); pFont->m_Font.CreateFontIndirect(pLogFont); pFont->m_pMarkupContext = this; MARKUP_ADDREF(pFont); return pFont; } BOOL CXTPMarkupContext::IsVisualChild(CXTPMarkupObject* pParent, CXTPMarkupObject* pChild) const { while (pChild) { if (pChild == pParent) return TRUE; pChild = pChild->GetLogicalParent(); } return FALSE; } void CXTPMarkupContext::BuildInputList(CXTPMarkupObject* pUIElement, CInputElementCollection* arrObjects) { CXTPMarkupObject* pParent = pUIElement; while (pParent) { if (pParent->IsKindOf(MARKUP_TYPE(CXTPMarkupInputElement))) { arrObjects->Add((CXTPMarkupInputElement*)pParent); pParent->AddRef(); } pParent = pParent->GetLogicalParent(); } } INT_PTR CXTPMarkupContext::OnToolHitTest(CPoint /*point*/, TOOLINFO* pToolInfo) { CInputElementCollection listMouseOver; BuildInputList(m_pMouseOver, &listMouseOver); for (int i = 0; i < listMouseOver.GetCount(); i++) { CXTPMarkupInputElement* pInputElement = listMouseOver.GetItem(i); CXTPMarkupObject* pToolTip = pInputElement->GetToolTip(); if (pToolTip && IsStringObject(pToolTip)) { CXTPToolTipContext::FillInToolInfo(pToolInfo, m_hContextWnd, GetClientBoundingRect(pInputElement), (INT_PTR)pInputElement, (LPCWSTR) * ((CXTPMarkupString*)pToolTip)); if (GetUseCustomToolTipPosition()) { pToolInfo->rect.left = m_ptCustomToolTipPos.x; if (pToolInfo->cbSize == sizeof(XTP_TOOLTIP_TOOLINFO_EX)) { RECT* pRC = &(((XTP_TOOLTIP_TOOLINFO_EX*)pToolInfo)->pToolInfo->rcExclude); pRC->bottom = m_ptCustomToolTipPos.y; // ensure that rcExclude non empty pRC->top = pRC->bottom - 10; pRC->right = m_ptCustomToolTipPos.x; pRC->left = pRC->right - 10; } } return XTPToIntPtr(pToolInfo->uId); } } return -1; } void CXTPMarkupContext::HandleMouseEnter(CXTPMarkupInputElement* pMouseOver, CPoint point) { if (m_pMouseOver == pMouseOver) return; if (!pMouseOver) m_pActiveElement = NULL; CInputElementCollection listOldMouseOver; CInputElementCollection listNewMouseOver; BuildInputList(m_pMouseOver, &listOldMouseOver); BuildInputList(pMouseOver, &listNewMouseOver); while (listOldMouseOver.GetCount() > 0 && listNewMouseOver.GetCount() > 0 && listOldMouseOver.GetTailItem() == listNewMouseOver.GetTailItem()) { listNewMouseOver.Remove(listNewMouseOver.GetCount() - 1); listOldMouseOver.Remove(listOldMouseOver.GetCount() - 1); } CXTPMarkupMouseEventArgs* eMouseLeaveEventArgs = new CXTPMarkupMouseEventArgs( CXTPMarkupInputElement::m_pMouseLeaveEvent); CXTPMarkupMouseEventArgs* eMouseEnterEventArgs = new CXTPMarkupMouseEventArgs( CXTPMarkupInputElement::m_pMouseEnterEvent); eMouseLeaveEventArgs->SetSource(m_pMouseOver); eMouseLeaveEventArgs->m_hWnd = m_hContextWnd; eMouseLeaveEventArgs->m_point = point; eMouseEnterEventArgs->SetSource(pMouseOver); eMouseEnterEventArgs->m_hWnd = m_hContextWnd; eMouseEnterEventArgs->m_point = point; m_pMouseOver = pMouseOver; int i; for (i = 0; i < listOldMouseOver.GetCount(); i++) { CXTPMarkupInputElement* pInputElement = listOldMouseOver.GetItem(i); pInputElement->RaiseEvent(eMouseLeaveEventArgs); if (eMouseLeaveEventArgs->IsHandled()) break; pInputElement->OnMouseLeave(eMouseLeaveEventArgs); if (eMouseLeaveEventArgs->IsHandled()) break; } for (i = 0; i < listNewMouseOver.GetCount(); i++) { CXTPMarkupInputElement* pInputElement = listNewMouseOver.GetItem(i); pInputElement->RaiseEvent(eMouseEnterEventArgs); if (eMouseEnterEventArgs->IsHandled()) break; pInputElement->OnMouseEnter(eMouseEnterEventArgs); if (eMouseEnterEventArgs->IsHandled()) break; } eMouseLeaveEventArgs->Release(); eMouseEnterEventArgs->Release(); } void CXTPMarkupContext::HandleMouseMove(CXTPMarkupUIElement* pUIElement, CPoint point) { CXTPMarkupInputElement* pObject = pUIElement->InputHitTest(point); if (m_pMouseCapture) { if ((pObject == NULL) || !IsVisualChild(m_pMouseCapture, pObject)) pObject = NULL; else pObject = m_pMouseCapture; } if (m_pMouseOver != pObject) { HandleMouseEnter(pObject, point); if (m_pMouseOver) { TRACKMOUSEEVENT tme = { sizeof(TRACKMOUSEEVENT), TME_LEAVE, m_hContextWnd, 0 }; _TrackMouseEvent(&tme); } if (!HandleSetCursor()) { SetCursor(AfxGetApp()->LoadStandardCursor(IDC_ARROW)); } } m_pActiveElement = m_pMouseOver ? pUIElement : NULL; if (m_pMouseOver) { CInputElementCollection listNewMouseOver; BuildInputList(m_pMouseOver, &listNewMouseOver); CXTPMarkupMouseEventArgs* eMouseMoveEventArgs = new CXTPMarkupMouseEventArgs( CXTPMarkupInputElement::m_pMouseMoveEvent); eMouseMoveEventArgs->SetSource(m_pMouseOver); eMouseMoveEventArgs->m_hWnd = m_hContextWnd; eMouseMoveEventArgs->m_point = point; for (int i = 0; i < listNewMouseOver.GetCount(); i++) { CXTPMarkupInputElement* pInputElement = listNewMouseOver.GetItem(i); pInputElement->RaiseEvent(eMouseMoveEventArgs); if (eMouseMoveEventArgs->IsHandled()) break; pInputElement->OnMouseMove(eMouseMoveEventArgs); if (eMouseMoveEventArgs->IsHandled()) break; } eMouseMoveEventArgs->Release(); } } BOOL CXTPMarkupContext::HandleSetCursor() { if (m_pMouseOver) { CInputElementCollection listNewMouseOver; BuildInputList(m_pMouseOver, &listNewMouseOver); CXTPMarkupQueryCursorEventArgs eQueryCursorEventArgs; eQueryCursorEventArgs.SetSource(m_pMouseOver); for (int i = 0; i < listNewMouseOver.GetCount(); i++) { CXTPMarkupInputElement* pInputElement = listNewMouseOver.GetItem(i); pInputElement->OnQueryCursor(&eQueryCursorEventArgs); if (!eQueryCursorEventArgs.IsHandled()) continue; if (eQueryCursorEventArgs.m_hCursor) { ::SetCursor(eQueryCursorEventArgs.m_hCursor); return TRUE; } return FALSE; } } return FALSE; } BOOL CXTPMarkupContext::HandleMouseWheel(int nDelta) { if (m_pMouseOver) { CInputElementCollection listNewMouseOver; BuildInputList(m_pMouseOver, &listNewMouseOver); CXTPMarkupMouseWheelEventArgs eMouseWheelEventArgs; eMouseWheelEventArgs.m_nDelta = nDelta; eMouseWheelEventArgs.SetSource(m_pMouseOver); for (int i = 0; i < listNewMouseOver.GetCount(); i++) { CXTPMarkupInputElement* pInputElement = listNewMouseOver.GetItem(i); pInputElement->OnMouseWheel(&eMouseWheelEventArgs); if (eMouseWheelEventArgs.IsHandled()) return TRUE; } } return FALSE; } BOOL CXTPMarkupContext::HandleMouseUpDown(UINT message, WPARAM /*wParam*/, LPARAM lParam) { CXTPMarkupInputElement* pMouseOver = m_pMouseOver; if (m_pMouseCapture) pMouseOver = m_pMouseCapture; if (!pMouseOver) return FALSE; CInputElementCollection listNewMouseOver; BuildInputList(pMouseOver, &listNewMouseOver); CXTPMarkupMouseButtonEventArgs* eMouseButtonEventArgs = new CXTPMarkupMouseButtonEventArgs( message == WM_LBUTTONDOWN || message == WM_LBUTTONDBLCLK ? CXTPMarkupInputElement::m_pMouseLeftButtonDownEvent : message == WM_LBUTTONUP ? CXTPMarkupInputElement::m_pMouseLeftButtonUpEvent : message == WM_RBUTTONDOWN ? CXTPMarkupInputElement::m_pMouseRightButtonDownEvent : message == WM_RBUTTONUP ? CXTPMarkupInputElement::m_pMouseRightButtonUpEvent : NULL); eMouseButtonEventArgs->SetSource(pMouseOver); eMouseButtonEventArgs->m_hWnd = m_hContextWnd; eMouseButtonEventArgs->m_point = lParam; for (int i = 0; i < listNewMouseOver.GetCount(); i++) { CXTPMarkupInputElement* pInputElement = listNewMouseOver.GetItem(i); pInputElement->RaiseEvent(eMouseButtonEventArgs); if (eMouseButtonEventArgs->IsHandled()) break; if (message == WM_LBUTTONDOWN || message == WM_LBUTTONDBLCLK) { pInputElement->OnMouseLeftButtonDown(eMouseButtonEventArgs); } else if (message == WM_LBUTTONUP) { pInputElement->OnMouseLeftButtonUp(eMouseButtonEventArgs); } else if (message == WM_RBUTTONDOWN) { pInputElement->OnMouseRightButtonDown(eMouseButtonEventArgs); } else if (message == WM_RBUTTONUP) { pInputElement->OnMouseRightButtonUp(eMouseButtonEventArgs); } if (eMouseButtonEventArgs->IsHandled()) break; } BOOL bHandled = eMouseButtonEventArgs->IsHandled(); eMouseButtonEventArgs->Release(); return bHandled; } void CXTPMarkupContext::CaptureMouse(CXTPMarkupInputElement* pUIElement) { if (m_pMouseCapture == pUIElement) return; ::SetCapture(m_hContextWnd); m_pMouseCapture = pUIElement; } void CXTPMarkupContext::ReleaseMouseCapture(CXTPMarkupInputElement* /*pUIElement*/) { m_pMouseCapture = NULL; ::ReleaseCapture(); } BOOL CXTPMarkupContext::OnWndMsg(CXTPMarkupUIElement* pUIElement, UINT message, WPARAM wParam, LPARAM lParam, LRESULT* pResult) { if (!m_hContextWnd) return FALSE; if (!pUIElement) { if (m_pActiveElement) { HandleMouseEnter(NULL, CPoint(-1, -1)); } return FALSE; } if (message == WM_MOUSEMOVE) { HandleMouseMove(pUIElement, CPoint(lParam)); } if (message == WM_DESTROY || message == WM_MOUSELEAVE) { HandleMouseEnter(NULL, CPoint(-1, -1)); } if ((message >= WM_MOUSEFIRST && message <= WM_MOUSELAST) || (message == WM_MOUSELEAVE)) { m_pToolTipContext->FilterToolTipMessage(CWnd::FromHandle(m_hContextWnd), message, wParam, lParam); } if (message == WM_SETCURSOR) { if (HandleSetCursor()) { *pResult = TRUE; return TRUE; } } if (message == WM_MOUSEWHEEL) { if (HandleMouseWheel((short)HIWORD(wParam))) { *pResult = TRUE; return TRUE; } } if (message == WM_LBUTTONDOWN || message == WM_RBUTTONDOWN || message == WM_LBUTTONUP || message == WM_RBUTTONUP || message == WM_LBUTTONDBLCLK) { if (HandleMouseUpDown(message, wParam, lParam)) return TRUE; } if (message == WM_CAPTURECHANGED && m_pMouseCapture) { CXTPMarkupMouseEventArgs* eLostMouseCaptureEventArgs = new CXTPMarkupMouseEventArgs( CXTPMarkupInputElement::m_pLostMouseCaptureEvent); eLostMouseCaptureEventArgs->SetSource(m_pMouseCapture); CXTPMarkupInputElement* pInputElement = m_pMouseCapture; pInputElement->RaiseEvent(eLostMouseCaptureEventArgs); if (!eLostMouseCaptureEventArgs->IsHandled()) { pInputElement->OnLostMouseCapture(eLostMouseCaptureEventArgs); } eLostMouseCaptureEventArgs->Release(); m_pMouseCapture = NULL; } if (message == WM_KEYDOWN || message == WM_SETFOCUS || message == WM_KILLFOCUS) { if (m_pKeyboardNavigation->OnWndMsg(message, wParam, lParam, pResult)) return TRUE; } return FALSE; } void CXTPMarkupContext::RaiseEvent(CXTPMarkupObject* pSource, CXTPMarkupRoutedEventArgs* pEventArgs) { if (m_pHandlers) m_pHandlers->Raise(pSource, pEventArgs); } void CXTPMarkupContext::AddHandler(CXTPMarkupRoutedEvent* pEvent, CXTPMarkupDelegate* pDelegate) { if (m_pHandlers == NULL) m_pHandlers = new CXTPMarkupEventHandlerMap(); m_pHandlers->Add(pEvent, pDelegate); } void CXTPMarkupContext::SetDelegate(LPCWSTR lpszHandler, CXTPMarkupDelegate* pDelegate) { if (m_pDelegates == NULL) m_pDelegates = new CXTPMarkupDelegateMap(); m_pDelegates->Add(lpszHandler, pDelegate); } CXTPMarkupDelegate* CXTPMarkupContext::LookupDelegate(LPCWSTR lpszDelegate) const { if (m_pDelegates == NULL) return NULL; CXTPMarkupDelegate* pDelegate = m_pDelegates->Lookup(lpszDelegate); if (pDelegate) return pDelegate; int nLen = (int)wcslen(lpszDelegate); LPWSTR lpMethodName = new WCHAR[XTPToUIntChecked(nLen + 1)]; memcpy(lpMethodName, lpszDelegate, (nLen + 1) * sizeof(WCHAR)); pDelegate = new CXTPMarkupOleAutoDelegate(lpMethodName, m_pDelegates); m_pDelegates->Add(lpMethodName, pDelegate); return pDelegate; } CRect CXTPMarkupContext::GetClientBoundingRect(CXTPMarkupInputElement* pInputElement) const { CRect rc(0, 0, 0, 0); if (!pInputElement) return rc; CXTPMarkupVisual* pVisual = NULL; if (pInputElement->IsKindOf(MARKUP_TYPE(CXTPMarkupVisual))) { pVisual = (CXTPMarkupVisual*)pInputElement; rc = pVisual->GetBoundRect(); } else if (pInputElement->IsKindOf(MARKUP_TYPE(CXTPMarkupFrameworkContentElement))) { pVisual = ((CXTPMarkupFrameworkContentElement*)pInputElement)->GetParent(); rc = ((CXTPMarkupFrameworkContentElement*)pInputElement)->GetBoundRect(); } if (!pVisual) return rc; while (pVisual != 0) { rc.OffsetRect(pVisual->GetVisualOffset()); pVisual = pVisual->GetVisualParent(); } return rc; } CRect CXTPMarkupContext::GetUpdateRect(CXTPMarkupInputElement* pInputElement) const { CRect rc(0, 0, 0, 0); if (!pInputElement) return rc; CXTPMarkupVisual* pVisual = NULL; if (pInputElement->IsKindOf(MARKUP_TYPE(CXTPMarkupVisual))) { pVisual = (CXTPMarkupVisual*)pInputElement; rc = pVisual->GetUpdateRect(); } else if (pInputElement->IsKindOf(MARKUP_TYPE(CXTPMarkupFrameworkContentElement))) { pVisual = ((CXTPMarkupFrameworkContentElement*)pInputElement)->GetParent(); rc = ((CXTPMarkupFrameworkContentElement*)pInputElement)->GetUpdateRect(); } if (!pVisual) return rc; while (pVisual != 0) { rc.OffsetRect(pVisual->GetVisualOffset()); pVisual = pVisual->GetVisualParent(); } return rc; } void CXTPMarkupContext::OnInvalidateVisual(CXTPMarkupUIElement* pUIElement) { if (0 < m_nFreezeUpdatesCounter) { m_bContainsPendingUpdates = TRUE; return; } if (NULL == m_hContextWnd || !::IsWindow(m_hContextWnd)) return; CRect rcUpdate = GetUpdateRect(pUIElement); Redraw(rcUpdate, TRUE); } void CXTPMarkupContext::OnInvalidateArrange(CXTPMarkupUIElement* /*pUIElement*/) { if (0 < m_nFreezeUpdatesCounter) { m_bContainsPendingUpdates = TRUE; return; } Redraw(NULL, TRUE); } ULONG CXTPMarkupContext::AddRef() { #ifdef _XTP_ACTIVEX return InternalAddRef(); #else return static_cast(InterlockedIncrement(&m_dwRef)); #endif } ULONG CXTPMarkupContext::Release() { #ifdef _XTP_ACTIVEX return InternalRelease(); #else _ASSERTE(0 < m_dwRef); LONG lResult = InterlockedDecrement(&m_dwRef); if (lResult == 0) { delete this; return 0; } return static_cast(lResult); #endif } void CXTPMarkupContext::SetImageManager(CXTPImageManager* pImageManager) { CMDTARGET_RELEASE(m_pImageManager); m_pImageManager = pImageManager; } CXTPImageManager* CXTPMarkupContext::GetImageManager() const { if (m_pImageManager) return m_pImageManager; return XTPImageManager(); } COLORREF CXTPMarkupContext::GetImageColorKey() const { COLORREF clr = m_clrImgColorKey; if (COLORREF_NULL == clr) { clr = GetImageManager()->GetMaskColor(); if (COLORREF_NULL == clr) { // Use a default one for backward compatibility. clr = RGB(0, 0xff, 0); } } return clr; } #ifdef _XTP_ACTIVEX IMPLEMENT_OLETYPELIB_EX(CXTPMarkupContext, XTPDIID_MarkupContext) BEGIN_INTERFACE_MAP(CXTPMarkupContext, CXTPCmdTarget) INTERFACE_PART(CXTPMarkupContext, IID_IActiveScriptSite, ActiveScriptSite) INTERFACE_PART(CXTPMarkupContext, XTPDIID_MarkupContext, Dispatch) END_INTERFACE_MAP() #endif #ifdef _XTP_ACTIVEX XTP_IMPLEMENT_IUNKNOWN(CXTPMarkupContext, ActiveScriptSite) #else /*!_XTP_ACTIVEX*/ STDMETHODIMP_(ULONG) CXTPMarkupContext::XActiveScriptSite::AddRef() { return pThis->AddRef(); } STDMETHODIMP_(ULONG) CXTPMarkupContext::XActiveScriptSite::Release() { return pThis->Release(); } STDMETHODIMP CXTPMarkupContext::XActiveScriptSite::QueryInterface(REFIID riid, void** ppvObj) { HRESULT hr = E_NOINTERFACE; if (NULL != ppvObj) { *ppvObj = NULL; if (IID_IActiveScriptSite == riid || IID_IUnknown == riid) { *ppvObj = pThis; AddRef(); hr = S_OK; } } else { hr = E_POINTER; } return hr; } #endif /*!_XTP_ACTIVEX*/ STDMETHODIMP CXTPMarkupContext::XActiveScriptSite::GetLCID(LCID* plcid) { UNREFERENCED_PARAMETER(plcid); return E_NOTIMPL; } STDMETHODIMP CXTPMarkupContext::XActiveScriptSite::GetItemInfo(LPCOLESTR pstrName, DWORD dwReturnMask, IUnknown** ppiunkItem, ITypeInfo** ppti) { #ifdef _XTP_ACTIVEX METHOD_PROLOGUE(CXTPMarkupContext, ActiveScriptSite); #endif HRESULT hr = TYPE_E_ELEMENTNOTFOUND; if (NULL != ppiunkItem) *ppiunkItem = NULL; if (NULL != ppti) *ppti = NULL; if (0 != (dwReturnMask & SCRIPTINFO_IUNKNOWN)) { if (NULL == ppiunkItem) return E_POINTER; // Check if standard runtime instance is requested. if (0 == wcscmp(pstrName, L"__XTPActiveScriptStdRuntime")) { if (NULL == pThis->m_pScriptEngineStdRuntime) pThis->m_pScriptEngineStdRuntime = new CXTPActiveScriptStdRuntime(this, FALSE); hr = pThis->m_pScriptEngineStdRuntime->GetControllingUnknown()->QueryInterface( ppiunkItem); } else { // If nothing found, try custom global objects. hr = pThis->GetScriptNamedItem(pstrName, ppiunkItem); } // If nothing found, forward to script engine. if (NULL == *ppiunkItem) { LPVOID lpItemData = pThis->m_pScriptEngine->GetNamedItemData(pstrName); if (NULL != lpItemData) { CXTPMarkupObject* pObject = reinterpret_cast(lpItemData); hr = pObject->GetControllingUnknown()->QueryInterface(ppiunkItem); } } } return hr; } STDMETHODIMP CXTPMarkupContext::XActiveScriptSite::GetDocVersionString(BSTR* pbstrVersion) { UNREFERENCED_PARAMETER(pbstrVersion); return E_NOTIMPL; } STDMETHODIMP CXTPMarkupContext::XActiveScriptSite::OnScriptTerminate(const VARIANT* pvarResult, const EXCEPINFO* pexcepinfo) { UNREFERENCED_PARAMETER(pvarResult); UNREFERENCED_PARAMETER(pexcepinfo); return S_OK; } STDMETHODIMP CXTPMarkupContext::XActiveScriptSite::OnStateChange(SCRIPTSTATE ssScriptState) { UNREFERENCED_PARAMETER(ssScriptState); return S_OK; } STDMETHODIMP CXTPMarkupContext::XActiveScriptSite::OnScriptError(IActiveScriptError* pScriptError) { UNREFERENCED_PARAMETER(pScriptError); return E_NOTIMPL; } STDMETHODIMP CXTPMarkupContext::XActiveScriptSite::OnEnterScript() { return S_OK; } STDMETHODIMP CXTPMarkupContext::XActiveScriptSite::OnLeaveScript() { return S_OK; } #ifdef _XTP_ACTIVEX BEGIN_DISPATCH_MAP(CXTPMarkupContext, CXTPCmdTarget) DISP_FUNCTION_ID(CXTPMarkupContext, "SetMethod", 1, OleSetMethod, VT_EMPTY, VTS_DISPATCH VTS_WBSTR) DISP_FUNCTION_ID(CXTPMarkupContext, "SetHandler", 6, OleSetHandler, VT_EMPTY, VTS_DISPATCH) DISP_FUNCTION_ID(CXTPMarkupContext, "CreateObject", 2, OleCreateObject, VT_DISPATCH, VTS_WBSTR) DISP_FUNCTION_ID(CXTPMarkupContext, "CreateSolidBrush", 3, OleCreateSolidBrush, VT_DISPATCH, VTS_VARIANT) DISP_FUNCTION_ID(CXTPMarkupContext, "CreateThickness", 4, OleCreateThickness, VT_DISPATCH, VTS_I4 VTS_I4 VTS_I4 VTS_I4) DISP_FUNCTION_ID(CXTPMarkupContext, "Parse", 5, OleParse, VT_DISPATCH, VTS_BSTR) DISP_PROPERTY_ID(CXTPMarkupContext, "EnableGdiPlus", 7, m_bEnableGdiPlus, VT_BOOL) DISP_PROPERTY_EX_ID(CXTPMarkupContext, "DpiAware", 43, OleIsDpiAware, OleSetDpiAware, VT_BOOL) DISP_PROPERTY_EX_ID(CXTPMarkupContext, "ToolTipContext", 39, OleGetToolTipContext, SetNotSupported, VT_DISPATCH) DISP_PROPERTY_EX_ID(CXTPMarkupContext, "Icons", 40, OleGetIcons, OleSetIcons, VT_DISPATCH) DISP_FUNCTION_ID(CXTPMarkupContext, "ValidateXML", 8, OleValidateXML, VT_BSTR, VTS_BSTR) DISP_FUNCTION_ID(CXTPMarkupContext, "FreezeUpdates", 41, OleFreezeUpdates, VT_EMPTY, VTS_NONE) DISP_FUNCTION_ID(CXTPMarkupContext, "UnfreezeUpdates", 42, OleUnfreezeUpdates, VT_EMPTY, VTS_NONE) DISP_PROPERTY_EX_ID(CXTPMarkupContext, "DefaultSmoothingMode", 44, OleGetDefaultSmoothingMode, OleSetDefaultSmoothingMode, VT_I4) DISP_PROPERTY_EX_ID(CXTPMarkupContext, "DefaultTextSmoothingEnabled", 45, OleGetDefaultTextSmoothing, OleSetDefaultTextSmoothing, VT_BOOL) END_DISPATCH_MAP() #endif /*!_XTP_ACTIVEX*/ class CXTPMarkupOleDelegate : public CXTPMarkupDelegate { public: CXTPMarkupOleDelegate(LPDISPATCH lpHandler, LPWSTR lpName) { m_lpName = lpName; m_lpHandler = lpHandler; } ~CXTPMarkupOleDelegate() { delete[] m_lpName; } virtual void Execute(CXTPMarkupObject* pSender, CXTPMarkupRoutedEventArgs* pArgs) { COleDispatchDriver dispDriverBinded(m_lpHandler, FALSE); OLECHAR* szMember = (OLECHAR*)m_lpName; DISPID dispidBinded = 0; if (FAILED(m_lpHandler->GetIDsOfNames(IID_NULL, &szMember, 1, LOCALE_SYSTEM_DEFAULT, &dispidBinded))) return; static BYTE parms[] = VTS_DISPATCH VTS_DISPATCH; dispDriverBinded.InvokeHelper(dispidBinded, DISPATCH_METHOD, VT_EMPTY, NULL, parms, XTPGetDispatch(pSender, FALSE), XTPGetDispatch(pArgs, FALSE)); } protected: LPDISPATCH m_lpHandler; LPWSTR m_lpName; }; void CXTPMarkupOleAutoDelegate::Execute(CXTPMarkupObject* pSender, CXTPMarkupRoutedEventArgs* pArgs) { if (!m_pMap->m_lpHandler) return; COleDispatchDriver dispDriverBinded(m_pMap->m_lpHandler, FALSE); OLECHAR* szMember = (OLECHAR*)m_lpName; DISPID dispidBinded = 0; if (FAILED(m_pMap->m_lpHandler->GetIDsOfNames(IID_NULL, &szMember, 1, LOCALE_SYSTEM_DEFAULT, &dispidBinded))) return; static BYTE parms[] = VTS_DISPATCH VTS_DISPATCH; dispDriverBinded.InvokeHelper(dispidBinded, DISPATCH_METHOD, VT_EMPTY, NULL, parms, XTPGetDispatch(pSender, FALSE), XTPGetDispatch(pArgs, FALSE)); } void CXTPMarkupInputElement::OleAddHandler(LPDISPATCH lpEventDisp, LPCOLESTR lpszDelegate) { CXTPMarkupRoutedEvent* pEvent = (CXTPMarkupRoutedEvent*)FromDispatch(lpEventDisp, FALSE); if (!pEvent) return; int nLen = (int)wcslen(lpszDelegate); LPWSTR lpMethodName = new WCHAR[XTPToUIntChecked(nLen + 1)]; memcpy(lpMethodName, lpszDelegate, (nLen + 1) * sizeof(WCHAR)); AddHandler(pEvent, new CXTPMarkupOleAutoDelegate(lpMethodName, GetMarkupContext()->m_pDelegates)); } #ifndef _XTP_ACTIVEX /////////////////////////////////////////////////////////////////////////////// // OLE methods implementation class CXTPMarkupContextInternalDispatch : public CXTPCmdTarget { DECLARE_DYNAMIC(CXTPMarkupContextInternalDispatch); public: explicit CXTPMarkupContextInternalDispatch(CXTPMarkupContext* pContext) : m_pContext(pContext) { _ASSERTE(NULL != m_pContext); EnableAutomation(); } private: DECLARE_DISPATCH_MAP(); void OleSetMethod(LPDISPATCH lpHandler, LPCOLESTR lpName) { m_pContext->OleSetMethod(lpHandler, lpName); } void OleSetHandler(LPDISPATCH lpHandler) { m_pContext->OleSetHandler(lpHandler); } LPDISPATCH OleCreateObject(LPCOLESTR lpName) { return m_pContext->OleCreateObject(lpName); } LPDISPATCH OleCreateSolidBrush(const VARIANT& clr) { return m_pContext->OleCreateSolidBrush(clr); } LPDISPATCH OleCreateThickness(long nLeft, long nTop, long nRight, long nBottom) { return m_pContext->OleCreateThickness(nLeft, nTop, nRight, nBottom); } LPDISPATCH OleParse(LPCTSTR lpText) { return m_pContext->OleParse(lpText); } LPDISPATCH OleGetToolTipContext() { return m_pContext->OleGetToolTipContext(); } void OleSetIcons(LPDISPATCH lpDisp) { m_pContext->OleSetIcons(lpDisp); } LPDISPATCH OleGetIcons() { return m_pContext->OleGetIcons(); } BSTR OleValidateXML(LPCTSTR lpText) { return m_pContext->OleValidateXML(lpText); } void OleSetEnableGdiPlus(BOOL bEnable) { m_pContext->m_bEnableGdiPlus = bEnable; } BOOL OleGetEnableGdiPlus() { return m_pContext->m_bEnableGdiPlus; } void OleFreezeUpdates() { m_pContext->OleFreezeUpdates(); } void OleUnfreezeUpdates() { m_pContext->OleUnfreezeUpdates(); } long OleGetDefaultSmoothingMode() { return m_pContext->OleGetDefaultSmoothingMode(); } void OleSetDefaultSmoothingMode(long lMode) { m_pContext->OleSetDefaultSmoothingMode(lMode); } BOOL OleGetDefaultTextSmoothing() { return m_pContext->OleGetDefaultTextSmoothing(); } void OleSetDefaultTextSmoothing(BOOL bEnableTextSmoothing) { m_pContext->OleSetDefaultTextSmoothing(bEnableTextSmoothing); } BOOL OleIsDpiAware() { return m_pContext->OleIsDpiAware(); } void OleSetDpiAware(BOOL bNewValue) { m_pContext->OleSetDpiAware(bNewValue); } private: CXTPMarkupContext* m_pContext; }; IMPLEMENT_DYNAMIC(CXTPMarkupContextInternalDispatch, CXTPCmdTarget); # include "Common/Base/Diagnostic/XTPBeginAfxMap.h" BEGIN_DISPATCH_MAP(CXTPMarkupContextInternalDispatch, CXTPCmdTarget) DISP_FUNCTION_ID(CXTPMarkupContextInternalDispatch, "SetMethod", 1, OleSetMethod, VT_EMPTY, VTS_DISPATCH VTS_WBSTR) DISP_FUNCTION_ID(CXTPMarkupContextInternalDispatch, "SetHandler", 6, OleSetHandler, VT_EMPTY, VTS_DISPATCH) DISP_FUNCTION_ID(CXTPMarkupContextInternalDispatch, "CreateObject", 2, OleCreateObject, VT_DISPATCH, VTS_WBSTR) DISP_FUNCTION_ID(CXTPMarkupContextInternalDispatch, "CreateSolidBrush", 3, OleCreateSolidBrush, VT_DISPATCH, VTS_VARIANT) DISP_FUNCTION_ID(CXTPMarkupContextInternalDispatch, "CreateThickness", 4, OleCreateThickness, VT_DISPATCH, VTS_I4 VTS_I4 VTS_I4 VTS_I4) DISP_FUNCTION_ID(CXTPMarkupContextInternalDispatch, "Parse", 5, OleParse, VT_DISPATCH, VTS_WBSTR) DISP_PROPERTY_EX_ID(CXTPMarkupContextInternalDispatch, "EnableGdiPlus", 7, OleGetEnableGdiPlus, OleSetEnableGdiPlus, VT_BOOL) DISP_PROPERTY_EX_ID(CXTPMarkupContextInternalDispatch, "DpiAware", 43, OleIsDpiAware, OleSetDpiAware, VT_BOOL) DISP_PROPERTY_EX_ID(CXTPMarkupContextInternalDispatch, "ToolTipContext", 39, OleGetToolTipContext, SetNotSupported, VT_DISPATCH) DISP_PROPERTY_EX_ID(CXTPMarkupContextInternalDispatch, "Icons", 40, OleGetIcons, OleSetIcons, VT_DISPATCH) DISP_FUNCTION_ID(CXTPMarkupContextInternalDispatch, "ValidateXML", 8, OleValidateXML, VT_BSTR, VTS_WBSTR) DISP_FUNCTION_ID(CXTPMarkupContextInternalDispatch, "FreezeUpdates", 41, OleFreezeUpdates, VT_EMPTY, VTS_NONE) DISP_FUNCTION_ID(CXTPMarkupContextInternalDispatch, "UnfreezeUpdates", 42, OleUnfreezeUpdates, VT_EMPTY, VTS_NONE) DISP_PROPERTY_EX_ID(CXTPMarkupContextInternalDispatch, "DefaultSmoothingMode", 44, OleGetDefaultSmoothingMode, OleSetDefaultSmoothingMode, VT_I4) DISP_PROPERTY_EX_ID(CXTPMarkupContextInternalDispatch, "DefaultTextSmoothingEnabled", 45, OleGetDefaultTextSmoothing, OleSetDefaultTextSmoothing, VT_BOOL) END_DISPATCH_MAP() # include "Common/Base/Diagnostic/XTPEndAfxMap.h" #endif // !_XTP_ACTIVEX CCmdTarget* CXTPMarkupContext::AccessInternalDispatch() { CCmdTarget* pDispatcher; #ifdef _XTP_ACTIVEX pDispatcher = this; #else if (NULL == m_pInternalDispatch) m_pInternalDispatch = new CXTPMarkupContextInternalDispatch(this); pDispatcher = m_pInternalDispatch; #endif return pDispatcher; } void CXTPMarkupContext::OleSetMethod(LPDISPATCH lpHandler, LPCOLESTR lpName) { if (!lpName || !lpHandler) return; int nLen = (int)wcslen(lpName); LPWSTR lpMethodName = new WCHAR[XTPToUIntChecked(nLen + 1)]; memcpy(lpMethodName, lpName, (nLen + 1) * sizeof(WCHAR)); SetDelegate(lpMethodName, new CXTPMarkupOleDelegate(lpHandler, lpMethodName)); } void CXTPMarkupContext::OleSetHandler(LPDISPATCH lpHandler) { if (m_pDelegates == NULL) m_pDelegates = new CXTPMarkupDelegateMap(); if (m_pDelegates->m_lpHandler != NULL) m_pDelegates->m_lpHandler = NULL; if (lpHandler) m_pDelegates->m_lpHandler = lpHandler; } LPDISPATCH CXTPMarkupContext::OleCreateObject(LPCOLESTR lpName) { CXTPMarkupType* pType = CXTPMarkupType::LookupTag(lpName); if (NULL == pType) return NULL; return XTPGetDispatch(CreateMarkupObject(pType), FALSE); } LPDISPATCH CXTPMarkupContext::OleCreateSolidBrush(const VARIANT& clr) { BOOL bValid = FALSE; COLORREF cr = COLORREF_NULL; switch (clr.vt) { case VT_I4: case VT_UI4: case VT_INT: case VT_UINT: cr = clr.ulVal; bValid = TRUE; break; case VT_I2: case VT_UI2: cr = clr.uiVal; bValid = TRUE; break; case VT_I1: case VT_UI1: cr = clr.bVal; bValid = TRUE; break; case VT_BSTR: case VT_LPWSTR: bValid = (NULL != clr.bstrVal && CXTPMarkupColor::ConvertFromString(clr.bstrVal, cr)); break; case VT_LPSTR: bValid = (NULL != clr.pcVal && CXTPMarkupColor::ConvertFromString(XTP_CA2CW(clr.pcVal), cr)); break; } if (!bValid) AfxThrowOleDispatchException(static_cast(GetScode(E_FAIL) & 0xffff), _T("Invalid color value specified")); BYTE nAlpha = static_cast(cr >> 24); if (nAlpha == 0) nAlpha = 0xFF; return XTPGetDispatch(new CXTPMarkupSolidColorBrush(nAlpha, cr), FALSE); } LPDISPATCH CXTPMarkupContext::OleCreateThickness(long nLeft, long nTop, long nRight, long nBottom) { return XTPGetDispatch(new CXTPMarkupThickness(nLeft, nTop, nRight, nBottom), FALSE); } LPDISPATCH CXTPMarkupContext::OleParse(LPCTSTR lpText) { return XTPGetDispatch(Parse(lpText), FALSE); } BSTR CXTPMarkupContext::OleValidateXML(LPCTSTR lpText) { return ValidateXML(lpText).AllocSysString(); } BOOL CXTPMarkupContext::OleIsDpiAware() { return IsDpiAware(); } void CXTPMarkupContext::OleSetDpiAware(BOOL bNewValue) { SetDpiAware(bNewValue); } LPDISPATCH CXTPMarkupContext::OleGetToolTipContext() { return GetToolTipContext()->GetIDispatch(TRUE); } LPDISPATCH CXTPMarkupContext::OleGetIcons() { return XTPGetDispatch(GetImageManager()); } void CXTPMarkupContext::OleSetIcons(LPDISPATCH lpDispatch) { CMDTARGET_RELEASE(m_pImageManager); if (lpDispatch) { m_pImageManager = CXTPImageManager::FromDispatch(lpDispatch); lpDispatch->AddRef(); } } void CXTPMarkupContext::OleFreezeUpdates() { ++m_nFreezeUpdatesCounter; } void CXTPMarkupContext::OleUnfreezeUpdates() { if (m_nFreezeUpdatesCounter <= 0) return; m_bContainsPendingUpdates = FALSE; if (0 == --m_nFreezeUpdatesCounter) Redraw(); } long CXTPMarkupContext::OleGetDefaultSmoothingMode() { return static_cast(GetDefaultSmoothingMode()); } void CXTPMarkupContext::OleSetDefaultSmoothingMode(long lMode) { SetDefaultSmoothingMode(static_cast(lMode)); } BOOL CXTPMarkupContext::OleGetDefaultTextSmoothing() { return GetDefaultTextSmoothing(); } void CXTPMarkupContext::OleSetDefaultTextSmoothing(BOOL bEnableTextSmoothing) { SetDefaultTextSmoothing(bEnableTextSmoothing); } void CXTPMarkupContext::SetDpiAware(BOOL bSet, HWND hWnd) { if (NULL != m_pDpi) { delete m_pDpi; m_pDpi = NULL; } if (bSet) { m_pDpi = new CXTPDpi(hWnd); } } void CXTPMarkupContext::SetDpiAware(BOOL bSet, HDC hDC) { if (NULL != m_pDpi) { delete m_pDpi; m_pDpi = NULL; } if (bSet) { m_pDpi = new CXTPDpi(hDC); } } CXTPMarkupDeviceDependentImage* CXTPMarkupContext::LoadImage(const CString& strSource, CSize size, CXTPMarkupDeviceContext* pDC, IXTPMarkupDeviceDependentImageSite* pSite) { ASSERT_VALID(pDC); _ASSERTE(NULL != pSite); CList* pImageDataList = NULL; if (m_CachedImages.Lookup(strSource, pImageDataList)) { POSITION pos = pImageDataList->GetHeadPosition(); while (NULL != pos) { CachedImageData* pImageData = pImageDataList->GetNext(pos); _ASSERTE(NULL != pImageData); if (pDC->GetRuntimeClass() == pImageData->pDCClass && size == pImageData->size && pSite == pImageData->pSite) { pImageData->pImage->AddRef(); return pImageData->pImage; } } } CXTPMarkupDeviceDependentImage* pImage = pDC->CreateDeviceDependentImage(pSite); if (NULL == pImage) return NULL; if (!pImage->Load(XTP_CT2CW(strSource), size.cx, size.cy)) { pImage->Release(); return 0; } CachedImageData* pImageData = new CachedImageData(); pImageData->pImage = pImage; pImageData->size = size; pImageData->pDCClass = pDC->GetRuntimeClass(); pImageData->pSite = pSite; if (NULL == pImageDataList) pImageDataList = new CList(); pImageDataList->AddTail(pImageData); if (1 == pImageDataList->GetCount()) m_CachedImages[strSource] = pImageDataList; pImage->AddRef(); return pImage; } void CXTPMarkupContext::FreeCachedImages() { POSITION mapPos = m_CachedImages.GetStartPosition(); while (NULL != mapPos) { CString strSource; CList* pImageDataList = NULL; m_CachedImages.GetNextAssoc(mapPos, strSource, pImageDataList); _ASSERTE(NULL != pImageDataList); POSITION pos = pImageDataList->GetHeadPosition(); while (NULL != pos) { CachedImageData* pImageData = pImageDataList->GetNext(pos); _ASSERTE(NULL != pImageData); pImageData->pImage->Release(); delete pImageData; } delete pImageDataList; } m_CachedImages.RemoveAll(); } /////////////////////////////////////////////////////////////////////////////// // CXTPMarkupContext::CCodeChunk CXTPMarkupContext::CCodeChunk::CCodeChunk(LPCWSTR pCode, LPCWSTR pRequirements /*= NULL*/) : m_code(pCode) { _ASSERTE(NULL != pCode); if (NULL != pRequirements) { LPCWSTR p = pRequirements; while (true) { while (isspace(*p)) ++p; LPCWSTR e = wcschr(p, L','); if (NULL != e) { SIZE_T len = static_cast(e - p); LPWSTR r = reinterpret_cast(malloc((len + 1) * sizeof(WCHAR))); WCSNCPY_S(r, len + 1, p, len); r[len] = L'\0'; m_req.AddTail(r); p = e + 1; } else { m_req.AddTail(_wcsdup(p)); break; } } } } CXTPMarkupContext::CCodeChunk::~CCodeChunk() { POSITION pos = m_req.GetHeadPosition(); while (NULL != pos) free(const_cast(m_req.GetNext(pos))); } LPCWSTR CXTPMarkupContext::CCodeChunk::GetCode() const { return m_code; } const CList& CXTPMarkupContext::CCodeChunk::GetRequirements() const { return m_req; } /////////////////////////////////////////////////////////////////////////////// // CXTPMarkupContext::CCustomScriptItem CXTPMarkupContext::CCustomScriptItem::CCustomScriptItem(LPCWSTR pName, LPDISPATCH pDisp) : m_name(NULL) , m_pDisp(NULL) { _ASSERTE(NULL != pName); _ASSERTE(NULL != pDisp); m_name = pName; m_pDisp = pDisp; m_pDisp->AddRef(); } CXTPMarkupContext::CCustomScriptItem::~CCustomScriptItem() { m_pDisp->Release(); } LPCWSTR CXTPMarkupContext::CCustomScriptItem::GetName() const { return m_name; } LPDISPATCH CXTPMarkupContext::CCustomScriptItem::GetDispatch() const { return m_pDisp; }