IDEView.cpp 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364
  1. // 这段 MFC 示例源代码演示如何使用 MFC Microsoft Office Fluent 用户界面
  2. // (“Fluent UI”)。该示例仅供参考,
  3. // 用以补充《Microsoft 基础类参考》和
  4. // MFC C++ 库软件随附的相关电子文档。
  5. // 复制、使用或分发 Fluent UI 的许可条款是单独提供的。
  6. // 若要了解有关 Fluent UI 许可计划的详细信息,请访问
  7. // https://go.microsoft.com/fwlink/?LinkId=238214.
  8. //
  9. // 版权所有(C) Microsoft Corporation
  10. // 保留所有权利。
  11. // IDEView.cpp: CIDEView 类的实现
  12. //
  13. #include "stdafx.h"
  14. // SHARED_HANDLERS 可以在实现预览、缩略图和搜索筛选器句柄的
  15. // ATL 项目中进行定义,并允许与该项目共享文档代码。
  16. #ifndef SHARED_HANDLERS
  17. #include "IDE.h"
  18. #endif
  19. #include "IDEDoc.h"
  20. #include "IDEView.h"
  21. #ifdef _DEBUG
  22. #define new DEBUG_NEW
  23. #endif
  24. // CIDEView
  25. IMPLEMENT_DYNCREATE(CIDEView, CScrollView)
  26. BEGIN_MESSAGE_MAP(CIDEView, CScrollView)
  27. // 标准打印命令
  28. ON_COMMAND(ID_FILE_PRINT, &CScrollView::OnFilePrint)
  29. ON_COMMAND(ID_FILE_PRINT_DIRECT, &CScrollView::OnFilePrint)
  30. ON_COMMAND(ID_FILE_PRINT_PREVIEW, &CIDEView::OnFilePrintPreview)
  31. ON_WM_CONTEXTMENU()
  32. ON_WM_RBUTTONUP()
  33. END_MESSAGE_MAP()
  34. // CIDEView 构造/析构
  35. CIDEView::CIDEView() noexcept
  36. {
  37. // TODO: 在此处添加构造代码
  38. }
  39. CIDEView::~CIDEView()
  40. {
  41. }
  42. BOOL CIDEView::PreCreateWindow(CREATESTRUCT& cs)
  43. {
  44. // TODO: 在此处通过修改
  45. // CREATESTRUCT cs 来修改窗口类或样式
  46. return CScrollView::PreCreateWindow(cs);
  47. }
  48. // CIDEView 绘图
  49. void CIDEView::OnDraw(CDC* pDC)
  50. {
  51. CIDEDoc* pDoc = GetDocument();
  52. ASSERT_VALID(pDoc);
  53. if (!pDoc)
  54. return;
  55. if (m_img.data != NULL)
  56. DrawImage(m_img, pDC);
  57. //DrawGrid(pDC);
  58. // TODO: 在此处为本机数据添加绘制代码
  59. }
  60. void CIDEView::DrawMat(Mat & img, CDC *pDC)
  61. {
  62. if (img.data == NULL)
  63. return;
  64. CRect rc;
  65. Mat imgTmp;
  66. // 获取控件大小;
  67. GetClientRect(rc);
  68. // 按控件大小,缩小或放大图片;
  69. cv::resize(img, imgTmp, cv::Size(rc.Width(), rc.Height()));
  70. //img.copyTo(imgTmp);
  71. // 转换格式;
  72. switch (imgTmp.channels())
  73. {
  74. case 1:
  75. cv::cvtColor(imgTmp, imgTmp, COLOR_GRAY2BGRA);
  76. break;
  77. case 3:
  78. cv::cvtColor(imgTmp, imgTmp, COLOR_BGR2BGRA);
  79. break;
  80. default:
  81. break;
  82. }
  83. int pixelBytes = imgTmp.channels()*(imgTmp.depth() + 1); // 计算一个像素多少个字节
  84. // 制作bitmapinfo(数据头);
  85. BITMAPINFO bitInfo;
  86. bitInfo.bmiHeader.biBitCount = 8 * pixelBytes;
  87. bitInfo.bmiHeader.biWidth = imgTmp.cols;
  88. bitInfo.bmiHeader.biHeight = -imgTmp.rows;
  89. bitInfo.bmiHeader.biPlanes = 1;
  90. bitInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
  91. bitInfo.bmiHeader.biCompression = BI_RGB;
  92. bitInfo.bmiHeader.biClrImportant = 0;
  93. bitInfo.bmiHeader.biClrUsed = 0;
  94. bitInfo.bmiHeader.biSizeImage = 0;
  95. bitInfo.bmiHeader.biXPelsPerMeter = 0;
  96. bitInfo.bmiHeader.biYPelsPerMeter = 0;
  97. // 双缓存;
  98. CDC MemDC; //首先定义一个显示设备对象
  99. CBitmap MemBitmap;//定义一个位图对象
  100. //随后建立与屏幕显示兼容的内存显示设备
  101. MemDC.CreateCompatibleDC(NULL);
  102. //这时还不能绘图,因为没有地方画 ^_^
  103. //下面建立一个与屏幕显示兼容的位图,至于位图的大小嘛,可以用窗口的大小
  104. MemBitmap.CreateCompatibleBitmap(pDC, rc.Width(), rc.Height());
  105. //将位图选入到内存显示设备中
  106. //只有选入了位图的内存显示设备才有地方绘图,画到指定的位图上
  107. CBitmap *pOldBit = MemDC.SelectObject(&MemBitmap);
  108. //先用背景色将位图清除干净,这里我用的是白色作为背景
  109. //你也可以用自己应该用的颜色
  110. MemDC.FillSolidRect(0, 0, rc.Width(), rc.Height(), RGB(255, 255, 255));
  111. // Mat.data + bitmap数据头 -> MFC
  112. int nRet = ::StretchDIBits(
  113. MemDC,
  114. 0, 0, rc.Width(), rc.Height(),
  115. 0, 0, rc.Width(), rc.Height(),
  116. imgTmp.data,
  117. &bitInfo,
  118. DIB_RGB_COLORS,
  119. SRCCOPY
  120. );
  121. //将内存中的图拷贝到屏幕上进行显示
  122. pDC->BitBlt(0, 0, rc.Width(), rc.Height(), &MemDC, 0, 0, SRCCOPY);
  123. //绘图完成后的清理
  124. MemBitmap.DeleteObject();
  125. MemDC.DeleteDC();
  126. }
  127. void CIDEView::DrawGrid(CDC * pDC)
  128. {
  129. // 获取客户区域;
  130. CRect rect;
  131. GetClientRect(&rect);
  132. // 备份北背色;
  133. COLORREF oldBkColor = pDC->GetBkColor();
  134. COLORREF gridColor = RGB(200,200,200);
  135. // Center lines
  136. CPen penDash;
  137. penDash.CreatePen(PS_DASH, 1, gridColor);
  138. CPen* pOldPen = pDC->SelectObject(&penDash);
  139. pDC->MoveTo(0, rect.top);
  140. pDC->LineTo(0, rect.bottom);
  141. pDC->MoveTo(rect.left, 0);
  142. pDC->LineTo(rect.right, 0);
  143. // Major unit lines
  144. CPen penDot;
  145. penDot.CreatePen(PS_DOT, 1, gridColor);
  146. pDC->SelectObject(&penDot);
  147. //for (int x = rect.left / 100 * 100; x < rect.right; x += 100)
  148. for (int x = rect.left / 50 * 50; x < rect.right; x += 50)
  149. {
  150. if (x != 0)
  151. {
  152. pDC->MoveTo(x, rect.top);
  153. pDC->LineTo(x, rect.bottom);
  154. }
  155. }
  156. //for (int y = rect.top / 100 * 100; y < rect.bottom; y += 100)
  157. for (int y = rect.top / 50 * 50; y < rect.bottom; y += 50)
  158. {
  159. if (y != 0)
  160. {
  161. pDC->MoveTo(rect.left, y);
  162. pDC->LineTo(rect.right, y);
  163. }
  164. }
  165. // Outlines
  166. CPen penSolid;
  167. penSolid.CreatePen(PS_SOLID, 1, gridColor);
  168. pDC->SelectObject(&penSolid);
  169. pDC->MoveTo(rect.left, rect.top);
  170. pDC->LineTo(rect.right, rect.top);
  171. pDC->LineTo(rect.right, rect.bottom);
  172. pDC->LineTo(rect.left, rect.bottom);
  173. pDC->LineTo(rect.left, rect.top);
  174. pDC->SelectObject(pOldPen);
  175. pDC->SetBkColor(oldBkColor);
  176. }
  177. void CIDEView::DrawImage(Mat & img, CDC * pDC)
  178. {
  179. if (img.data == NULL)
  180. return;
  181. CRect rc;
  182. Mat imgTmp;
  183. // 获取控件大小;
  184. GetClientRect(rc);
  185. // 按控件大小,缩小或放大图片;
  186. //cv::resize(img, imgTmp, cv::Size(rc.Width(), rc.Height()));
  187. img.copyTo(imgTmp);
  188. // 转换格式;
  189. switch (imgTmp.channels())
  190. {
  191. case 1:
  192. cv::cvtColor(imgTmp, imgTmp, COLOR_GRAY2BGRA);
  193. break;
  194. case 3:
  195. cv::cvtColor(imgTmp, imgTmp, COLOR_BGR2BGRA);
  196. break;
  197. default:
  198. break;
  199. }
  200. // gdi+双缓存;
  201. #if 1
  202. Bitmap bmp(imgTmp.cols, imgTmp.rows, imgTmp.step1(), PixelFormat32bppARGB, imgTmp.data);
  203. Graphics bmpGraphics(&bmp);
  204. bmpGraphics.SetSmoothingMode(SmoothingModeAntiAlias);
  205. // 画布颜色;
  206. //SolidBrush bkBrush(Color(0, 0, 0));
  207. //bmpGraphics.FillRectangle(&bkBrush, 0, 0, rc.Width(), rc.Height());
  208. // 在DC上画;
  209. Graphics graphDC(pDC->GetSafeHdc());
  210. CachedBitmap cachedBmp(&bmp, &graphDC);
  211. graphDC.DrawCachedBitmap(&cachedBmp, 0, 0);
  212. #else
  213. Graphics graphDC(pDC->GetSafeHdc());
  214. Gdiplus::Bitmap bitmap(imgTmp.cols, imgTmp.rows, imgTmp.step1(), PixelFormat32bppARGB, imgTmp.data);
  215. graphDC.DrawImage(&bitmap, Gdiplus::Rect(rc.left, rc.top, rc.Width(), rc.Height()));
  216. #endif
  217. }
  218. void CIDEView::OnInitialUpdate()
  219. {
  220. CScrollView::OnInitialUpdate();
  221. m_img = imread(_T("IDE.png"), IMREAD_COLOR);
  222. // 设置滚动条出现时的范围;
  223. CSize sizeTotal = CSize(m_img.cols, m_img.rows);
  224. //sizeTotal.cx = sizeTotal.cy = 100;
  225. //CSize sizePage = CSize(m_img.cols, m_img.rows);
  226. CSize sizePage = CSize(200, 200);
  227. CSize sizeLine = CSize(10, 10);
  228. SetScrollSizes(MM_TEXT, sizeTotal, sizePage, sizeLine);//单伴:MM_TEXT像素;
  229. }
  230. // CIDEView 打印
  231. void CIDEView::OnFilePrintPreview()
  232. {
  233. #ifndef SHARED_HANDLERS
  234. AFXPrintPreview(this);
  235. #endif
  236. }
  237. BOOL CIDEView::OnPreparePrinting(CPrintInfo* pInfo)
  238. {
  239. // 默认准备
  240. return DoPreparePrinting(pInfo);
  241. }
  242. void CIDEView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
  243. {
  244. // TODO: 添加额外的打印前进行的初始化过程
  245. }
  246. void CIDEView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
  247. {
  248. // TODO: 添加打印后进行的清理过程
  249. }
  250. void CIDEView::OnRButtonUp(UINT /* nFlags */, CPoint point)
  251. {
  252. ClientToScreen(&point);
  253. OnContextMenu(this, point);
  254. }
  255. void CIDEView::OnContextMenu(CWnd* /* pWnd */, CPoint point)
  256. {
  257. #ifndef SHARED_HANDLERS
  258. theApp.GetContextMenuManager()->ShowPopupMenu(IDR_POPUP_EDIT, point.x, point.y, this, TRUE);
  259. #endif
  260. }
  261. // CIDEView 诊断
  262. #ifdef _DEBUG
  263. void CIDEView::AssertValid() const
  264. {
  265. CScrollView::AssertValid();
  266. }
  267. void CIDEView::Dump(CDumpContext& dc) const
  268. {
  269. CScrollView::Dump(dc);
  270. }
  271. CIDEDoc* CIDEView::GetDocument() const // 非调试版本是内联的
  272. {
  273. ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CIDEDoc)));
  274. return (CIDEDoc*)m_pDocument;
  275. }
  276. #endif //_DEBUG
  277. // CIDEView 消息处理程序
  278. void CIDEView::OnPrepareDC(CDC* pDC, CPrintInfo* pInfo)
  279. {
  280. // TODO: 在此添加专用代码和/或调用基类
  281. CScrollView::OnPrepareDC(pDC, pInfo);
  282. // mapping mode is MM_ANISOTROPIC
  283. // these extents setup a mode similar to MM_LOENGLISH
  284. // MM_LOENGLISH is in .01 physical inches
  285. // these extents provide .01 logical inches
  286. #if 0
  287. pDC->SetMapMode(MM_ANISOTROPIC);
  288. pDC->SetViewportExt(pDC->GetDeviceCaps(LOGPIXELSX),
  289. pDC->GetDeviceCaps(LOGPIXELSY));
  290. pDC->SetWindowExt(100, -100);
  291. // set the origin of the coordinate system to the center of the page
  292. CPoint ptOrg;
  293. ptOrg.x = GetDocument()->GetSize().cx / 2;
  294. ptOrg.y = GetDocument()->GetSize().cy / 2;
  295. // ptOrg is in logical coordinates
  296. pDC->OffsetWindowOrg(-ptOrg.x, ptOrg.y);
  297. #endif
  298. }