Graph.cpp 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354
  1. // CGraph.cpp: implementation of the CGraph class.
  2. //
  3. //////////////////////////////////////////////////////////////////////
  4. #include "stdafx.h"
  5. //#include <afxtempl.h>
  6. #include "drawobj.h"
  7. #include "graph.h"
  8. //---------------------------------------------- CGraph ---------
  9. CGraph::CGraph(CSize size)
  10. {
  11. m_Type = 1;
  12. m_sizePic.cx = size.cx;
  13. m_sizePic.cy = size.cy;
  14. m_bGrid = FALSE;
  15. m_sizeGrid.cx = 40;
  16. m_sizeGrid.cy = 40;
  17. m_clrBack = RGB(230, 241, 249);//RGB(255, 255, 255);//RGB(92, 92, 92);画面默认背景 颜色
  18. }
  19. CGraph::~CGraph(void)
  20. {
  21. ClearDrawList();
  22. }
  23. void CGraph::ClearDrawList()
  24. {
  25. CDrawObj *pDrawObj = NULL;
  26. while( !m_DrawObjList.IsEmpty() )
  27. {
  28. // RemoveTail删除元素并返回对象指针;
  29. pDrawObj = m_DrawObjList.RemoveTail();
  30. if ( pDrawObj )
  31. delete pDrawObj;
  32. pDrawObj = NULL;
  33. }
  34. }
  35. void CGraph::SetPicFile(IN LPCTSTR lpPicPath)
  36. {
  37. if ( lpPicPath != NULL )
  38. m_strPicFile = lpPicPath;
  39. }
  40. void CGraph::SetView(CView* pView)
  41. {
  42. m_pView = pView; // if ( pView == NULL )
  43. POSITION pos = m_DrawObjList.GetHeadPosition();
  44. while( pos != NULL )
  45. {
  46. CDrawObj *pDrawObj = m_DrawObjList.GetNext(pos);
  47. pDrawObj->m_pView = m_pView;
  48. }
  49. }
  50. BOOL CGraph::Load(void)
  51. {
  52. // 加载前,先清空以前的;
  53. ClearDrawList();
  54. if ( m_pView == NULL)
  55. return FALSE;
  56. // 从文件中读取;
  57. CFile file;
  58. if ( !file.Open(m_strPicFile,CFile::modeRead) )
  59. return FALSE;
  60. CArchive ar(&file,CArchive::load);
  61. ar >> m_Type;
  62. ar >> m_sizePic;
  63. ar >> m_sizeGrid;
  64. ar >> m_bGrid;
  65. ar >> m_clrBack;
  66. m_DrawObjList.Serialize(ar);
  67. // 编辑按钮控件数次,有撤销显示时,继续编辑,点击撤销,客户端会崩溃 解决;
  68. POSITION pos = m_DrawObjList.GetHeadPosition();
  69. while ( pos != NULL )
  70. {
  71. CDrawObj *pDrawObj = m_DrawObjList.GetNext(pos);
  72. pDrawObj->m_pView = m_pView;
  73. }
  74. // 释放资源;
  75. ar.Close();
  76. file.Close();
  77. return TRUE;
  78. }
  79. void CGraph::Store(void)
  80. {
  81. CFile file;
  82. if(file.Open(m_strPicFile,CFile::modeCreate|CFile::modeWrite))
  83. {
  84. CArchive ar(&file,CArchive::store);
  85. ar << m_Type;
  86. ar << m_sizePic;
  87. ar << m_sizeGrid;
  88. ar << m_bGrid;
  89. ar << m_clrBack;
  90. m_DrawObjList.Serialize(ar);
  91. ar.Flush();
  92. ar.Close();
  93. file.Flush();
  94. file.Close();
  95. }
  96. }
  97. /************************************************************************/
  98. /* 函数:[5/9/2016 IT];
  99. /* 描述:;
  100. /* 参数:;
  101. /* [IN] :;
  102. /* [OUT] :;
  103. /* [IN/OUT] :;
  104. /* 返回:void;
  105. /* 注意:;
  106. /* 示例:;
  107. /*
  108. /* 修改:;
  109. /* 日期:;
  110. /* 内容:;
  111. /************************************************************************/
  112. CRect CGraph::Draw(IN CDC* pDC, IN CString &sOCXPath, IN int &iOcxIndex, IN BOOL bPrint /* = FALSE */)
  113. {
  114. CRect rectRet=NULL;
  115. CRect rect;
  116. // 1.判断是否打印;
  117. if ( !bPrint )
  118. {
  119. if (g_bRun)
  120. {
  121. m_pView->GetClientRect(rect);
  122. CRect tmp = CRect(CPoint(0,0),m_sizePic);;
  123. rect.UnionRect( rect, tmp );
  124. pDC->FillSolidRect(rect,m_clrBack);
  125. }
  126. else
  127. {
  128. rect = CRect(CPoint(0,0),m_sizePic);
  129. pDC->FillSolidRect(rect,m_clrBack);
  130. }
  131. }
  132. pDC->SetBkMode(TRANSPARENT);
  133. // 2.如果没运行,并且不是打印状态,则画网格;
  134. if(!CDrawObj::bRuning && !pDC->IsPrinting() && m_bGrid && (!bPrint) )
  135. {
  136. int r = (64+GetRValue(m_clrBack)) % 256;
  137. int g = (64+GetGValue(m_clrBack)) % 256;
  138. int b = (64+GetBValue(m_clrBack)) % 256;
  139. CPen pen(PS_DOT,1,RGB(r,g,b));
  140. CPen* pOldPen = pDC->SelectObject(&pen);
  141. int Width = rect.Width();
  142. int Height = rect.Height();
  143. for(int w=0;w<Width;w+=m_sizeGrid.cx)
  144. {
  145. pDC->MoveTo(rect.left + w-1, rect.top);
  146. pDC->LineTo(rect.left + w-1, rect.bottom);
  147. }
  148. for(int h=0;h<Height;h+=m_sizeGrid.cy)
  149. {
  150. pDC->MoveTo(rect.left , rect.top + h-1);
  151. pDC->LineTo(rect.right, rect.top + h-1);
  152. }
  153. pDC->SelectObject(pOldPen);
  154. DeleteObject( pen );
  155. }
  156. // 3.GetClipBox取得当前需要重绘的矩形区域;
  157. // 并据此计算需要重绘那几行;
  158. CRect rectClip;
  159. pDC->GetClipBox(&rectClip);
  160. // 4.逐个图元判断是否相交,相交则绘制出图元;
  161. POSITION pos = m_DrawObjList.GetHeadPosition();
  162. while(pos!=NULL)
  163. {
  164. CDrawObj* pObj = m_DrawObjList.GetNext(pos);
  165. CRect rect = pObj->m_rect;
  166. rect.NormalizeRect();
  167. rect.InflateRect(5,5,5,5);
  168. if(rect.IntersectRect(&rect,&rectClip))
  169. {// 图元与裁剪区相交,则图元重绘;
  170. if ( pObj->m_strCaption == _T("OCX"))
  171. {
  172. sOCXPath = ((CDrawOCX *)pObj)->m_strOcxPath;
  173. iOcxIndex = ((CDrawOCX *)pObj)->m_nOcxIndex;
  174. rectRet = pObj->m_rect;
  175. }
  176. pObj->Draw(pDC);
  177. }
  178. }
  179. // 5.编辑状态下,且不是打印状态下,画整个图元视图的边框;
  180. if (!g_bRun && (!bPrint) )
  181. {
  182. CRect rect1;
  183. CBrush brush(RGB(202,202,202));
  184. CBrush *prb;
  185. prb=pDC->SelectObject(&brush);
  186. rect1 = CRect(0,0,m_sizePic.cx,5);
  187. pDC->FillRect(&rect1,&brush);
  188. rect1 = CRect(0,0,5,m_sizePic.cy);
  189. pDC->FillRect(&rect1,&brush);
  190. rect1 = CRect(0,m_sizePic.cy,m_sizePic.cx,m_sizePic.cy-5);
  191. pDC->FillRect(&rect1,&brush);
  192. rect1 = CRect(m_sizePic.cx,0,m_sizePic.cx-5,m_sizePic.cy);
  193. pDC->FillRect(&rect1,&brush);
  194. // 画8根线
  195. CPen pen(PS_SOLID,1,RGB(232,232,232));
  196. CPen* pOldPen = pDC->SelectObject(&pen);
  197. pDC->MoveTo(1, m_sizePic.cy-1);
  198. pDC->LineTo(1, 1);
  199. pDC->LineTo(m_sizePic.cx-1, 1);
  200. CPen pen1(PS_SOLID,1,RGB(64,64,64));
  201. pDC->SelectObject(&pen1);
  202. pDC->MoveTo(1, m_sizePic.cy-1);
  203. pDC->LineTo(m_sizePic.cx, m_sizePic.cy-1);
  204. pDC->LineTo(m_sizePic.cx, 1);
  205. CPen pen2(PS_SOLID,1,RGB(242,242,242));
  206. pDC->SelectObject(&pen2);
  207. pDC->MoveTo(5, m_sizePic.cy-5);
  208. pDC->LineTo(m_sizePic.cx-4, m_sizePic.cy-5);
  209. pDC->LineTo(m_sizePic.cx-4, 5);
  210. CPen pen3(PS_SOLID,1,RGB(96,96,96));
  211. pDC->SelectObject(&pen3);
  212. pDC->MoveTo(4, m_sizePic.cy-5);
  213. pDC->LineTo(4, 4);
  214. pDC->LineTo(m_sizePic.cx-5, 4);
  215. pDC->SelectObject(pOldPen);
  216. pDC->SelectObject(prb);
  217. brush.DeleteObject();
  218. pDC->SetBkMode(OPAQUE);
  219. DeleteObject( pen );
  220. DeleteObject( pen1 );
  221. DeleteObject( pen2 );
  222. DeleteObject( pen3 );
  223. DeleteObject( brush );
  224. }
  225. return rectRet;
  226. }
  227. void CGraph::Print(CDC* pDC)
  228. {
  229. ASSERT(m_pView);
  230. CString sTemp;
  231. int nTemp=0;
  232. CSize size = m_sizePic;
  233. CClientDC dc(m_pView);
  234. CDC dcMem;
  235. dcMem.CreateCompatibleDC(&dc);
  236. CBitmap* pBitmap = new CBitmap;
  237. pBitmap->CreateCompatibleBitmap(&dc,size.cx,size.cy);
  238. CBitmap* pOldBitmap = dcMem.SelectObject(pBitmap);
  239. Draw(&dcMem,sTemp,nTemp,TRUE);
  240. dcMem.InvertRect(CRect(CPoint(0,0),m_sizePic));
  241. for(int y=0;y<size.cy;y++)
  242. {
  243. int nX1 = 0;
  244. COLORREF clrPixel = ::GetPixel(dcMem.m_hDC,0,y);
  245. int nRValue0 = GetRValue(clrPixel);
  246. int nGValue0 = GetGValue(clrPixel);
  247. int nBValue0 = GetBValue(clrPixel);
  248. int x = 0;
  249. for( x=1;x<size.cx;x++)
  250. {
  251. COLORREF clrPixel = ::GetPixel(dcMem.m_hDC,x,y);
  252. int nRValue = GetRValue(clrPixel);
  253. int nGValue = GetGValue(clrPixel);
  254. int nBValue = GetBValue(clrPixel);
  255. int nRDiff = (nRValue<nRValue0)?nRValue0-nRValue:nRValue-nRValue0;
  256. int nGDiff = (nGValue<nGValue0)?nGValue0-nGValue:nGValue-nGValue0;
  257. int nBDiff = (nBValue<nBValue0)?nBValue0-nBValue:nBValue-nBValue0;
  258. if(nRDiff+nGDiff+nBDiff>32)
  259. {
  260. RECT rect;
  261. rect.left = nX1;
  262. rect.top = y;
  263. rect.right = x;
  264. rect.bottom = y+1;
  265. ::SetBkColor(pDC->m_hDC,RGB(nRValue0,nGValue0,nBValue0));
  266. ::ExtTextOut(pDC->m_hDC,0,0,ETO_OPAQUE,&rect,NULL,0,NULL);
  267. nX1 = x;
  268. nRValue0 = nRValue;
  269. nGValue0 = nGValue;
  270. nBValue0 = nBValue;
  271. }
  272. }
  273. RECT rect;
  274. rect.left = nX1;
  275. rect.top = y;
  276. rect.right = x;
  277. rect.bottom = y+1;
  278. ::SetBkColor(pDC->m_hDC,RGB(nRValue0,nGValue0,nBValue0));
  279. ::ExtTextOut(pDC->m_hDC,0,0,ETO_OPAQUE,&rect,NULL,0,NULL);
  280. }
  281. //2011-11-01 add
  282. DeleteObject( pBitmap );
  283. dcMem.SelectObject(pOldBitmap);
  284. dcMem.DeleteDC( );
  285. delete pBitmap;
  286. }
  287. void CGraph::Fresh(void)
  288. {
  289. #if 0
  290. if(!m_DrawObjList.IsEmpty())
  291. {
  292. CRect rect;
  293. for(POSITION pos = m_DrawObjList.GetHeadPosition();pos!=NULL;)
  294. {
  295. POSITION pos1 = pos ; //要在这里做一个备份
  296. if( (int)pos1 == 0xfeeefeee ) break; // 频繁单击画面会出现异常,暂时不知道什么解决
  297. CDrawObj* pObj = m_DrawObjList.GetAt(pos1);
  298. if( (int)pObj == 0xcdcdcdcd || (int)pObj == 0xfeeefeee || (int)pObj == 0x00000001 ) break; // 频繁单击画面会出现异常,暂时不知道什么解决
  299. if( (int)pObj->m_pView == 0xfeeefeee || (int)pObj->m_pView == 0x00000001 ) // 频繁单击画面会出现异常,暂时不知道什么解决
  300. {
  301. TRACE(g_strTRACE0);
  302. break;
  303. }
  304. if( pObj->Fresh(rect) )
  305. InvalidateRect( pObj->m_pView->GetSafeHwnd(),rect,true );
  306. m_DrawObjList.GetNext(pos);//他会改变 pos的值
  307. }
  308. }
  309. #else
  310. CRect rect;
  311. CDrawObj* pObj = NULL;
  312. POSITION pos = m_DrawObjList.GetHeadPosition();
  313. while( pos != NULL)
  314. {
  315. pObj = m_DrawObjList.GetNext(pos);
  316. if ( pObj->Fresh(rect) )
  317. InvalidateRect( pObj->m_pView->GetSafeHwnd(), rect, true);
  318. }
  319. #endif
  320. }