Graph.cpp 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352
  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. rectRet = pObj->m_rect;
  173. }
  174. pObj->Draw(pDC);
  175. }
  176. }
  177. // 5.编辑状态下,且不是打印状态下,画整个图元视图的边框;
  178. if (!g_bRun && (!bPrint) )
  179. {
  180. CRect rect1;
  181. CBrush brush(RGB(202,202,202));
  182. CBrush *prb;
  183. prb=pDC->SelectObject(&brush);
  184. rect1 = CRect(0,0,m_sizePic.cx,5);
  185. pDC->FillRect(&rect1,&brush);
  186. rect1 = CRect(0,0,5,m_sizePic.cy);
  187. pDC->FillRect(&rect1,&brush);
  188. rect1 = CRect(0,m_sizePic.cy,m_sizePic.cx,m_sizePic.cy-5);
  189. pDC->FillRect(&rect1,&brush);
  190. rect1 = CRect(m_sizePic.cx,0,m_sizePic.cx-5,m_sizePic.cy);
  191. pDC->FillRect(&rect1,&brush);
  192. // 画8根线
  193. CPen pen(PS_SOLID,1,RGB(232,232,232));
  194. CPen* pOldPen = pDC->SelectObject(&pen);
  195. pDC->MoveTo(1, m_sizePic.cy-1);
  196. pDC->LineTo(1, 1);
  197. pDC->LineTo(m_sizePic.cx-1, 1);
  198. CPen pen1(PS_SOLID,1,RGB(64,64,64));
  199. pDC->SelectObject(&pen1);
  200. pDC->MoveTo(1, m_sizePic.cy-1);
  201. pDC->LineTo(m_sizePic.cx, m_sizePic.cy-1);
  202. pDC->LineTo(m_sizePic.cx, 1);
  203. CPen pen2(PS_SOLID,1,RGB(242,242,242));
  204. pDC->SelectObject(&pen2);
  205. pDC->MoveTo(5, m_sizePic.cy-5);
  206. pDC->LineTo(m_sizePic.cx-4, m_sizePic.cy-5);
  207. pDC->LineTo(m_sizePic.cx-4, 5);
  208. CPen pen3(PS_SOLID,1,RGB(96,96,96));
  209. pDC->SelectObject(&pen3);
  210. pDC->MoveTo(4, m_sizePic.cy-5);
  211. pDC->LineTo(4, 4);
  212. pDC->LineTo(m_sizePic.cx-5, 4);
  213. pDC->SelectObject(pOldPen);
  214. pDC->SelectObject(prb);
  215. brush.DeleteObject();
  216. pDC->SetBkMode(OPAQUE);
  217. DeleteObject( pen );
  218. DeleteObject( pen1 );
  219. DeleteObject( pen2 );
  220. DeleteObject( pen3 );
  221. DeleteObject( brush );
  222. }
  223. return rectRet;
  224. }
  225. void CGraph::Print(CDC* pDC)
  226. {
  227. ASSERT(m_pView);
  228. CString sTemp;
  229. int nTemp=0;
  230. CSize size = m_sizePic;
  231. CClientDC dc(m_pView);
  232. CDC dcMem;
  233. dcMem.CreateCompatibleDC(&dc);
  234. CBitmap* pBitmap = new CBitmap;
  235. pBitmap->CreateCompatibleBitmap(&dc,size.cx,size.cy);
  236. CBitmap* pOldBitmap = dcMem.SelectObject(pBitmap);
  237. Draw(&dcMem,sTemp,nTemp,TRUE);
  238. dcMem.InvertRect(CRect(CPoint(0,0),m_sizePic));
  239. for(int y=0;y<size.cy;y++)
  240. {
  241. int nX1 = 0;
  242. COLORREF clrPixel = ::GetPixel(dcMem.m_hDC,0,y);
  243. int nRValue0 = GetRValue(clrPixel);
  244. int nGValue0 = GetGValue(clrPixel);
  245. int nBValue0 = GetBValue(clrPixel);
  246. int x = 0;
  247. for( x=1;x<size.cx;x++)
  248. {
  249. COLORREF clrPixel = ::GetPixel(dcMem.m_hDC,x,y);
  250. int nRValue = GetRValue(clrPixel);
  251. int nGValue = GetGValue(clrPixel);
  252. int nBValue = GetBValue(clrPixel);
  253. int nRDiff = (nRValue<nRValue0)?nRValue0-nRValue:nRValue-nRValue0;
  254. int nGDiff = (nGValue<nGValue0)?nGValue0-nGValue:nGValue-nGValue0;
  255. int nBDiff = (nBValue<nBValue0)?nBValue0-nBValue:nBValue-nBValue0;
  256. if(nRDiff+nGDiff+nBDiff>32)
  257. {
  258. RECT rect;
  259. rect.left = nX1;
  260. rect.top = y;
  261. rect.right = x;
  262. rect.bottom = y+1;
  263. ::SetBkColor(pDC->m_hDC,RGB(nRValue0,nGValue0,nBValue0));
  264. ::ExtTextOut(pDC->m_hDC,0,0,ETO_OPAQUE,&rect,NULL,0,NULL);
  265. nX1 = x;
  266. nRValue0 = nRValue;
  267. nGValue0 = nGValue;
  268. nBValue0 = nBValue;
  269. }
  270. }
  271. RECT rect;
  272. rect.left = nX1;
  273. rect.top = y;
  274. rect.right = x;
  275. rect.bottom = y+1;
  276. ::SetBkColor(pDC->m_hDC,RGB(nRValue0,nGValue0,nBValue0));
  277. ::ExtTextOut(pDC->m_hDC,0,0,ETO_OPAQUE,&rect,NULL,0,NULL);
  278. }
  279. //2011-11-01 add
  280. DeleteObject( pBitmap );
  281. dcMem.SelectObject(pOldBitmap);
  282. dcMem.DeleteDC( );
  283. delete pBitmap;
  284. }
  285. void CGraph::Fresh(void)
  286. {
  287. #if 0
  288. if(!m_DrawObjList.IsEmpty())
  289. {
  290. CRect rect;
  291. for(POSITION pos = m_DrawObjList.GetHeadPosition();pos!=NULL;)
  292. {
  293. POSITION pos1 = pos ; //要在这里做一个备份
  294. if( (int)pos1 == 0xfeeefeee ) break; // 频繁单击画面会出现异常,暂时不知道什么解决
  295. CDrawObj* pObj = m_DrawObjList.GetAt(pos1);
  296. if( (int)pObj == 0xcdcdcdcd || (int)pObj == 0xfeeefeee || (int)pObj == 0x00000001 ) break; // 频繁单击画面会出现异常,暂时不知道什么解决
  297. if( (int)pObj->m_pView == 0xfeeefeee || (int)pObj->m_pView == 0x00000001 ) // 频繁单击画面会出现异常,暂时不知道什么解决
  298. {
  299. TRACE(g_strTRACE0);
  300. break;
  301. }
  302. if( pObj->Fresh(rect) )
  303. InvalidateRect( pObj->m_pView->GetSafeHwnd(),rect,true );
  304. m_DrawObjList.GetNext(pos);//他会改变 pos的值
  305. }
  306. }
  307. #else
  308. CRect rect;
  309. CDrawObj* pObj = NULL;
  310. POSITION pos = m_DrawObjList.GetHeadPosition();
  311. while( pos != NULL)
  312. {
  313. pObj = m_DrawObjList.GetNext(pos);
  314. if ( pObj->Fresh(rect) )
  315. InvalidateRect( pObj->m_pView->GetSafeHwnd(), rect, true);
  316. }
  317. #endif
  318. }