You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

963 lines
23 KiB
C++

2 years ago
// XTPMarkupContext.cpp: implementation of the CXTPMarkupContext class.
//
// This file is a part of the XTREME TOOLKIT PRO 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/XTPToolTipContext.h"
#include "Common/XTPResourceManager.h"
#include "Common/XTPMarkupRender.h"
#include "Common/XTPImageManager.h"
#include "XTPMarkupObject.h"
#include "XTPMarkupContext.h"
#include "XTPMarkupInputElement.h"
#include "XTPMarkupUIElement.h"
#include "XTPMarkupFrameworkElement.h"
#include "XTPMarkupDecorator.h"
#include "XTPMarkupControl.h"
#include "XTPMarkupPanel.h"
#include "Text/XTPMarkupInline.h"
#include "Text/XTPMarkupSpan.h"
#include "Text/XTPMarkupRun.h"
#include "XTPMarkupBorder.h"
#include "XTPMarkupStackPanel.h"
#include "XTPMarkupGrid.h"
#include "XTPMarkupCanvas.h"
#include "XTPMarkupPage.h"
#include "XTPMarkupShape.h"
#include "XTPMarkupImage.h"
#include "XTPMarkupTextBlock.h"
#include "XTPMarkupButton.h"
#include "XTPMarkupScrollViewer.h"
#include "XTPMarkupResourceDictionary.h"
#include "XTPMarkupThickness.h"
#include "Path/XTPMarkupPath.h"
#include "Path/XTPMarkupPathData.h"
#include "XTPMarkupBuilder.h"
#include "XTPMarkupParser.h"
#include "XTPMarkupDrawingContext.h"
#include "XTPMarkupKeyboardNavigation.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
class CXTPMarkupContext::CXTPMarkupFontArray : public CXTPMarkupTypedSimpleStack<CXTPMarkupFont>
{
};
CXTPMarkupFont::CXTPMarkupFont()
{
m_pMarkupContext = NULL;
m_hFont = NULL;
m_pNextChain = NULL;
}
CXTPMarkupFont::~CXTPMarkupFont()
{
if (m_pMarkupContext)
{
VERIFY(m_pMarkupContext->m_pFonts->Remove(this));
}
DeleteObject(m_hFont);
}
//////////////////////////////////////////////////////////////////////////
// CXTPMarkupDelegateMap
class CXTPMarkupDelegateMap
{
public:
CXTPMarkupDelegateMap();
~CXTPMarkupDelegateMap();
public:
void RemoveAll();
void Add(LPCWSTR lpszDelegate, CXTPMarkupDelegate* pDelegate);
CXTPMarkupDelegate* Lookup(LPCWSTR lpszDelegate) const;
protected:
CMap<LPCWSTR, LPCWSTR, CXTPMarkupDelegate*, CXTPMarkupDelegate*> m_mapDelegates;
public:
LPDISPATCH m_lpHandler;
};
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;
}
template<> inline BOOL AFXAPI CompareElements(const LPCWSTR* pElement1, const LPCWSTR* pElement2)
{
return wcscmp(*pElement1, *pElement2) == 0;
}
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()
{
NONCLIENTMETRICS ncm = { sizeof(NONCLIENTMETRICS) };
VERIFY(::SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICS), &ncm, 0));
ncm.lfMessageFont.lfCharSet = XTPResourceManager()->GetFontCharset();
m_dwRef = 1;
m_logFont = ncm.lfMessageFont;
m_clrForeground = 0;
m_pImageManager = NULL;
m_pMouseOver = NULL;
m_pMouseCapture = NULL;
m_pActiveElement = NULL;
m_hContextWnd = NULL;
m_pHandlers = NULL;
m_pDelegates = NULL;
m_pFonts = NULL;
m_pKeyboardNavigation = new CXTPMarkupKeyboardNavigation(this);
m_pToolTipContext = new CTooltipContext(this);
m_pToolTipContext->SetStyle(xtpToolTipMarkup);
m_bEnableGdiPlus = TRUE;
RegisterClasses();
CXTPMarkupDrawingContext::Register(TRUE);
}
void CXTPMarkupContext::RegisterClasses()
{
static BOOL bRegistered = FALSE;
if (bRegistered)
return;
bRegistered = TRUE;
CXTPMarkupType::RegisterAll();
CXTPMarkupSetter::RegisterType();
CXTPMarkupFrameworkElement::RegisterType();
CXTPMarkupUIElement::RegisterType();
CXTPMarkupTextElement::RegisterType();
CXTPMarkupBorder::RegisterType();
CXTPMarkupCanvas::RegisterType();
CXTPMarkupSolidColorBrush::RegisterType();
CXTPMarkupGradientStop::RegisterType();
CXTPMarkupLinearGradientBrush::RegisterType();
CXTPMarkupColumnDefinition::RegisterType();
CXTPMarkupRowDefinition::RegisterType();
CXTPMarkupGrid::RegisterType();
CXTPMarkupImage::RegisterType();
CXTPMarkupPanel::RegisterType();
CXTPMarkupControl::RegisterType();
CXTPMarkupContentControl::RegisterType();
CXTPMarkupButtonBase::RegisterType();
CXTPMarkupToggleButton::RegisterType();
CXTPMarkupButton::RegisterType();
CXTPMarkupFrameworkContentElement::RegisterType();
CXTPMarkupInline::RegisterType();
CXTPMarkupRun::RegisterType();
CXTPMarkupHyperlink::RegisterType();
CXTPMarkupInputElement::RegisterType();
CXTPMarkupPage::RegisterType();
CXTPMarkupShape::RegisterType();
CXTPMarkupPolygon::RegisterType();
CXTPMarkupPolyline::RegisterType();
CXTPMarkupLine::RegisterType();
CXTPMarkupEllipse::RegisterType();
CXTPMarkupRectangle::RegisterType();
CXTPMarkupStackPanel::RegisterType();
CXTPMarkupWrapPanel::RegisterType();
CXTPMarkupTextBlock::RegisterType();
CXTPMarkupScrollViewer::RegisterType();
CXTPMarkupStyle::RegisterType();
CXTPMarkupDockPanel::RegisterType();
CXTPMarkupUniformGrid::RegisterType();
CXTPMarkupPath::RegisterType();
CXTPMarkupPathData::RegisterType();
}
CXTPMarkupContext::~CXTPMarkupContext()
{
CMDTARGET_RELEASE(m_pImageManager);
m_pMouseOver = NULL;
MARKUP_RELEASE(m_pKeyboardNavigation);
ASSERT(m_pFonts == NULL || m_pFonts->IsEmpty());
SAFE_DELETE(m_pHandlers);
SAFE_DELETE(m_pDelegates);
SAFE_DELETE(m_pFonts);
CMDTARGET_RELEASE(m_pToolTipContext);
ASSERT(m_dwRef <= 1);
CXTPMarkupDrawingContext::Register(FALSE);
}
CXTPMarkupObject* CXTPMarkupContext::CreateMarkupObject(CXTPMarkupType* pType)
{
CXTPMarkupObject* pObject = pType->CreateObject();
if (!pObject)
return NULL;
if (pObject->IsKindOf(MARKUP_TYPE(CXTPMarkupInputElement)))
{
((CXTPMarkupInputElement*)pObject)->m_pMarkupContext = this;
AddRef();
}
return (CXTPMarkupObject*)pObject;
}
void CXTPMarkupContext::Cleanup()
{
m_pMouseOver = NULL;
m_pActiveElement = NULL;
if (m_pMouseCapture)
{
m_pMouseCapture = NULL;
ReleaseCapture();
}
}
void CXTPMarkupContext::FinalizeMarkupObject(CXTPMarkupInputElement* pInputElement)
{
if (pInputElement == m_pMouseOver)
m_pMouseOver = NULL;
if (pInputElement == m_pActiveElement)
m_pActiveElement = NULL;
if (pInputElement == m_pMouseCapture)
{
m_pMouseCapture = NULL;
ReleaseCapture();
}
pInputElement->m_pMarkupContext = NULL;
Release();
}
CXTPMarkupUIElement* CXTPMarkupContext::Parse(LPCSTR lpszBuffer)
{
Cleanup();
if (!lpszBuffer)
return NULL;
CXTPMarkupParser sc;
sc.SetBuffer(lpszBuffer, lpszBuffer + strlen(lpszBuffer));
CXTPMarkupBuilder builder(this);
return builder.Parse(&sc);
}
CXTPMarkupUIElement* CXTPMarkupContext::Parse(LPCWSTR lpszBuffer)
{
Cleanup();
if (!lpszBuffer)
return NULL;
CXTPMarkupParser sc;
sc.SetBuffer(lpszBuffer, lpszBuffer + wcslen(lpszBuffer));
CXTPMarkupBuilder builder(this);
return builder.Parse(&sc);
}
CString CXTPMarkupContext::ValidateXML(LPCWSTR lpszBuffer)
{
Cleanup();
if (!lpszBuffer)
return _T("No Text To Parse.");
CXTPMarkupParser sc;
sc.SetBuffer(lpszBuffer, lpszBuffer + wcslen(lpszBuffer));
CXTPMarkupBuilder builder(this);
CXTPMarkupUIElement* pUIElement = builder.Parse(&sc);
BOOL bError = TRUE;
if (pUIElement)
bError = FALSE;
MARKUP_RELEASE(pUIElement);
if (bError)
{
LPCTSTR lpszLastError = builder.GetLastError();
LPCTSTR lpszIndex = _tcsstr(lpszLastError, _T(". Line "));
if (lpszIndex == NULL)
return lpszLastError;
((LPTSTR)lpszIndex)[1] = 0;
CString str;
str.Format(_T("<TextBlock VerticalAlignment='Center'>%s <Hyperlink>%s</Hyperlink></TextBlock>"), lpszLastError, lpszIndex + 2);
((LPTSTR)lpszIndex)[1] = ' ';
return str;
}
else
{
return _T("Done.");
}
}
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;
}
CXTPMarkupFont* CXTPMarkupContext::GetFont(LOGFONT* pLogFont)
{
if (m_pFonts == NULL)
m_pFonts = new CXTPMarkupFontArray();
CXTPMarkupFont* pFont;
for (pFont = m_pFonts->GetHead(); pFont != NULL; pFont = pFont->m_pNextChain)
{
if (CompareFont(&pFont->m_lf, pLogFont))
{
pFont->AddRef();
return pFont;
}
}
pFont = new CXTPMarkupFont();
m_pFonts->AddTail(pFont);
pFont->m_lf = *pLogFont;
pFont->m_hFont = ::CreateFontIndirect(pLogFont);
pFont->m_pMarkupContext = this;
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));
return 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(LPWSTR 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);
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;
}
void CXTPMarkupContext::OnInvalidateVisual(CXTPMarkupUIElement* pUIElement)
{
if (m_hContextWnd)
{
InvalidateRect(m_hContextWnd, GetClientBoundingRect(pUIElement), FALSE);
::SendMessage(m_hContextWnd, XTP_WM_MARKUPREDRAW, 0, 0);
}
}
void CXTPMarkupContext::OnInvalidateArrange(CXTPMarkupUIElement* /*pUIElement*/)
{
if (m_hContextWnd)
{
InvalidateRect(m_hContextWnd, NULL, FALSE);
::SendMessage(m_hContextWnd, XTP_WM_MARKUPREDRAW, 0, 0);
}
}
void CXTPMarkupContext::AddRef()
{
InterlockedIncrement(&m_dwRef);
}
void CXTPMarkupContext::Release()
{
if (m_dwRef == 0)
return;
LONG lResult = InterlockedDecrement(&m_dwRef);
if (lResult == 0)
{
delete this;
}
}
void CXTPMarkupContext::SetImageManager(CXTPImageManager* pImageManager)
{
CMDTARGET_RELEASE(m_pImageManager);
m_pImageManager = pImageManager;
}
CXTPImageManager* CXTPMarkupContext::GetImageManager() const
{
if (m_pImageManager)
return m_pImageManager;
return XTPImageManager();
}