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

对话框与窗口

开发平台:

Visual C++

  1. // drawobj.cpp - implementation for drawing objects
  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 "drawcli.h"
  22. #include "drawdoc.h"
  23. #include "drawvw.h"
  24. #include "drawobj.h"
  25. #include "cntritem.h"
  26. #include "rectdlg.h"
  27. IMPLEMENT_SERIAL(CDrawObj, CObject, 0)
  28. CDrawObj::CDrawObj()
  29. {
  30. }
  31. CDrawObj::~CDrawObj()
  32. {
  33. }
  34. CDrawObj::CDrawObj(const CRect& position)
  35. {
  36. m_position = position;
  37. m_pDocument = NULL;
  38. m_bPen = TRUE;
  39. m_logpen.lopnStyle = PS_INSIDEFRAME;
  40. m_logpen.lopnWidth.x = 1;
  41. m_logpen.lopnWidth.y = 1;
  42. m_logpen.lopnColor = RGB(0, 0, 0);
  43. m_bBrush = TRUE;
  44. m_logbrush.lbStyle = BS_SOLID;
  45. m_logbrush.lbColor = RGB(192, 192, 192);
  46. m_logbrush.lbHatch = HS_HORIZONTAL;
  47. }
  48. void CDrawObj::Serialize(CArchive& ar)
  49. {
  50. CObject::Serialize(ar);
  51. if (ar.IsStoring())
  52. {
  53. ar << m_position;
  54. ar << (WORD)m_bPen;
  55. ar.Write(&m_logpen, sizeof(LOGPEN));
  56. ar << (WORD)m_bBrush;
  57. ar.Write(&m_logbrush, sizeof(LOGBRUSH));
  58. }
  59. else
  60. {
  61. // get the document back pointer from the archive
  62. m_pDocument = (CDrawDoc*)ar.m_pDocument;
  63. ASSERT_VALID(m_pDocument);
  64. ASSERT_KINDOF(CDrawDoc, m_pDocument);
  65. WORD wTemp;
  66. ar >> m_position;
  67. ar >> wTemp; m_bPen = (BOOL)wTemp;
  68. ar.Read(&m_logpen,sizeof(LOGPEN));
  69. ar >> wTemp; m_bBrush = (BOOL)wTemp;
  70. ar.Read(&m_logbrush, sizeof(LOGBRUSH));
  71. }
  72. }
  73. void CDrawObj::Remove()
  74. {
  75. delete this;
  76. }
  77. void CDrawObj::Draw(CDC*)
  78. {
  79. }
  80. void CDrawObj::DrawTracker(CDC* pDC, TrackerState state)
  81. {
  82. ASSERT_VALID(this);
  83. switch (state)
  84. {
  85. case normal:
  86. break;
  87. case selected:
  88. case active:
  89. {
  90. int nHandleCount = GetHandleCount();
  91. for (int nHandle = 1; nHandle <= nHandleCount; nHandle += 1)
  92. {
  93. CPoint handle = GetHandle(nHandle);
  94. pDC->PatBlt(handle.x - 3, handle.y - 3, 7, 7, DSTINVERT);
  95. }
  96. }
  97. break;
  98. }
  99. }
  100. // position is in logical
  101. void CDrawObj::MoveTo(const CRect& position, CDrawView* pView)
  102. {
  103. ASSERT_VALID(this);
  104. if (position == m_position)
  105. return;
  106. if (pView == NULL)
  107. {
  108. Invalidate();
  109. m_position = position;
  110. Invalidate();
  111. }
  112. else
  113. {
  114. pView->InvalObj(this);
  115. m_position = position;
  116. pView->InvalObj(this);
  117. }
  118. m_pDocument->SetModifiedFlag();
  119. }
  120. // Note: if bSelected, hit-codes start at one for the top-left
  121. // and increment clockwise, 0 means no hit.
  122. // If !bSelected, 0 = no hit, 1 = hit (anywhere)
  123. // point is in logical coordinates
  124. int CDrawObj::HitTest(CPoint point, CDrawView* pView, BOOL bSelected)
  125. {
  126. ASSERT_VALID(this);
  127. ASSERT(pView != NULL);
  128. if (bSelected)
  129. {
  130. int nHandleCount = GetHandleCount();
  131. for (int nHandle = 1; nHandle <= nHandleCount; nHandle += 1)
  132. {
  133. // GetHandleRect returns in logical coords
  134. CRect rc = GetHandleRect(nHandle,pView);
  135. if (point.x >= rc.left && point.x < rc.right &&
  136. point.y <= rc.top && point.y > rc.bottom)
  137. return nHandle;
  138. }
  139. }
  140. else
  141. {
  142. if (point.x >= m_position.left && point.x < m_position.right &&
  143. point.y <= m_position.top && point.y > m_position.bottom)
  144. return 1;
  145. }
  146. return 0;
  147. }
  148. // rect must be in logical coordinates
  149. BOOL CDrawObj::Intersects(const CRect& rect)
  150. {
  151. ASSERT_VALID(this);
  152. CRect fixed = m_position;
  153. fixed.NormalizeRect();
  154. CRect rectT = rect;
  155. rectT.NormalizeRect();
  156. return !(rectT & fixed).IsRectEmpty();
  157. }
  158. int CDrawObj::GetHandleCount()
  159. {
  160. ASSERT_VALID(this);
  161. return 8;
  162. }
  163. // returns logical coords of center of handle
  164. CPoint CDrawObj::GetHandle(int nHandle)
  165. {
  166. ASSERT_VALID(this);
  167. int x, y, xCenter, yCenter;
  168. // this gets the center regardless of left/right and top/bottom ordering
  169. xCenter = m_position.left + m_position.Width() / 2;
  170. yCenter = m_position.top + m_position.Height() / 2;
  171. switch (nHandle)
  172. {
  173. default:
  174. ASSERT(FALSE);
  175. case 1:
  176. x = m_position.left;
  177. y = m_position.top;
  178. break;
  179. case 2:
  180. x = xCenter;
  181. y = m_position.top;
  182. break;
  183. case 3:
  184. x = m_position.right;
  185. y = m_position.top;
  186. break;
  187. case 4:
  188. x = m_position.right;
  189. y = yCenter;
  190. break;
  191. case 5:
  192. x = m_position.right;
  193. y = m_position.bottom;
  194. break;
  195. case 6:
  196. x = xCenter;
  197. y = m_position.bottom;
  198. break;
  199. case 7:
  200. x = m_position.left;
  201. y = m_position.bottom;
  202. break;
  203. case 8:
  204. x = m_position.left;
  205. y = yCenter;
  206. break;
  207. }
  208. return CPoint(x, y);
  209. }
  210. // return rectange of handle in logical coords
  211. CRect CDrawObj::GetHandleRect(int nHandleID, CDrawView* pView)
  212. {
  213. ASSERT_VALID(this);
  214. ASSERT(pView != NULL);
  215. CRect rect;
  216. // get the center of the handle in logical coords
  217. CPoint point = GetHandle(nHandleID);
  218. // convert to client/device coords
  219. pView->DocToClient(point);
  220. // return CRect of handle in device coords
  221. rect.SetRect(point.x-3, point.y-3, point.x+3, point.y+3);
  222. pView->ClientToDoc(rect);
  223. return rect;
  224. }
  225. HCURSOR CDrawObj::GetHandleCursor(int nHandle)
  226. {
  227. ASSERT_VALID(this);
  228. LPCTSTR id;
  229. switch (nHandle)
  230. {
  231. default:
  232. ASSERT(FALSE);
  233. case 1:
  234. case 5:
  235. id = IDC_SIZENWSE;
  236. break;
  237. case 2:
  238. case 6:
  239. id = IDC_SIZENS;
  240. break;
  241. case 3:
  242. case 7:
  243. id = IDC_SIZENESW;
  244. break;
  245. case 4:
  246. case 8:
  247. id = IDC_SIZEWE;
  248. break;
  249. }
  250. return AfxGetApp()->LoadStandardCursor(id);
  251. }
  252. // point must be in logical
  253. void CDrawObj::MoveHandleTo(int nHandle, CPoint point, CDrawView* pView)
  254. {
  255. ASSERT_VALID(this);
  256. CRect position = m_position;
  257. switch (nHandle)
  258. {
  259. default:
  260. ASSERT(FALSE);
  261. case 1:
  262. position.left = point.x;
  263. position.top = point.y;
  264. break;
  265. case 2:
  266. position.top = point.y;
  267. break;
  268. case 3:
  269. position.right = point.x;
  270. position.top = point.y;
  271. break;
  272. case 4:
  273. position.right = point.x;
  274. break;
  275. case 5:
  276. position.right = point.x;
  277. position.bottom = point.y;
  278. break;
  279. case 6:
  280. position.bottom = point.y;
  281. break;
  282. case 7:
  283. position.left = point.x;
  284. position.bottom = point.y;
  285. break;
  286. case 8:
  287. position.left = point.x;
  288. break;
  289. }
  290. MoveTo(position, pView);
  291. }
  292. void CDrawObj::Invalidate()
  293. {
  294. ASSERT_VALID(this);
  295. m_pDocument->UpdateAllViews(NULL, HINT_UPDATE_DRAWOBJ, this);
  296. }
  297. CDrawObj* CDrawObj::Clone(CDrawDoc* pDoc)
  298. {
  299. ASSERT_VALID(this);
  300. CDrawObj* pClone = new CDrawObj(m_position);
  301. pClone->m_bPen = m_bPen;
  302. pClone->m_logpen = m_logpen;
  303. pClone->m_bBrush = m_bBrush;
  304. pClone->m_logbrush = m_logbrush;
  305. ASSERT_VALID(pClone);
  306. if (pDoc != NULL)
  307. pDoc->Add(pClone);
  308. return pClone;
  309. }
  310. void CDrawObj::OnEditProperties()
  311. {
  312. ASSERT_VALID(this);
  313. CPropertySheet sheet( _T("Shape Properties") );
  314. CRectDlg dlg;
  315. dlg.m_bNoFill = !m_bBrush;
  316. dlg.m_penSize = m_bPen ? m_logpen.lopnWidth.x : 0;
  317. sheet.AddPage( &dlg );
  318. if (sheet.DoModal() != IDOK)
  319. return;
  320. m_bBrush = !dlg.m_bNoFill;
  321. m_bPen = dlg.m_penSize > 0;
  322. if (m_bPen)
  323. {
  324. m_logpen.lopnWidth.x = dlg.m_penSize;
  325. m_logpen.lopnWidth.y = dlg.m_penSize;
  326. }
  327. Invalidate();
  328. m_pDocument->SetModifiedFlag();
  329. }
  330. void CDrawObj::OnOpen(CDrawView* /*pView*/ )
  331. {
  332. OnEditProperties();
  333. }
  334. void CDrawObj::SetLineColor(COLORREF color)
  335. {
  336. ASSERT_VALID(this);
  337. m_logpen.lopnColor = color;
  338. Invalidate();
  339. m_pDocument->SetModifiedFlag();
  340. }
  341. void CDrawObj::SetFillColor(COLORREF color)
  342. {
  343. ASSERT_VALID(this);
  344. m_logbrush.lbColor = color;
  345. Invalidate();
  346. m_pDocument->SetModifiedFlag();
  347. }
  348. #ifdef _DEBUG
  349. void CDrawObj::AssertValid()
  350. {
  351. ASSERT(m_position.left <= m_position.right);
  352. ASSERT(m_position.bottom <= m_position.top);
  353. }
  354. #endif
  355. ////////////////////////////////////////////////////////////////////////////
  356. // CDrawRect
  357. IMPLEMENT_SERIAL(CDrawRect, CDrawObj, 0)
  358. CDrawRect::CDrawRect()
  359. {
  360. }
  361. CDrawRect::CDrawRect(const CRect& position)
  362. : CDrawObj(position)
  363. {
  364. ASSERT_VALID(this);
  365. m_nShape = rectangle;
  366. m_roundness.x = 16;
  367. m_roundness.y = 16;
  368. }
  369. void CDrawRect::Serialize(CArchive& ar)
  370. {
  371. ASSERT_VALID(this);
  372. CDrawObj::Serialize(ar);
  373. if (ar.IsStoring())
  374. {
  375. ar << (WORD) m_nShape;
  376. ar << m_roundness;
  377. }
  378. else
  379. {
  380. WORD wTemp;
  381. ar >> wTemp; m_nShape = (Shape)wTemp;
  382. ar >> m_roundness;
  383. }
  384. }
  385. void CDrawRect::Draw(CDC* pDC)
  386. {
  387. ASSERT_VALID(this);
  388. CBrush brush;
  389. if (!brush.CreateBrushIndirect(&m_logbrush))
  390. return;
  391. CPen pen;
  392. if (!pen.CreatePenIndirect(&m_logpen))
  393. return;
  394. CBrush* pOldBrush;
  395. CPen* pOldPen;
  396. if (m_bBrush)
  397. pOldBrush = pDC->SelectObject(&brush);
  398. else
  399. pOldBrush = (CBrush*)pDC->SelectStockObject(NULL_BRUSH);
  400. if (m_bPen)
  401. pOldPen = pDC->SelectObject(&pen);
  402. else
  403. pOldPen = (CPen*)pDC->SelectStockObject(NULL_PEN);
  404. CRect rect = m_position;
  405. switch (m_nShape)
  406. {
  407. case rectangle:
  408. pDC->Rectangle(rect);
  409. break;
  410. case roundRectangle:
  411. pDC->RoundRect(rect, m_roundness);
  412. break;
  413. case ellipse:
  414. pDC->Ellipse(rect);
  415. break;
  416. case line:
  417. if (rect.top > rect.bottom)
  418. {
  419. rect.top -= m_logpen.lopnWidth.y / 2;
  420. rect.bottom += (m_logpen.lopnWidth.y + 1) / 2;
  421. }
  422. else
  423. {
  424. rect.top += (m_logpen.lopnWidth.y + 1) / 2;
  425. rect.bottom -= m_logpen.lopnWidth.y / 2;
  426. }
  427. if (rect.left > rect.right)
  428. {
  429. rect.left -= m_logpen.lopnWidth.x / 2;
  430. rect.right += (m_logpen.lopnWidth.x + 1) / 2;
  431. }
  432. else
  433. {
  434. rect.left += (m_logpen.lopnWidth.x + 1) / 2;
  435. rect.right -= m_logpen.lopnWidth.x / 2;
  436. }
  437. pDC->MoveTo(rect.TopLeft());
  438. pDC->LineTo(rect.BottomRight());
  439. break;
  440. }
  441. pDC->SelectObject(pOldBrush);
  442. pDC->SelectObject(pOldPen);
  443. }
  444. int CDrawRect::GetHandleCount()
  445. {
  446. ASSERT_VALID(this);
  447. return m_nShape == line ? 2 :
  448. CDrawObj::GetHandleCount() + (m_nShape == roundRectangle);
  449. }
  450. // returns center of handle in logical coordinates
  451. CPoint CDrawRect::GetHandle(int nHandle)
  452. {
  453. ASSERT_VALID(this);
  454. if (m_nShape == line && nHandle == 2)
  455. nHandle = 5;
  456. else if (m_nShape == roundRectangle && nHandle == 9)
  457. {
  458. CRect rect = m_position;
  459. rect.NormalizeRect();
  460. CPoint point = rect.BottomRight();
  461. point.x -= m_roundness.x / 2;
  462. point.y -= m_roundness.y / 2;
  463. return point;
  464. }
  465. return CDrawObj::GetHandle(nHandle);
  466. }
  467. HCURSOR CDrawRect::GetHandleCursor(int nHandle)
  468. {
  469. ASSERT_VALID(this);
  470. if (m_nShape == line && nHandle == 2)
  471. nHandle = 5;
  472. else if (m_nShape == roundRectangle && nHandle == 9)
  473. return AfxGetApp()->LoadStandardCursor(IDC_SIZEALL);
  474. return CDrawObj::GetHandleCursor(nHandle);
  475. }
  476. // point is in logical coordinates
  477. void CDrawRect::MoveHandleTo(int nHandle, CPoint point, CDrawView* pView)
  478. {
  479. ASSERT_VALID(this);
  480. if (m_nShape == line && nHandle == 2)
  481. nHandle = 5;
  482. else if (m_nShape == roundRectangle && nHandle == 9)
  483. {
  484. CRect rect = m_position;
  485. rect.NormalizeRect();
  486. if (point.x > rect.right - 1)
  487. point.x = rect.right - 1;
  488. else if (point.x < rect.left + rect.Width() / 2)
  489. point.x = rect.left + rect.Width() / 2;
  490. if (point.y > rect.bottom - 1)
  491. point.y = rect.bottom - 1;
  492. else if (point.y < rect.top + rect.Height() / 2)
  493. point.y = rect.top + rect.Height() / 2;
  494. m_roundness.x = 2 * (rect.right - point.x);
  495. m_roundness.y = 2 * (rect.bottom - point.y);
  496. m_pDocument->SetModifiedFlag();
  497. if (pView == NULL)
  498. Invalidate();
  499. else
  500. pView->InvalObj(this);
  501. return;
  502. }
  503. CDrawObj::MoveHandleTo(nHandle, point, pView);
  504. }
  505. // rect must be in logical coordinates
  506. BOOL CDrawRect::Intersects(const CRect& rect)
  507. {
  508. ASSERT_VALID(this);
  509. CRect rectT = rect;
  510. rectT.NormalizeRect();
  511. CRect fixed = m_position;
  512. fixed.NormalizeRect();
  513. if ((rectT & fixed).IsRectEmpty())
  514. return FALSE;
  515. CRgn rgn;
  516. switch (m_nShape)
  517. {
  518. case rectangle:
  519. return TRUE;
  520. case roundRectangle:
  521. rgn.CreateRoundRectRgn(fixed.left, fixed.top, fixed.right, fixed.bottom,
  522. m_roundness.x, m_roundness.y);
  523. break;
  524. case ellipse:
  525. rgn.CreateEllipticRgnIndirect(fixed);
  526. break;
  527. case line:
  528. {
  529. int x = (m_logpen.lopnWidth.x + 5) / 2;
  530. int y = (m_logpen.lopnWidth.y + 5) / 2;
  531. POINT points[4];
  532. points[0].x = fixed.left;
  533. points[0].y = fixed.top;
  534. points[1].x = fixed.left;
  535. points[1].y = fixed.top;
  536. points[2].x = fixed.right;
  537. points[2].y = fixed.bottom;
  538. points[3].x = fixed.right;
  539. points[3].y = fixed.bottom;
  540. if (fixed.left < fixed.right)
  541. {
  542. points[0].x -= x;
  543. points[1].x += x;
  544. points[2].x += x;
  545. points[3].x -= x;
  546. }
  547. else
  548. {
  549. points[0].x += x;
  550. points[1].x -= x;
  551. points[2].x -= x;
  552. points[3].x += x;
  553. }
  554. if (fixed.top < fixed.bottom)
  555. {
  556. points[0].y -= y;
  557. points[1].y += y;
  558. points[2].y += y;
  559. points[3].y -= y;
  560. }
  561. else
  562. {
  563. points[0].y += y;
  564. points[1].y -= y;
  565. points[2].y -= y;
  566. points[3].y += y;
  567. }
  568. rgn.CreatePolygonRgn(points, 4, ALTERNATE);
  569. }
  570. break;
  571. }
  572. return rgn.RectInRegion(fixed);
  573. }
  574. CDrawObj* CDrawRect::Clone(CDrawDoc* pDoc)
  575. {
  576. ASSERT_VALID(this);
  577. CDrawRect* pClone = new CDrawRect(m_position);
  578. pClone->m_bPen = m_bPen;
  579. pClone->m_logpen = m_logpen;
  580. pClone->m_bBrush = m_bBrush;
  581. pClone->m_logbrush = m_logbrush;
  582. pClone->m_nShape = m_nShape;
  583. pClone->m_roundness = m_roundness;
  584. ASSERT_VALID(pClone);
  585. if (pDoc != NULL)
  586. pDoc->Add(pClone);
  587. ASSERT_VALID(pClone);
  588. return pClone;
  589. }
  590. ////////////////////////////////////////////////////////////////////////////
  591. // CDrawPoly
  592. IMPLEMENT_SERIAL(CDrawPoly, CDrawObj, 0)
  593. CDrawPoly::CDrawPoly()
  594. {
  595. m_points = NULL;
  596. m_nPoints = 0;
  597. m_nAllocPoints = 0;
  598. }
  599. CDrawPoly::CDrawPoly(const CRect& position)
  600. : CDrawObj(position)
  601. {
  602. m_points = NULL;
  603. m_nPoints = 0;
  604. m_nAllocPoints = 0;
  605. m_bPen = TRUE;
  606. m_bBrush = FALSE;
  607. }
  608. CDrawPoly::~CDrawPoly()
  609. {
  610. if (m_points != NULL)
  611. delete[] m_points;
  612. }
  613. void CDrawPoly::Serialize( CArchive& ar )
  614. {
  615. int i;
  616. CDrawObj::Serialize( ar );
  617. if( ar.IsStoring() )
  618. {
  619. ar << (WORD) m_nPoints;
  620. ar << (WORD) m_nAllocPoints;
  621. for (i = 0;i< m_nPoints; i++)
  622. ar << m_points[i];
  623. }
  624. else
  625. {
  626. WORD wTemp;
  627. ar >> wTemp; m_nPoints = wTemp;
  628. ar >> wTemp; m_nAllocPoints = wTemp;
  629. m_points = new CPoint[m_nAllocPoints];
  630. for (i = 0;i < m_nPoints; i++)
  631. ar >> m_points[i];
  632. }
  633. }
  634. void CDrawPoly::Draw(CDC* pDC)
  635. {
  636. ASSERT_VALID(this);
  637. CBrush brush;
  638. if (!brush.CreateBrushIndirect(&m_logbrush))
  639. return;
  640. CPen pen;
  641. if (!pen.CreatePenIndirect(&m_logpen))
  642. return;
  643. CBrush* pOldBrush;
  644. CPen* pOldPen;
  645. if (m_bBrush)
  646. pOldBrush = pDC->SelectObject(&brush);
  647. else
  648. pOldBrush = (CBrush*)pDC->SelectStockObject(NULL_BRUSH);
  649. if (m_bPen)
  650. pOldPen = pDC->SelectObject(&pen);
  651. else
  652. pOldPen = (CPen*)pDC->SelectStockObject(NULL_PEN);
  653. pDC->Polygon(m_points, m_nPoints);
  654. pDC->SelectObject(pOldBrush);
  655. pDC->SelectObject(pOldPen);
  656. }
  657. // position must be in logical coordinates
  658. void CDrawPoly::MoveTo(const CRect& position, CDrawView* pView)
  659. {
  660. ASSERT_VALID(this);
  661. if (position == m_position)
  662. return;
  663. if (pView == NULL)
  664. Invalidate();
  665. else
  666. pView->InvalObj(this);
  667. for (int i = 0; i < m_nPoints; i += 1)
  668. {
  669. m_points[i].x += position.left - m_position.left;
  670. m_points[i].y += position.top - m_position.top;
  671. }
  672. m_position = position;
  673. if (pView == NULL)
  674. Invalidate();
  675. else
  676. pView->InvalObj(this);
  677. m_pDocument->SetModifiedFlag();
  678. }
  679. int CDrawPoly::GetHandleCount()
  680. {
  681. return m_nPoints;
  682. }
  683. CPoint CDrawPoly::GetHandle(int nHandle)
  684. {
  685. ASSERT_VALID(this);
  686. ASSERT(nHandle >= 1 && nHandle <= m_nPoints);
  687. return m_points[nHandle - 1];
  688. }
  689. HCURSOR CDrawPoly::GetHandleCursor(int )
  690. {
  691. return AfxGetApp()->LoadStandardCursor(IDC_ARROW);
  692. }
  693. // point is in logical coordinates
  694. void CDrawPoly::MoveHandleTo(int nHandle, CPoint point, CDrawView* pView)
  695. {
  696. ASSERT_VALID(this);
  697. ASSERT(nHandle >= 1 && nHandle <= m_nPoints);
  698. if (m_points[nHandle - 1] == point)
  699. return;
  700. m_points[nHandle - 1] = point;
  701. RecalcBounds(pView);
  702. if (pView == NULL)
  703. Invalidate();
  704. else
  705. pView->InvalObj(this);
  706. m_pDocument->SetModifiedFlag();
  707. }
  708. // rect must be in logical coordinates
  709. BOOL CDrawPoly::Intersects(const CRect& rect)
  710. {
  711. ASSERT_VALID(this);
  712. CRgn rgn;
  713. rgn.CreatePolygonRgn(m_points, m_nPoints, ALTERNATE);
  714. return rgn.RectInRegion(rect);
  715. }
  716. CDrawObj* CDrawPoly::Clone(CDrawDoc* pDoc)
  717. {
  718. ASSERT_VALID(this);
  719. CDrawPoly* pClone = new CDrawPoly(m_position);
  720. pClone->m_bPen = m_bPen;
  721. pClone->m_logpen = m_logpen;
  722. pClone->m_bBrush = m_bBrush;
  723. pClone->m_logbrush = m_logbrush;
  724. pClone->m_points = new CPoint[m_nAllocPoints];
  725. MEMCPY_S(pClone->m_points, m_points, sizeof(CPoint) * m_nPoints);
  726. pClone->m_nAllocPoints = m_nAllocPoints;
  727. pClone->m_nPoints = m_nPoints;
  728. ASSERT_VALID(pClone);
  729. if (pDoc != NULL)
  730. pDoc->Add(pClone);
  731. ASSERT_VALID(pClone);
  732. return pClone;
  733. }
  734. // point is in logical coordinates
  735. void CDrawPoly::AddPoint(const CPoint& point, CDrawView* pView)
  736. {
  737. ASSERT_VALID(this);
  738. if (m_nPoints == m_nAllocPoints)
  739. {
  740. CPoint* newPoints = new CPoint[m_nAllocPoints + 10];
  741. if (m_points != NULL)
  742. {
  743. MEMCPY_S(newPoints, m_points, sizeof(CPoint) * m_nAllocPoints);
  744. delete[] m_points;
  745. }
  746. m_points = newPoints;
  747. m_nAllocPoints += 10;
  748. }
  749. if (m_nPoints == 0 || m_points[m_nPoints - 1] != point)
  750. {
  751. m_points[m_nPoints++] = point;
  752. if (!RecalcBounds(pView))
  753. {
  754. if (pView == NULL)
  755. Invalidate();
  756. else
  757. pView->InvalObj(this);
  758. }
  759. m_pDocument->SetModifiedFlag();
  760. }
  761. }
  762. BOOL CDrawPoly::RecalcBounds(CDrawView* pView)
  763. {
  764. ASSERT_VALID(this);
  765. if (m_nPoints == 0)
  766. return FALSE;
  767. CRect bounds(m_points[0], CSize(0, 0));
  768. for (int i = 1; i < m_nPoints; ++i)
  769. {
  770. if (m_points[i].x < bounds.left)
  771. bounds.left = m_points[i].x;
  772. if (m_points[i].x > bounds.right)
  773. bounds.right = m_points[i].x;
  774. if (m_points[i].y < bounds.top)
  775. bounds.top = m_points[i].y;
  776. if (m_points[i].y > bounds.bottom)
  777. bounds.bottom = m_points[i].y;
  778. }
  779. if (bounds == m_position)
  780. return FALSE;
  781. if (pView == NULL)
  782. Invalidate();
  783. else
  784. pView->InvalObj(this);
  785. m_position = bounds;
  786. if (pView == NULL)
  787. Invalidate();
  788. else
  789. pView->InvalObj(this);
  790. return TRUE;
  791. }
  792. ////////////////////////////////////////////////////////////////////////////
  793. IMPLEMENT_SERIAL(CDrawOleObj, CDrawObj, 0)
  794. BOOL CDrawOleObj::c_bShowItems = TRUE;
  795. CDrawOleObj::CDrawOleObj() : m_extent(0,0)
  796. {
  797. m_pClientItem = NULL;
  798. }
  799. CDrawOleObj::CDrawOleObj(const CRect& position)
  800. : CDrawObj(position), m_extent(0, 0)
  801. {
  802. m_pClientItem = NULL;
  803. }
  804. CDrawOleObj::~CDrawOleObj()
  805. {
  806. if (m_pClientItem != NULL)
  807. {
  808. m_pClientItem->Release();
  809. m_pClientItem = NULL;
  810. }
  811. }
  812. void CDrawOleObj::Remove()
  813. {
  814. if (m_pClientItem != NULL)
  815. {
  816. m_pClientItem->Delete();
  817. m_pClientItem = NULL;
  818. }
  819. CDrawObj::Remove();
  820. }
  821. void CDrawOleObj::Serialize( CArchive& ar )
  822. {
  823. ASSERT_VALID(this);
  824. CDrawObj::Serialize(ar);
  825. if (ar.IsStoring())
  826. {
  827. ar << m_extent;
  828. ar << m_pClientItem;
  829. }
  830. else
  831. {
  832. ar >> m_extent;
  833. ar >> m_pClientItem;
  834. m_pClientItem->m_pDrawObj = this;
  835. }
  836. }
  837. CDrawObj* CDrawOleObj::Clone(CDrawDoc* pDoc)
  838. {
  839. ASSERT_VALID(this);
  840. AfxGetApp()->BeginWaitCursor();
  841. CDrawOleObj* pClone = NULL;
  842. CDrawItem* pItem = NULL;
  843. TRY
  844. {
  845. // perform a "deep copy" -- need to copy CDrawOleObj and the CDrawItem
  846. //  that it points to.
  847. CDrawOleObj* pClone = new CDrawOleObj(m_position);
  848. CDrawItem* pItem = new CDrawItem(m_pDocument, pClone);
  849. if (!pItem->CreateCloneFrom(m_pClientItem))
  850. AfxThrowMemoryException();
  851. pClone->m_pClientItem = pItem;
  852. pClone->m_bPen = m_bPen;
  853. pClone->m_logpen = m_logpen;
  854. pClone->m_bBrush = m_bBrush;
  855. pClone->m_logbrush = m_logbrush;
  856. ASSERT_VALID(pClone);
  857. if (pDoc != NULL)
  858. pDoc->Add(pClone);
  859. }
  860. CATCH_ALL(e)
  861. {
  862. pItem->Delete();
  863. pClone->m_pClientItem = NULL;
  864. pClone->Remove();
  865. AfxGetApp()->EndWaitCursor();
  866. THROW_LAST();
  867. }
  868. END_CATCH_ALL
  869. AfxGetApp()->EndWaitCursor();
  870. return pClone;
  871. }
  872. void CDrawOleObj::Draw(CDC* pDC)
  873. {
  874. ASSERT_VALID(this);
  875. CDrawItem* pItem = m_pClientItem;
  876. if (pItem != NULL)
  877. {
  878. // draw the OLE item itself
  879. pItem->Draw(pDC, m_position);
  880. // don't draw tracker in print preview or on printer
  881. if (!pDC->IsPrinting())
  882. {
  883. // use a CRectTracker to draw the standard effects
  884. CRectTracker tracker;
  885. tracker.m_rect = m_position;
  886. pDC->LPtoDP(tracker.m_rect);
  887. if (c_bShowItems)
  888. {
  889. // put correct border depending on item type
  890. if (pItem->GetType() == OT_LINK)
  891. tracker.m_nStyle |= CRectTracker::dottedLine;
  892. else
  893. tracker.m_nStyle |= CRectTracker::solidLine;
  894. }
  895. // put hatching over the item if it is currently open
  896. if (pItem->GetItemState() == COleClientItem::openState ||
  897. pItem->GetItemState() == COleClientItem::activeUIState)
  898. {
  899. tracker.m_nStyle |= CRectTracker::hatchInside;
  900. }
  901. tracker.Draw(pDC);
  902. }
  903. }
  904. }
  905. void CDrawOleObj::OnOpen(CDrawView* pView)
  906. {
  907. AfxGetApp()->BeginWaitCursor();
  908. m_pClientItem->DoVerb(
  909. GetKeyState(VK_CONTROL) < 0 ? OLEIVERB_OPEN : OLEIVERB_PRIMARY,
  910. pView);
  911. AfxGetApp()->EndWaitCursor();
  912. }
  913. void CDrawOleObj::OnEditProperties()
  914. {
  915. // using COlePropertiesDialog directly means no scaling
  916. COlePropertiesDialog dlg(m_pClientItem, 100, 100, NULL);
  917. dlg.DoModal();
  918. }
  919. // position is in logical
  920. void CDrawOleObj::MoveTo(const CRect& position, CDrawView* pView)
  921. {
  922. ASSERT_VALID(this);
  923. if (position == m_position)
  924. return;
  925. // call base class to update position
  926. CDrawObj::MoveTo(position, pView);
  927. // update position of in-place editing session on position change
  928. if (m_pClientItem->IsInPlaceActive())
  929. m_pClientItem->SetItemRects();
  930. }
  931. /////////////////////////////////////////////////////////////////////////////