XTPMarkupShape.cpp
上传用户:szled88
上传日期:2015-04-09
资源大小:43957k
文件大小:17k
源码类别:

对话框与窗口

开发平台:

Visual C++

  1. // XTPMarkupShape.cpp: implementation of the CXTPMarkupShape class.
  2. //
  3. // This file is a part of the XTREME TOOLKIT PRO MFC class library.
  4. // (c)1998-2008 Codejock Software, All Rights Reserved.
  5. //
  6. // THIS SOURCE FILE IS THE PROPERTY OF CODEJOCK SOFTWARE AND IS NOT TO BE
  7. // RE-DISTRIBUTED BY ANY MEANS WHATSOEVER WITHOUT THE EXPRESSED WRITTEN
  8. // CONSENT OF CODEJOCK SOFTWARE.
  9. //
  10. // THIS SOURCE CODE CAN ONLY BE USED UNDER THE TERMS AND CONDITIONS OUTLINED
  11. // IN THE XTREME TOOLKIT PRO LICENSE AGREEMENT. CODEJOCK SOFTWARE GRANTS TO
  12. // YOU (ONE SOFTWARE DEVELOPER) THE LIMITED RIGHT TO USE THIS SOFTWARE ON A
  13. // SINGLE COMPUTER.
  14. //
  15. // CONTACT INFORMATION:
  16. // support@codejock.com
  17. // http://www.codejock.com
  18. //
  19. /////////////////////////////////////////////////////////////////////////////
  20. #include "stdafx.h"
  21. #include <math.h>
  22. #include "XTPMarkupShape.h"
  23. #include "XTPMarkupDrawingContext.h"
  24. #include "XTPMarkupBuilder.h"
  25. #ifdef _DEBUG
  26. #undef THIS_FILE
  27. static char THIS_FILE[]=__FILE__;
  28. #define new DEBUG_NEW
  29. #endif
  30. //////////////////////////////////////////////////////////////////////////
  31. // CXTPMarkupShape
  32. CXTPMarkupDependencyProperty* CXTPMarkupShape::m_pFillProperty = NULL;
  33. CXTPMarkupDependencyProperty* CXTPMarkupShape::m_pStrokeProperty = NULL;
  34. CXTPMarkupDependencyProperty* CXTPMarkupShape::m_pStrokeThicknessProperty = NULL;
  35. CXTPMarkupDependencyProperty* CXTPMarkupShape::m_pStretchProperty = NULL;
  36. IMPLEMENT_MARKUPCLASS(NULL, CXTPMarkupShape, CXTPMarkupFrameworkElement)
  37. void CXTPMarkupShape::RegisterMarkupClass()
  38. {
  39. m_pFillProperty = CXTPMarkupDependencyProperty::Register(L"Fill", MARKUP_TYPE(CXTPMarkupBrush), MARKUP_TYPE(CXTPMarkupShape),
  40. new CXTPMarkupPropertyMetadata(NULL, CXTPMarkupPropertyMetadata::flagAffectsRender));
  41. m_pStrokeProperty = CXTPMarkupDependencyProperty::Register(L"Stroke", MARKUP_TYPE(CXTPMarkupBrush), MARKUP_TYPE(CXTPMarkupShape),
  42. new CXTPMarkupPropertyMetadata(NULL, CXTPMarkupPropertyMetadata::flagAffectsRender));
  43. m_pStrokeThicknessProperty = CXTPMarkupDependencyProperty::Register(L"StrokeThickness", MARKUP_TYPE(CXTPMarkupInt), MARKUP_TYPE(CXTPMarkupShape),
  44. new CXTPMarkupPropertyMetadata(NULL, CXTPMarkupPropertyMetadata::flagAffectsRender));
  45. m_pStretchProperty = CXTPMarkupDependencyProperty::Register(L"Stretch", MARKUP_TYPE(CXTPMarkupEnum), MARKUP_TYPE(CXTPMarkupShape),
  46. new CXTPMarkupPropertyMetadata(CXTPMarkupEnum::CreateValue(xtpMarkupStretchNone), &CXTPMarkupBuilder::ConvertStretch, CXTPMarkupPropertyMetadata::flagAffectsRender));
  47. }
  48. CXTPMarkupShape::CXTPMarkupShape()
  49. {
  50. }
  51. CXTPMarkupShape::~CXTPMarkupShape()
  52. {
  53. }
  54. CXTPMarkupBrush* CXTPMarkupShape::GetFill() const
  55. {
  56. return MARKUP_STATICCAST(CXTPMarkupBrush, GetValue(m_pFillProperty));
  57. }
  58. void CXTPMarkupShape::SetFill(CXTPMarkupBrush* brush)
  59. {
  60. SetValue(m_pFillProperty, brush);
  61. }
  62. CXTPMarkupBrush* CXTPMarkupShape::GetStroke() const
  63. {
  64. return MARKUP_STATICCAST(CXTPMarkupBrush, GetValue(m_pStrokeProperty));
  65. }
  66. void CXTPMarkupShape::SetStroke(CXTPMarkupBrush* brush)
  67. {
  68. SetValue(m_pStrokeProperty, brush);
  69. }
  70. //////////////////////////////////////////////////////////////////////////
  71. // CXTPMarkupPointCollection
  72. IMPLEMENT_MARKUPCLASS(NULL, CXTPMarkupPointCollection, CXTPMarkupObject)
  73. void CXTPMarkupPointCollection::RegisterMarkupClass()
  74. {
  75. }
  76. CXTPMarkupPointCollection::CXTPMarkupPointCollection()
  77. {
  78. m_rcBounds.SetRectEmpty();
  79. }
  80. CXTPMarkupPointCollection::CXTPMarkupPointCollection(CPointArray& arr)
  81. {
  82. m_arrPoints.Copy(arr);
  83. m_rcBounds.SetRectEmpty();
  84. for (int i = 0; i < (int)m_arrPoints.GetSize(); i++)
  85. {
  86. POINT& pt = m_arrPoints[i];
  87. if (pt.x > m_rcBounds.right) m_rcBounds.right = pt.x;
  88. if (pt.y > m_rcBounds.bottom) m_rcBounds.bottom = pt.y;
  89. }
  90. }
  91. BOOL CXTPMarkupPointCollection::GetNextValue(LPCWSTR& lpszValue, int& nValue)
  92. {
  93. while (*lpszValue == ' ') lpszValue++;
  94. LPCWSTR lpszNext = lpszValue;
  95. nValue = 0;
  96. int nSign = 1;
  97. if (*lpszNext == '-')
  98. {
  99. nSign = -1;
  100. lpszNext++;
  101. }
  102. if (*lpszNext == 0)
  103. return FALSE;
  104. while (*lpszNext != 0)
  105. {
  106. WCHAR c = *lpszNext;
  107. if (c == ' ' || c == ',')
  108. {
  109. if (lpszNext == lpszValue)
  110. return FALSE;
  111. lpszNext++;
  112. break;
  113. }
  114. if (c <'0' || c > '9')
  115. return FALSE;
  116. nValue = 10 * nValue + (c - '0');
  117. lpszNext++;
  118. }
  119. lpszValue = lpszNext;
  120. nValue *= nSign;
  121. return TRUE;
  122. }
  123. BOOL CXTPMarkupPointCollection::ConvertFromString(LPCWSTR lpszValue, CXTPMarkupPointCollection::CPointArray& arr)
  124. {
  125. if (!lpszValue)
  126. return FALSE;
  127. while (*lpszValue != 0)
  128. {
  129. int x, y;
  130. if (!GetNextValue(lpszValue, x))
  131. return FALSE;
  132. if (!GetNextValue(lpszValue, y))
  133. return FALSE;
  134. while (*lpszValue == ' ') lpszValue++;
  135. POINT pt = {x, y};
  136. arr.Add(pt);
  137. }
  138. return TRUE;
  139. }
  140. CXTPMarkupObject* CXTPMarkupPointCollection::ConvertFrom(CXTPMarkupObject* pObject) const
  141. {
  142. if (IsStringObject(pObject))
  143. {
  144. CPointArray arr;
  145. if (ConvertFromString(*((CXTPMarkupString*)pObject), arr))
  146. {
  147. return new CXTPMarkupPointCollection(arr);
  148. }
  149. }
  150. return NULL;
  151. }
  152. //////////////////////////////////////////////////////////////////////////
  153. // CXTPMarkupPolygon
  154. CXTPMarkupDependencyProperty* CXTPMarkupPolygon::m_pPointsProperty = NULL;
  155. IMPLEMENT_MARKUPCLASS(L"Polygon", CXTPMarkupPolygon, CXTPMarkupShape)
  156. void CXTPMarkupPolygon::RegisterMarkupClass()
  157. {
  158. m_pPointsProperty = CXTPMarkupDependencyProperty::Register(L"Points", MARKUP_TYPE(CXTPMarkupPointCollection), MARKUP_TYPE(CXTPMarkupPolygon),
  159. new CXTPMarkupPropertyMetadata(NULL, CXTPMarkupPropertyMetadata::flagAffectsMeasure));
  160. }
  161. CXTPMarkupPolygon::CXTPMarkupPolygon()
  162. {
  163. }
  164. CXTPMarkupPolygon::~CXTPMarkupPolygon()
  165. {
  166. }
  167. void CXTPMarkupPolygon::SetPoints(CXTPMarkupPointCollection* pPoints)
  168. {
  169. SetValue(m_pPointsProperty, pPoints);
  170. }
  171. CXTPMarkupPointCollection* CXTPMarkupPolygon::GetPoints() const
  172. {
  173. return MARKUP_STATICCAST(CXTPMarkupPointCollection, GetValue(m_pPointsProperty));
  174. }
  175. CSize CXTPMarkupPolygon::MeasureOverride(CXTPMarkupDrawingContext* /*pDC*/, CSize /*szAvailableSize*/)
  176. {
  177. CXTPMarkupPointCollection* pPoints = GetPoints();
  178. if (!pPoints)
  179. return CSize(0, 0);
  180. return pPoints->GetBounds().Size();
  181. }
  182. void CXTPMarkupPolygon::OnRender(CXTPMarkupDrawingContext* pDC)
  183. {
  184. CXTPMarkupBrush* pStrokeBrush = GetStroke();
  185. CXTPMarkupBrush* pFillBrush = GetFill();
  186. if (!pStrokeBrush && !pFillBrush)
  187. return;
  188. CXTPMarkupPointCollection* pPoints = GetPoints();
  189. if (!pPoints)
  190. return;
  191. const CXTPMarkupPointCollection::CPointArray& arr = pPoints->GetPoints();
  192. int nStroke = pStrokeBrush ? GetStrokeThickness() : 0;
  193. CPen penStroke;
  194. if (nStroke > 0) penStroke.CreatePen(PS_SOLID, nStroke, pStrokeBrush->GetHintColor());
  195. CBrush brushFill;
  196. if (pFillBrush) brushFill.CreateSolidBrush(pFillBrush->GetHintColor());
  197. HGDIOBJ hOldPen = penStroke.GetSafeHandle() ? ::SelectObject(pDC->GetSafeHdc(), penStroke) : ::SelectObject(pDC->GetSafeHdc(), ::GetStockObject(NULL_PEN));
  198. HGDIOBJ hOldBrush = brushFill.GetSafeHandle() ? ::SelectObject(pDC->GetSafeHdc(), brushFill) : ::SelectObject(pDC->GetSafeHdc(), ::GetStockObject(NULL_BRUSH));
  199. ::Polygon(pDC->GetSafeHdc(), arr.GetData(), (int)arr.GetSize());
  200. if (hOldPen) ::SelectObject(pDC->GetSafeHdc(), hOldPen);
  201. if (hOldBrush) ::SelectObject(pDC->GetSafeHdc(), hOldBrush);
  202. }
  203. //////////////////////////////////////////////////////////////////////////
  204. // CXTPMarkupPolyline
  205. CXTPMarkupDependencyProperty* CXTPMarkupPolyline::m_pPointsProperty = NULL;
  206. IMPLEMENT_MARKUPCLASS(L"Polyline", CXTPMarkupPolyline, CXTPMarkupShape)
  207. void CXTPMarkupPolyline::RegisterMarkupClass()
  208. {
  209. m_pPointsProperty = CXTPMarkupDependencyProperty::Register(L"Points", MARKUP_TYPE(CXTPMarkupPointCollection), MARKUP_TYPE(CXTPMarkupPolyline),
  210. new CXTPMarkupPropertyMetadata(NULL, CXTPMarkupPropertyMetadata::flagAffectsMeasure));
  211. }
  212. CXTPMarkupPolyline::CXTPMarkupPolyline()
  213. {
  214. }
  215. CXTPMarkupPolyline::~CXTPMarkupPolyline()
  216. {
  217. }
  218. void CXTPMarkupPolyline::SetPoints(CXTPMarkupPointCollection* pPoints)
  219. {
  220. SetValue(m_pPointsProperty, pPoints);
  221. }
  222. CXTPMarkupPointCollection* CXTPMarkupPolyline::GetPoints() const
  223. {
  224. return MARKUP_STATICCAST(CXTPMarkupPointCollection, GetValue(m_pPointsProperty));
  225. }
  226. CSize CXTPMarkupPolyline::MeasureOverride(CXTPMarkupDrawingContext* /*pDC*/, CSize /*szAvailableSize*/)
  227. {
  228. CXTPMarkupPointCollection* pPoints = GetPoints();
  229. if (!pPoints)
  230. return CSize(0, 0);
  231. CSize sz = pPoints->GetBounds().Size();
  232. CXTPMarkupBrush* pStrokeBrush = GetStroke();
  233. int nStroke = pStrokeBrush ? GetStrokeThickness() : 0;
  234. sz.cx += nStroke;
  235. sz.cy += nStroke;
  236. return sz;
  237. }
  238. void CXTPMarkupPolyline::OnRender(CXTPMarkupDrawingContext* pDC)
  239. {
  240. CXTPMarkupBrush* pStrokeBrush = GetStroke();
  241. if (!pStrokeBrush)
  242. return;
  243. CXTPMarkupPointCollection* pPoints = GetPoints();
  244. if (!pPoints)
  245. return;
  246. const CXTPMarkupPointCollection::CPointArray& arr = pPoints->GetPoints();
  247. int nStroke = pStrokeBrush ? GetStrokeThickness() : 0;
  248. CPen penStroke;
  249. if (nStroke > 0) penStroke.CreatePen(PS_SOLID, nStroke, pStrokeBrush->GetHintColor());
  250. HGDIOBJ hOldPen = penStroke.GetSafeHandle() ? ::SelectObject(pDC->GetSafeHdc(), penStroke) : ::SelectObject(pDC->GetSafeHdc(), ::GetStockObject(NULL_PEN));
  251. if (GetStretch() != xtpMarkupStretchNone)
  252. {
  253. CXTPMarkupPointCollection::CPointArray arrStretch;
  254. arrStretch.Copy(arr);
  255. int nCount = (int)arrStretch.GetSize();
  256. CSize sz = GetRenderSize();
  257. CRect rc = pPoints->GetBounds();
  258. for (int i = 0; i < nCount; i++)
  259. {
  260. POINT& pt = arrStretch[i];
  261. if (rc.Width() != 0) pt.x = pt.x * sz.cx / rc.Width();
  262. if (rc.Height() != 0) pt.y = pt.y * sz.cy / rc.Height();
  263. }
  264. ::Polyline(pDC->GetSafeHdc(), arrStretch.GetData(), nCount);
  265. }
  266. else
  267. {
  268. ::Polyline(pDC->GetSafeHdc(), arr.GetData(), (int)arr.GetSize());
  269. }
  270. if (hOldPen) ::SelectObject(pDC->GetSafeHdc(), hOldPen);
  271. }
  272. //////////////////////////////////////////////////////////////////////////
  273. // CXTPMarkupRectangle
  274. IMPLEMENT_MARKUPCLASS(L"Rectangle", CXTPMarkupRectangle, CXTPMarkupShape)
  275. void CXTPMarkupRectangle::RegisterMarkupClass()
  276. {
  277. }
  278. CXTPMarkupRectangle::CXTPMarkupRectangle()
  279. {
  280. }
  281. CXTPMarkupRectangle::~CXTPMarkupRectangle()
  282. {
  283. }
  284. CSize CXTPMarkupRectangle::MeasureOverride(CXTPMarkupDrawingContext* /*pDC*/, CSize /*szAvailableSize*/)
  285. {
  286. return CSize(0, 0);
  287. }
  288. void CXTPMarkupRectangle::OnRender(CXTPMarkupDrawingContext* pDC)
  289. {
  290. CXTPMarkupBrush* pStrokeBrush = GetStroke();
  291. CXTPMarkupBrush* pFillBrush = GetFill();
  292. if (!pStrokeBrush && !pFillBrush)
  293. return;
  294. int nStroke = pStrokeBrush ? GetStrokeThickness() : 0;
  295. CRect rc(0, 0, GetRenderSize().cx, GetRenderSize().cy);
  296. if (rc.Width() == 0 || rc.Height() == 0)
  297. return;
  298. if (FALSE)
  299. {
  300. CPoint ptViewortOrg;
  301. GetViewportOrgEx(pDC->GetSafeHdc(), &ptViewortOrg);
  302. CRgn rgn;
  303. rgn.Attach(::CreateRoundRectRgn(ptViewortOrg.x, ptViewortOrg.y, ptViewortOrg.x + rc.Width(), ptViewortOrg.y + rc.Height(), 0, 0));
  304. ::ExtSelectClipRgn(pDC->GetSafeHdc(), rgn, RGN_AND);
  305. }
  306. if (pFillBrush) pFillBrush->FillRect(pDC, rc);
  307. if (nStroke > 0)
  308. {
  309. pStrokeBrush->FillRect(pDC, CRect(0, 0, nStroke, rc.bottom));
  310. pStrokeBrush->FillRect(pDC, CRect(rc.right - nStroke, 0, rc.right, rc.bottom));
  311. pStrokeBrush->FillRect(pDC, CRect(0, 0, rc.right, nStroke));
  312. pStrokeBrush->FillRect(pDC, CRect(0, rc.bottom - nStroke, rc.right, rc.bottom));
  313. }
  314. if (FALSE)
  315. {
  316. ::SelectClipRgn(pDC->GetSafeHdc(), 0);
  317. }
  318. }
  319. //////////////////////////////////////////////////////////////////////////
  320. // CXTPMarkupEllipse
  321. IMPLEMENT_MARKUPCLASS(L"Ellipse", CXTPMarkupEllipse, CXTPMarkupShape)
  322. void CXTPMarkupEllipse::RegisterMarkupClass()
  323. {
  324. }
  325. CXTPMarkupEllipse::CXTPMarkupEllipse()
  326. {
  327. }
  328. CXTPMarkupEllipse::~CXTPMarkupEllipse()
  329. {
  330. }
  331. CSize CXTPMarkupEllipse::MeasureOverride(CXTPMarkupDrawingContext* /*pDC*/, CSize /*szAvailableSize*/)
  332. {
  333. return CSize(0, 0);
  334. }
  335. void CXTPMarkupEllipse::OnRender(CXTPMarkupDrawingContext* pDC)
  336. {
  337. CXTPMarkupBrush* pStrokeBrush = GetStroke();
  338. CXTPMarkupBrush* pFillBrush = GetFill();
  339. if (!pStrokeBrush && !pFillBrush)
  340. return;
  341. int nStroke = pStrokeBrush ? GetStrokeThickness() : 0;
  342. CPen penStroke;
  343. if (nStroke > 0) penStroke.CreatePen(PS_SOLID, nStroke, pStrokeBrush->GetHintColor());
  344. CBrush brushFill;
  345. if (pFillBrush) brushFill.CreateSolidBrush(pFillBrush->GetHintColor());
  346. HGDIOBJ hOldPen = penStroke.GetSafeHandle() ? ::SelectObject(pDC->GetSafeHdc(), penStroke) : ::SelectObject(pDC->GetSafeHdc(), ::GetStockObject(NULL_PEN));
  347. HGDIOBJ hOldBrush = brushFill.GetSafeHandle() ? ::SelectObject(pDC->GetSafeHdc(), brushFill) : ::SelectObject(pDC->GetSafeHdc(), ::GetStockObject(NULL_BRUSH));
  348. ::Ellipse(pDC->GetSafeHdc(), 0, 0, GetRenderSize().cx, GetRenderSize().cy);
  349. if (hOldPen) ::SelectObject(pDC->GetSafeHdc(), hOldPen);
  350. if (hOldBrush) ::SelectObject(pDC->GetSafeHdc(), hOldBrush);
  351. }
  352. CXTPMarkupInputElement* CXTPMarkupEllipse::InputHitTestOverride(CPoint point) const
  353. {
  354. if (m_szRenderSize.cx < 1 || m_szRenderSize.cy < 1)
  355. return (CXTPMarkupInputElement*)this;
  356.    // Determine radii
  357. double a = m_szRenderSize.cx / 2;
  358. double b = m_szRenderSize.cy / 2;
  359. double x = point.x - a;
  360. double y = point.y - b;
  361. return ((x * x) / (a * a) + (y * y) / (b * b) <= 1) ? (CXTPMarkupInputElement*)this : NULL;
  362. }
  363. //////////////////////////////////////////////////////////////////////////
  364. //
  365. //////////////////////////////////////////////////////////////////////////
  366. // CXTPMarkupLine
  367. CXTPMarkupDependencyProperty* CXTPMarkupLine::m_pX1Property = NULL;
  368. CXTPMarkupDependencyProperty* CXTPMarkupLine::m_pY1Property = NULL;
  369. CXTPMarkupDependencyProperty* CXTPMarkupLine::m_pX2Property = NULL;
  370. CXTPMarkupDependencyProperty* CXTPMarkupLine::m_pY2Property = NULL;
  371. IMPLEMENT_MARKUPCLASS(L"Line", CXTPMarkupLine, CXTPMarkupShape)
  372. void CXTPMarkupLine::RegisterMarkupClass()
  373. {
  374. m_pX1Property = CXTPMarkupDependencyProperty::Register(L"X1", MARKUP_TYPE(CXTPMarkupInt), MARKUP_TYPE(CXTPMarkupLine),
  375. new CXTPMarkupPropertyMetadata(NULL, CXTPMarkupPropertyMetadata::flagAffectsMeasure));
  376. m_pY1Property = CXTPMarkupDependencyProperty::Register(L"Y1", MARKUP_TYPE(CXTPMarkupInt), MARKUP_TYPE(CXTPMarkupLine),
  377. new CXTPMarkupPropertyMetadata(NULL, CXTPMarkupPropertyMetadata::flagAffectsMeasure));
  378. m_pX2Property = CXTPMarkupDependencyProperty::Register(L"X2", MARKUP_TYPE(CXTPMarkupInt), MARKUP_TYPE(CXTPMarkupLine),
  379. new CXTPMarkupPropertyMetadata(NULL, CXTPMarkupPropertyMetadata::flagAffectsMeasure));
  380. m_pY2Property = CXTPMarkupDependencyProperty::Register(L"Y2", MARKUP_TYPE(CXTPMarkupInt), MARKUP_TYPE(CXTPMarkupLine),
  381. new CXTPMarkupPropertyMetadata(NULL, CXTPMarkupPropertyMetadata::flagAffectsMeasure));
  382. }
  383. CXTPMarkupLine::CXTPMarkupLine()
  384. {
  385. }
  386. CXTPMarkupLine::~CXTPMarkupLine()
  387. {
  388. }
  389. int CXTPMarkupLine::GetX1() const
  390. {
  391. CXTPMarkupInt* pValue = MARKUP_STATICCAST(CXTPMarkupInt, GetValue(m_pX1Property));
  392. return pValue != NULL ? (int)*pValue : 0;
  393. }
  394. int CXTPMarkupLine::GetX2() const
  395. {
  396. CXTPMarkupInt* pValue = MARKUP_STATICCAST(CXTPMarkupInt, GetValue(m_pX2Property));
  397. return pValue != NULL ? (int)*pValue : 0;
  398. }
  399. int CXTPMarkupLine::GetY1() const
  400. {
  401. CXTPMarkupInt* pValue = MARKUP_STATICCAST(CXTPMarkupInt, GetValue(m_pY1Property));
  402. return pValue != NULL ? (int)*pValue : 0;
  403. }
  404. int CXTPMarkupLine::GetY2() const
  405. {
  406. CXTPMarkupInt* pValue = MARKUP_STATICCAST(CXTPMarkupInt, GetValue(m_pY2Property));
  407. return pValue != NULL ? (int)*pValue : 0;
  408. }
  409. CSize CXTPMarkupLine::MeasureOverride(CXTPMarkupDrawingContext* /*pDC*/, CSize /*szAvailableSize*/)
  410. {
  411. int x = max(GetX1(), GetX2());
  412. int y = max(GetY1(), GetY2());
  413. return CSize(x, y);
  414. }
  415. void CXTPMarkupLine::OnRender(CXTPMarkupDrawingContext* pDC)
  416. {
  417. CXTPMarkupBrush* pStrokeBrush = GetStroke();
  418. if (!pStrokeBrush)
  419. return;
  420. int x1 = GetX1();
  421. int x2 = GetX2();
  422. int y1 = GetY1();
  423. int y2 = GetY2();
  424. if (x1 == 0 && x2 == 0 && y1 == 0 && y2 == 0)
  425. return;
  426. int nStroke = GetStrokeThickness();
  427. if (nStroke == 0)
  428. return;
  429. CPen penStroke;
  430. penStroke.CreatePen(PS_SOLID, nStroke, pStrokeBrush->GetHintColor());
  431. HGDIOBJ hOldPen = penStroke.GetSafeHandle() ? ::SelectObject(pDC->GetSafeHdc(), penStroke) : ::SelectObject(pDC->GetSafeHdc(), ::GetStockObject(NULL_PEN));
  432. ::MoveToEx(pDC->GetSafeHdc(), x1, y1, NULL);
  433. ::LineTo(pDC->GetSafeHdc(), x2, y2);
  434. if (hOldPen) ::SelectObject(pDC->GetSafeHdc(), hOldPen);
  435. }
  436. CXTPMarkupInputElement* CXTPMarkupLine::InputHitTestOverride(CPoint point) const
  437. {
  438. if (!GetStroke())
  439. return NULL;
  440. int nStroke = GetStrokeThickness();
  441. if (nStroke == 0)
  442. return NULL;
  443. double x = GetX2() - GetX1();
  444. double y = GetY2() - GetY1();
  445. double xp = point.x - GetX1();
  446. double yp = point.y - GetY1();
  447. double s = (double)nStroke / 2.0;
  448. if (xp + s < min(x, 0) || xp - s > max(x, 0) || yp + s < min(y, 0) || yp - s > max(y, 0))
  449. return NULL;
  450. if (x == 0)
  451. return fabs(xp) <= s ? (CXTPMarkupInputElement*)this : NULL;
  452. double yStroke = fabs(s / cos(atan(y / x)));
  453. double y0 = y * xp / (double)x;
  454. return fabs(y0 - yp) <= yStroke ? (CXTPMarkupInputElement*)this : NULL;
  455. }