// 这段 MFC 示例源代码演示如何使用 MFC Microsoft Office Fluent 用户界面 // (“Fluent UI”)。该示例仅供参考, // 用以补充《Microsoft 基础类参考》和 // MFC C++ 库软件随附的相关电子文档。 // 复制、使用或分发 Fluent UI 的许可条款是单独提供的。 // 若要了解有关 Fluent UI 许可计划的详细信息,请访问 // https://go.microsoft.com/fwlink/?LinkId=238214. // // 版权所有(C) Microsoft Corporation // 保留所有权利。 // IDEView.cpp: CIDEView 类的实现 // #include "stdafx.h" // SHARED_HANDLERS 可以在实现预览、缩略图和搜索筛选器句柄的 // ATL 项目中进行定义,并允许与该项目共享文档代码。 #ifndef SHARED_HANDLERS #include "IDE.h" #endif #include "IDEDoc.h" #include "IDEView.h" #ifdef _DEBUG #define new DEBUG_NEW #endif // CIDEView IMPLEMENT_DYNCREATE(CIDEView, CScrollView) BEGIN_MESSAGE_MAP(CIDEView, CScrollView) // 标准打印命令 ON_COMMAND(ID_FILE_PRINT, &CScrollView::OnFilePrint) ON_COMMAND(ID_FILE_PRINT_DIRECT, &CScrollView::OnFilePrint) ON_COMMAND(ID_FILE_PRINT_PREVIEW, &CIDEView::OnFilePrintPreview) ON_WM_CONTEXTMENU() ON_WM_RBUTTONUP() END_MESSAGE_MAP() // CIDEView 构造/析构 CIDEView::CIDEView() noexcept { // TODO: 在此处添加构造代码 } CIDEView::~CIDEView() { } BOOL CIDEView::PreCreateWindow(CREATESTRUCT& cs) { // TODO: 在此处通过修改 // CREATESTRUCT cs 来修改窗口类或样式 return CScrollView::PreCreateWindow(cs); } // CIDEView 绘图 void CIDEView::OnDraw(CDC* pDC) { CIDEDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); if (!pDoc) return; if (m_img.data != NULL) DrawImage(m_img, pDC); //DrawGrid(pDC); // TODO: 在此处为本机数据添加绘制代码 } void CIDEView::DrawMat(Mat & img, CDC *pDC) { if (img.data == NULL) return; CRect rc; Mat imgTmp; // 获取控件大小; GetClientRect(rc); // 按控件大小,缩小或放大图片; cv::resize(img, imgTmp, cv::Size(rc.Width(), rc.Height())); //img.copyTo(imgTmp); // 转换格式; switch (imgTmp.channels()) { case 1: cv::cvtColor(imgTmp, imgTmp, COLOR_GRAY2BGRA); break; case 3: cv::cvtColor(imgTmp, imgTmp, COLOR_BGR2BGRA); break; default: break; } int pixelBytes = imgTmp.channels()*(imgTmp.depth() + 1); // 计算一个像素多少个字节 // 制作bitmapinfo(数据头); BITMAPINFO bitInfo; bitInfo.bmiHeader.biBitCount = 8 * pixelBytes; bitInfo.bmiHeader.biWidth = imgTmp.cols; bitInfo.bmiHeader.biHeight = -imgTmp.rows; bitInfo.bmiHeader.biPlanes = 1; bitInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); bitInfo.bmiHeader.biCompression = BI_RGB; bitInfo.bmiHeader.biClrImportant = 0; bitInfo.bmiHeader.biClrUsed = 0; bitInfo.bmiHeader.biSizeImage = 0; bitInfo.bmiHeader.biXPelsPerMeter = 0; bitInfo.bmiHeader.biYPelsPerMeter = 0; // 双缓存; CDC MemDC; //首先定义一个显示设备对象 CBitmap MemBitmap;//定义一个位图对象 //随后建立与屏幕显示兼容的内存显示设备 MemDC.CreateCompatibleDC(NULL); //这时还不能绘图,因为没有地方画 ^_^ //下面建立一个与屏幕显示兼容的位图,至于位图的大小嘛,可以用窗口的大小 MemBitmap.CreateCompatibleBitmap(pDC, rc.Width(), rc.Height()); //将位图选入到内存显示设备中 //只有选入了位图的内存显示设备才有地方绘图,画到指定的位图上 CBitmap *pOldBit = MemDC.SelectObject(&MemBitmap); //先用背景色将位图清除干净,这里我用的是白色作为背景 //你也可以用自己应该用的颜色 MemDC.FillSolidRect(0, 0, rc.Width(), rc.Height(), RGB(255, 255, 255)); // Mat.data + bitmap数据头 -> MFC int nRet = ::StretchDIBits( MemDC, 0, 0, rc.Width(), rc.Height(), 0, 0, rc.Width(), rc.Height(), imgTmp.data, &bitInfo, DIB_RGB_COLORS, SRCCOPY ); //将内存中的图拷贝到屏幕上进行显示 pDC->BitBlt(0, 0, rc.Width(), rc.Height(), &MemDC, 0, 0, SRCCOPY); //绘图完成后的清理 MemBitmap.DeleteObject(); MemDC.DeleteDC(); } void CIDEView::DrawGrid(CDC * pDC) { // 获取客户区域; CRect rect; GetClientRect(&rect); // 备份北背色; COLORREF oldBkColor = pDC->GetBkColor(); COLORREF gridColor = RGB(200,200,200); // Center lines CPen penDash; penDash.CreatePen(PS_DASH, 1, gridColor); CPen* pOldPen = pDC->SelectObject(&penDash); pDC->MoveTo(0, rect.top); pDC->LineTo(0, rect.bottom); pDC->MoveTo(rect.left, 0); pDC->LineTo(rect.right, 0); // Major unit lines CPen penDot; penDot.CreatePen(PS_DOT, 1, gridColor); pDC->SelectObject(&penDot); //for (int x = rect.left / 100 * 100; x < rect.right; x += 100) for (int x = rect.left / 50 * 50; x < rect.right; x += 50) { if (x != 0) { pDC->MoveTo(x, rect.top); pDC->LineTo(x, rect.bottom); } } //for (int y = rect.top / 100 * 100; y < rect.bottom; y += 100) for (int y = rect.top / 50 * 50; y < rect.bottom; y += 50) { if (y != 0) { pDC->MoveTo(rect.left, y); pDC->LineTo(rect.right, y); } } // Outlines CPen penSolid; penSolid.CreatePen(PS_SOLID, 1, gridColor); pDC->SelectObject(&penSolid); pDC->MoveTo(rect.left, rect.top); pDC->LineTo(rect.right, rect.top); pDC->LineTo(rect.right, rect.bottom); pDC->LineTo(rect.left, rect.bottom); pDC->LineTo(rect.left, rect.top); pDC->SelectObject(pOldPen); pDC->SetBkColor(oldBkColor); } void CIDEView::DrawImage(Mat & img, CDC * pDC) { if (img.data == NULL) return; CRect rc; Mat imgTmp; // 获取控件大小; GetClientRect(rc); // 按控件大小,缩小或放大图片; //cv::resize(img, imgTmp, cv::Size(rc.Width(), rc.Height())); img.copyTo(imgTmp); // 转换格式; switch (imgTmp.channels()) { case 1: cv::cvtColor(imgTmp, imgTmp, COLOR_GRAY2BGRA); break; case 3: cv::cvtColor(imgTmp, imgTmp, COLOR_BGR2BGRA); break; default: break; } // gdi+双缓存; #if 1 Bitmap bmp(imgTmp.cols, imgTmp.rows, imgTmp.step1(), PixelFormat32bppARGB, imgTmp.data); Graphics bmpGraphics(&bmp); bmpGraphics.SetSmoothingMode(SmoothingModeAntiAlias); // 画布颜色; //SolidBrush bkBrush(Color(0, 0, 0)); //bmpGraphics.FillRectangle(&bkBrush, 0, 0, rc.Width(), rc.Height()); // 在DC上画; Graphics graphDC(pDC->GetSafeHdc()); CachedBitmap cachedBmp(&bmp, &graphDC); graphDC.DrawCachedBitmap(&cachedBmp, 0, 0); #else Graphics graphDC(pDC->GetSafeHdc()); Gdiplus::Bitmap bitmap(imgTmp.cols, imgTmp.rows, imgTmp.step1(), PixelFormat32bppARGB, imgTmp.data); graphDC.DrawImage(&bitmap, Gdiplus::Rect(rc.left, rc.top, rc.Width(), rc.Height())); #endif } void CIDEView::OnInitialUpdate() { CScrollView::OnInitialUpdate(); m_img = imread(_T("IDE.png"), IMREAD_COLOR); // 设置滚动条出现时的范围; CSize sizeTotal = CSize(m_img.cols, m_img.rows); //sizeTotal.cx = sizeTotal.cy = 100; //CSize sizePage = CSize(m_img.cols, m_img.rows); CSize sizePage = CSize(200, 200); CSize sizeLine = CSize(10, 10); SetScrollSizes(MM_TEXT, sizeTotal, sizePage, sizeLine);//单伴:MM_TEXT像素; } // CIDEView 打印 void CIDEView::OnFilePrintPreview() { #ifndef SHARED_HANDLERS AFXPrintPreview(this); #endif } BOOL CIDEView::OnPreparePrinting(CPrintInfo* pInfo) { // 默认准备 return DoPreparePrinting(pInfo); } void CIDEView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/) { // TODO: 添加额外的打印前进行的初始化过程 } void CIDEView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/) { // TODO: 添加打印后进行的清理过程 } void CIDEView::OnRButtonUp(UINT /* nFlags */, CPoint point) { ClientToScreen(&point); OnContextMenu(this, point); } void CIDEView::OnContextMenu(CWnd* /* pWnd */, CPoint point) { #ifndef SHARED_HANDLERS theApp.GetContextMenuManager()->ShowPopupMenu(IDR_POPUP_EDIT, point.x, point.y, this, TRUE); #endif } // CIDEView 诊断 #ifdef _DEBUG void CIDEView::AssertValid() const { CScrollView::AssertValid(); } void CIDEView::Dump(CDumpContext& dc) const { CScrollView::Dump(dc); } CIDEDoc* CIDEView::GetDocument() const // 非调试版本是内联的 { ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CIDEDoc))); return (CIDEDoc*)m_pDocument; } #endif //_DEBUG // CIDEView 消息处理程序 void CIDEView::OnPrepareDC(CDC* pDC, CPrintInfo* pInfo) { // TODO: 在此添加专用代码和/或调用基类 CScrollView::OnPrepareDC(pDC, pInfo); // mapping mode is MM_ANISOTROPIC // these extents setup a mode similar to MM_LOENGLISH // MM_LOENGLISH is in .01 physical inches // these extents provide .01 logical inches #if 0 pDC->SetMapMode(MM_ANISOTROPIC); pDC->SetViewportExt(pDC->GetDeviceCaps(LOGPIXELSX), pDC->GetDeviceCaps(LOGPIXELSY)); pDC->SetWindowExt(100, -100); // set the origin of the coordinate system to the center of the page CPoint ptOrg; ptOrg.x = GetDocument()->GetSize().cx / 2; ptOrg.y = GetDocument()->GetSize().cy / 2; // ptOrg is in logical coordinates pDC->OffsetWindowOrg(-ptOrg.x, ptOrg.y); #endif }