绘制直线、矩阵——MFC基于单文档的应用(1)

准备:确定自己已经在Vs上安装好了MFC的配件:

(最后的连接错误让我很难受~~~~~)

 

首先是创建单文档的MFC程序应用。(这里MFC应用命名为:OOPEx)

前提工作:

在类视图中,找到:程序名+View类(这里为COOPExView[也被称为CView])

右键给该类添加一个CPoint m_point变量(获取点击的点的位置)

然后继续在该类点击,右键--->类向导中为该类添加左键点击函数(WM_LBUTTONDOWN)和左键释放函数(WM_LBUTTONUP),还有光标移动消息函数(WM_MOUSEMOVE)

(一定要点击第二步添加,直接确定是没有添加响应函数的~~~~)

好了,函数添加完后,就是响应函数的代码了,~~~~~

壹:直线绘制的四种方法:

一、API函数方式添加

void COOPExView::OnLButtonDown(UINT nFlags, CPoint point)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	m_point = point;//保存点的位置
	CView::OnLButtonDown(nFlags, point);
}


void COOPExView::OnLButtonUp(UINT nFlags, CPoint point)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	HDC hdc;
	hdc = ::GetDC(m_hWnd);//移动到线条的起始位置
	MoveToEx(hdc, m_point.x, m_point.y, NULL);//画线
	LineTo(hdc, point.x, point.y);
	::ReleaseDC(m_hWnd, hdc);
	CView::OnLButtonUp(nFlags, point);
}

二、MFC绘制(CDC类)

void COOPExView::OnLButtonDown(UINT nFlags, CPoint point)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	m_point = point;
	CView::OnLButtonDown(nFlags, point);
}


void COOPExView::OnLButtonUp(UINT nFlags, CPoint point)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	CDC *pDC = GetDC();//CDC类中的GetDC()正好返回了一个CDC类的对象指针
	pDC->MoveTo(m_point);//利用CDC的成员函数画线
	pDC->LineTo(point);
	ReleaseDC(pDC);//牢记的是,在这里我们依然不要忘记释放DC
	CView::OnLButtonUp(nFlags, point);
}

三、CClientDC类绘制

void COOPExView::OnLButtonDown(UINT nFlags, CPoint point)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	m_point = point;//保存点的位置
	CView::OnLButtonDown(nFlags, point);
}


void COOPExView::OnLButtonUp(UINT nFlags, CPoint point)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	//CClientDC dc(GetDesktopWindow());//整个屏幕,NULL也可以
	//CClientDC dc(GetParent());//获取父类的窗口句柄,也就是CMainFrame的窗口句柄,在父类的客户区内画线
	CClientDC dc(this);
	dc.MoveTo(m_point);  //CClientDC类型的变量dc是一个对象,采用点操作符来调用该对象的函数
	dc.LineTo(point);
	CView::OnLButtonUp(nFlags, point);
}

四、CWindowDC类绘制

void COOPExView::OnLButtonDown(UINT nFlags, CPoint point)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	m_point = point;//保存点的位置
	CView::OnLButtonDown(nFlags, point);
}


void COOPExView::OnLButtonUp(UINT nFlags, CPoint point)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	//CWindowDC dc(GetDesktopWindow());//整个屏幕,NULL也可以
	//CWindowDC dc(GetParent());//获取父类的窗口句柄,也就是CMainFrame的窗口句柄,在父类的客户区内画线
	CWindowDC dc(this); //视图客户区内作图,结束时会自释放DC
	dc.MoveTo(m_point);
	dc.LineTo(point);
//CWindowDC类是从CDC继承的。它在构造的时候调用Windows函数GetWindowDC,在销毁的时候调用ReleaseDC。
	CView::OnLButtonUp(nFlags, point);
}

 

 

贰:绘制红色实线:

void COOPExView::OnLButtonDown(UINT nFlags, CPoint point)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	m_point = point;//保存点的位置
	CView::OnLButtonDown(nFlags, point);
}


void COOPExView::OnLButtonUp(UINT nFlags, CPoint point)
{
	CPen pen(PS_SOLID, 5, RGB(255, 0, 0));//中间的数字可以调整画笔大小
	CClientDC dc(this);
	CPen *pOldPen = dc.SelectObject(&pen);
	dc.MoveTo(m_point);
	dc.LineTo(point);
	dc.SelectObject(pOldPen);
	CView::OnLButtonUp(nFlags, point);
}

 

绘制(填充)矩阵:

void COOPExView::OnLButtonDown(UINT nFlags, CPoint point)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	m_point = point;//保存点的位置
	CView::OnLButtonDown(nFlags, point);
}


void COOPExView::OnLButtonUp(UINT nFlags, CPoint point)
{
	CBrush brush(RGB(255, 0, 0));            //画刷填充,可空心(这个自己查)
	CPen pen(PS_SOLID, 5, RGB(255, 0, 0));
	CClientDC dc(this);

	CPen *pOldPen = dc.SelectObject(&pen);
	dc.FillRect(CRect(m_point, point), &brush);
	dc.MoveTo(m_point);
	dc.LineTo(point);
	dc.SelectObject(pOldPen);
	CView::OnLButtonUp(nFlags, point);
}

 

绘制(非填充)矩阵:

void CMFCApplication1View::OnLButtonDown(UINT nFlags, CPoint point)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	m_point = point;
	CView::OnLButtonDown(nFlags, point);
}


void CMFCApplication1View::OnLButtonUp(UINT nFlags, CPoint point)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	CClientDC dc(this);
	CBrush *pBrush = CBrush::FromHandle((HBRUSH)GetStockObject(NULL_BRUSH)); // CBrush::FromHandle是静态成员函数  
	//FromHandle给出一个Windows HBRUSH对象句柄时,返回一个指向CBrush对象的指针。即将画刷的句柄转换为对象的指针。
	CBrush *pOldBrush = dc.SelectObject(pBrush);
	dc.Rectangle(CRect(m_point, point));
	dc.SelectObject(pOldBrush);
	CView::OnLButtonUp(nFlags, point);
}

 

叁:绘制国际象棋棋盘:

void COOPExView::OnLButtonDown(UINT nFlags, CPoint point)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	m_point = point;//保存点的位置
	CView::OnLButtonDown(nFlags, point);
}


void COOPExView::OnLButtonUp(UINT nFlags, CPoint point)
{
	int hight = 20, width = 20, flag = 0;//参数可自己调大小
	CClientDC dc(this);
	CBrush *pBrush = CBrush::FromHandle((HBRUSH)GetStockObject(NULL_BRUSH)); // CBrush::FromHandle是静态成员函数  
	CBrush *pOldBrush = dc.SelectObject(pBrush);
	dc.SelectObject(pOldBrush);
	//CClientDC dc(this);
	p1.x = m_point.x - 15;
	p1.y = m_point.y - 15;
	p2.x = m_point.x + 8 * hight + 16;
	p2.y = m_point.y + 8 * width + 16;
	dc.Rectangle(CRect(p1, p2));
	p1.x = m_point.x - 1;
	p1.y = m_point.y - 1;
	p2.x = m_point.x + 8 * hight + 1;
	p2.y = m_point.y + 8 * width + 1;
	dc.Rectangle(CRect(p1, p2));
		for (int i = 0; i < 8; i++)
		{
			for (int j = 0; j < 8; j++)
			{
				point1.x = m_point.x + i * hight;
				point1.y = m_point.y + j * width;
				point2.x = m_point.x+(i + 1)*hight;
				point2.y = m_point.y+(j + 1)*width;
				if ((i + j) % 2 == 0)
				{
					CBrush brush(RGB(0, 0, 0));
					dc.FillRect(CRect(point1, point2), &brush);
				}
				else
				{
					CBrush brush(RGB(255, 255, 255));
					dc.FillRect(CRect(point1, point2), &brush);
				}

			}
	}
	CView::OnLButtonUp(nFlags, point);
}

 

肆:双缓冲实现国际象棋:

参考博客:MFC双缓冲解决图象闪烁[转]

在CView类的类向导中虚函数里,有一个OnDraw虚函数,对其进行修改;

添加代码为:

先在构造函数中确定初始棋盘的位置:

CMFCApplication2View::CMFCApplication2View() noexcept
{
	// TODO: 在此处添加构造代码
	m_point.x = 200;//自己看情况
	m_point.y = 200;
}

 或者定义一个数字,让棋盘不显现:

CMFCApplication2View::CMFCApplication2View() noexcept
{
	// TODO: 在此处添加构造代码
	count = 0;
}

然后在上面绘制棋盘的基础上给OnDraw函数添加代码:

void CMFCApplication2View::OnDraw(CDC* pDC)
{
	int nWidth = 1, nHeight = 1;
	CMFCApplication2Doc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	CDC MemDC; //首先定义一个显示设备对象
	CBitmap MemBitmap;//定义一个位图对象
	//随后建立与屏幕显示兼容的内存显示设备
	MemDC.CreateCompatibleDC(NULL);
	//这时还不能绘图,因为没有地方画 ^_^
	//下面建立一个与屏幕显示兼容的位图,至于位图的大小嘛,可以用窗口的大小
	MemBitmap.CreateCompatibleBitmap(pDC, nWidth, nHeight);
	//将位图选入到内存显示设备中
	//只有选入了位图的内存显示设备才有地方绘图,画到指定的位图上
	CBitmap *pOldBit = MemDC.SelectObject(&MemBitmap);
	//先用背景色将位图清除干净,这里我用的是白色作为背景
	//你也可以用自己应该用的颜色
	MemDC.FillSolidRect(0, 0, nWidth, nHeight, RGB(255, 255, 255));
	//绘图
	int hight = 20, width = 20, flag = 0;//参数可自己调大小
	CClientDC dc(this);
	CBrush *pBrush = CBrush::FromHandle((HBRUSH)GetStockObject(NULL_BRUSH)); // CBrush::FromHandle是静态成员函数  
	CBrush *pOldBrush = dc.SelectObject(pBrush);
	dc.SelectObject(pOldBrush);
	//CClientDC dc(this);
	if (count > 0){                //可加可不加。。。。看老师心情
	p1.x = m_point.x - 15;
	p1.y = m_point.y - 15;
	p2.x = m_point.x + 8 * hight + 16;
	p2.y = m_point.y + 8 * width + 16;
	dc.Rectangle(CRect(p1, p2));
	p1.x = m_point.x - 1;
	p1.y = m_point.y - 1;
	p2.x = m_point.x + 8 * hight + 1;
	p2.y = m_point.y + 8 * width + 1;
	dc.Rectangle(CRect(p1, p2));
	for (int i = 0; i < 8; i++)
	{
		for (int j = 0; j < 8; j++)
		{
			point1.x = m_point.x + i * hight;
			point1.y = m_point.y + j * width;
			point2.x = m_point.x + (i + 1)*hight;
			point2.y = m_point.y + (j + 1)*width;
			if ((i + j) % 2 == 0)
			{
				CBrush brush(RGB(0, 0, 0));
				dc.FillRect(CRect(point1, point2), &brush);
			}
			else
			{
				CBrush brush(RGB(255, 255, 255));
				dc.FillRect(CRect(point1, point2), &brush);
			}

		}
	}
	}
	//将内存中的图拷贝到屏幕上进行显示
	pDC->BitBlt(0, 0, nWidth, nHeight, &MemDC, 0, 0, SRCCOPY);
	//绘图完成后的清理
	MemBitmap.DeleteObject();
	MemDC.DeleteDC();
	// TODO: 在此处为本机数据添加绘制代码
}

 

效果图:

(注意:该双缓冲代码只能解决最后一次绘画国际象棋时的闪烁问题,即最大化后只会保留最后绘制的那个国际象棋棋盘)

 

伍:交互式指定棋盘大小;

方法:

通过绘画标准线的方法界定棋盘的大小

步骤:左键点击到左键释放绘画标准线,双击右键进行棋盘绘画。。

示例:

具体操作:(文件名为:MFCApplication3)

为Cview类添加的变量和响应函数如下:

 

将.cpp文件中的右键释放函数代码注销:(可在类向导中寻找该响应函数)

 

 继续对各响应函数编写代码为:

void CMFCApplication3View::OnLButtonDown(UINT nFlags, CPoint point)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	m_point = point;
	CView::OnLButtonDown(nFlags, point);
}


void CMFCApplication3View::OnLButtonUp(UINT nFlags, CPoint point)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	int S = (int)sqrt((m_point.x - point.x)*(m_point.x - point.x) + (m_point.y - point.y)*(m_point.y - point.y));
	hight = width = S;
	hight /= 9;
	width /= 9;
	CPen pen(PS_SOLID, 2, RGB(255, 0, 0));//中间的数字可以调整画笔大小
	CClientDC dc(this);
	CPen *pOldPen = dc.SelectObject(&pen);
	dc.MoveTo(m_point);
	dc.LineTo(point);
	dc.SelectObject(pOldPen);
	CView::OnLButtonUp(nFlags, point);
}

void CMFCApplication3View::OnLButtonDblClk(UINT nFlags, CPoint point)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	
	CView::OnLButtonDblClk(nFlags, point);
}


void CMFCApplication3View::OnRButtonDblClk(UINT nFlags, CPoint point)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	c_point = point;
	count++;
	CClientDC dc(this);
	CBrush *pBrush = CBrush::FromHandle((HBRUSH)GetStockObject(NULL_BRUSH)); 
        // CBrush::FromHandle是静态成员函数  
	CBrush *pOldBrush = dc.SelectObject(pBrush);
	dc.SelectObject(pOldBrush);
	//CClientDC dc(this);
	p1.x = point.x - hight / 4 * 3-1;
	p1.y = point.y - width / 4 * 3-1;
	p2.x = point.x + 8 * hight + hight / 4 * 3 + 1;
	p2.y = point.y + 8 * width + width / 4 * 3 + 1;
	dc.Rectangle(CRect(p1, p2));
	p1.x = point.x - 1;
	p1.y = point.y - 1;
	p2.x = point.x + 8 * hight + 1;
	p2.y = point.y + 8 * width + 1;
	dc.Rectangle(CRect(p1, p2));
	for (int i = 0; i < 8; i++)
	{
		for (int j = 0; j < 8; j++)
		{
			point1.x = point.x + i * hight;
			point1.y = point.y + j * width;
			point2.x = point.x + (i + 1)*hight;
			point2.y = point.y + (j + 1)*width;
			if ((i + j) % 2 == 0)
			{
				CBrush brush(RGB(0, 0, 0));
				dc.FillRect(CRect(point1, point2), &brush);
			}
			else
			{
				CBrush brush(RGB(255, 255, 255));
				dc.FillRect(CRect(point1, point2), &brush);
			}

		}
	}
	CView::OnRButtonDblClk(nFlags, point);
}

构造函数初始化变量:

CMFCApplication3View::CMFCApplication3View() noexcept
{
	// TODO: 在此处添加构造代码
	count = 0;             //双缓冲刷新限制条件
	hight = width = 20;    //未画标准线时棋盘的大小
}

双缓冲防刷新(找到OnDraw函数进行编译):

void CMFCApplication3View::OnDraw(CDC* pDC)
{
	/*CMFCApplication3Doc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	if (!pDoc)
		return;*/
		int nWidth = 1, nHeight = 1;
		CMFCApplication3Doc* pDoc = GetDocument();
		ASSERT_VALID(pDoc);
		CDC MemDC; //首先定义一个显示设备对象
		CBitmap MemBitmap;//定义一个位图对象
		//随后建立与屏幕显示兼容的内存显示设备
		MemDC.CreateCompatibleDC(NULL);
		//这时还不能绘图,因为没有地方画 ^_^
		//下面建立一个与屏幕显示兼容的位图,至于位图的大小嘛,可以用窗口的大小
		MemBitmap.CreateCompatibleBitmap(pDC, nWidth, nHeight);
		//将位图选入到内存显示设备中
		//只有选入了位图的内存显示设备才有地方绘图,画到指定的位图上
		CBitmap *pOldBit = MemDC.SelectObject(&MemBitmap);
		//先用背景色将位图清除干净,这里我用的是白色作为背景
		//你也可以用自己应该用的颜色
		MemDC.FillSolidRect(0, 0, nWidth, nHeight, RGB(255, 255, 255));
		//绘图
		if (count > 0)
		{
		CClientDC dc(this);
		CBrush *pBrush = CBrush::FromHandle((HBRUSH)GetStockObject(NULL_BRUSH)); // CBrush::FromHandle是静态成员函数  
		CBrush *pOldBrush = dc.SelectObject(pBrush);
		dc.SelectObject(pOldBrush);
		//CClientDC dc(this);
		p1.x = c_point.x - hight / 4 * 3-1;
		p1.y = c_point.y - width / 4 * 3-1;
		p2.x = c_point.x + 8 * hight + hight / 4 * 3 + 1;
		p2.y = c_point.y + 8 * width + width / 4 * 3 + 1;
		dc.Rectangle(CRect(p1, p2));
		p1.x = c_point.x - 1;
		p1.y = c_point.y - 1;
		p2.x = c_point.x + 8 * hight + 1;
		p2.y = c_point.y + 8 * width + 1;
		dc.Rectangle(CRect(p1, p2));
		for (int i = 0; i < 8; i++)
		{
			for (int j = 0; j < 8; j++)
			{
				point1.x = c_point.x + i * hight;
				point1.y = c_point.y + j * width;
				point2.x = c_point.x + (i + 1)*hight;
				point2.y = c_point.y + (j + 1)*width;
				if ((i + j) % 2 == 0)
				{
					CBrush brush(RGB(0, 0, 0));
					dc.FillRect(CRect(point1, point2), &brush);
				}
				else
				{
					CBrush brush(RGB(255, 255, 255));
					dc.FillRect(CRect(point1, point2), &brush);
				}

			}
		}
		}
		//将内存中的图拷贝到屏幕上进行显示
		pDC->BitBlt(0, 0, nWidth, nHeight, &MemDC, 0, 0, SRCCOPY);
		//绘图完成后的清理
		MemBitmap.DeleteObject();
		MemDC.DeleteDC();
	// TODO: 在此处为本机数据添加绘制代码
}

 

 还有一种交互式绘画棋盘大小的方法:分割视图,用对话框传参

(这个,我遇到了一个小小的bug,,就是对话框中获取的数据无法传到视图类中,所以导致失败,

    如果有找到如何将对话框中数据传到视图类中的同志们,望私戳告知,不胜感激。)

 

 

陆:将棋盘文件保存为BMP格式文件:

(注意:这里仅保存棋盘,而不是整个屏幕,当然,保存棋盘是建立在保存整个屏幕的基础上的。)

前提:在  伍:【交互式指定棋盘大小的基础】上继续进行。

一、BITMAPINFO方式保存:

步骤:

1、切换到资源视图,在Menu文件中双击IDR_MAINFRAME弹出右侧文件框架中,

      为“ 文件——>保存 ” 添加 “保存文件为bmp格式” (当然,你开心就好~~~),

 

 2、右键“保存文件为bmp格式”选择“添加事件处理程序”,在弹出的对话框中选择第一个COMMAND,

       右边的类一定要选择CView类,这里为“CMFCApplication3View”。

3、对上述COMMAND函数进行编辑,编辑代码为:

void CMFCApplication3View::On32771()
{
	// TODO: 在此添加命令处理程序代码
	int x = c_point.x - hight / 4 * 3 - 1;//定位棋盘的位置
	int y = c_point.y - hight / 4 * 3 - 1;
	CDC* pDC = GetWindowDC();
	CBitmap bitmap;
	CDC memDC;
	CRect rect;
	GetWindowRect(rect);
	memDC.CreateCompatibleDC(pDC);

	bitmap.CreateCompatibleBitmap(pDC, rect.Width(), rect.Height());
	memDC.SelectObject(&bitmap);
	memDC.BitBlt(0, 0, rect.Width(), rect.Height(), pDC, x, y, SRCCOPY);

	CFileDialog fDlg(FALSE, _T("bmp"), NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, _T("位图文件|*.bmp"), this);
	if (fDlg.DoModal() == IDOK)
	{
		CString bmpfile = fDlg.GetPathName();
		CFile file(bmpfile, CFile::modeCreate | CFile::modeWrite);
		BITMAP bInfo;
		bitmap.GetBitmap(&bInfo);
		//计算调色板大小   
		int panelsize = 0;
		if (bInfo.bmBitsPixel < 24) //非真彩色   
		{
			panelsize = pow((double)2, bInfo.bmBitsPixel) * sizeof(RGBQUAD);
		}
		//定义位图信息  
		int size = hight * 9 + hight/2 + 3;//设置棋盘的大小
		BITMAPINFO*  bMapInfo = (BITMAPINFO*)LocalAlloc(LPTR, sizeof(BITMAPINFO) + panelsize);
		bMapInfo->bmiHeader.biBitCount = bInfo.bmBitsPixel;
		bMapInfo->bmiHeader.biClrImportant = 0;
		bMapInfo->bmiHeader.biCompression = 0;
		bMapInfo->bmiHeader.biHeight = size;
		bMapInfo->bmiHeader.biPlanes = bInfo.bmPlanes;
		bMapInfo->bmiHeader.biSize = sizeof(BITMAPINFO);
		bMapInfo->bmiHeader.biSizeImage = bInfo.bmHeight*bInfo.bmWidthBytes;
		bMapInfo->bmiHeader.biWidth = size;
		bMapInfo->bmiHeader.biXPelsPerMeter = 0;
		bMapInfo->bmiHeader.biYPelsPerMeter = 0;

		//获取位图的实际数据   
		char* pData = new char[bMapInfo->bmiHeader.biSizeImage];
		int len = GetDIBits(pDC->m_hDC, bitmap, 0, bInfo.bmHeight, pData, bMapInfo, DIB_RGB_COLORS);

		BITMAPFILEHEADER bFileHeader;
		bFileHeader.bfType = 0x4D42;
		bFileHeader.bfReserved1 = 0;
		bFileHeader.bfReserved2 = 0;
		bFileHeader.bfSize = sizeof(BITMAPFILEHEADER);
		bFileHeader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + panelsize;

		//向文件中写入位图数据   
		file.Write(&bFileHeader, sizeof(BITMAPFILEHEADER));
		file.Write(&bMapInfo->bmiHeader, sizeof(BITMAPINFOHEADER));
		file.Write(pData, bMapInfo->bmiHeader.biSizeImage + panelsize);
		file.Close();
		delete pData;
		LocalFree(bMapInfo);
	}
	bitmap.DeleteObject();
	memDC.DeleteDC();
}

测试:

这里我们选择合适的位置进行保存即可。

  二、CImage类保存图片

(这个保存方式等你们慢慢发现一下吧~~~~~)

给出第三步代码:

(这个需要自己先创建文件和写入路径。。。)

void CMainFrame::On32775()
{
	// TODO: 在此添加命令处理程序代码
	
	HWND hwnd = this->GetSafeHwnd();
	HDC hDC = ::GetWindowDC(hwnd);//获取DC      

	RECT rect;
	::GetWindowRect(hwnd, &rect);//获取屏幕大小     
	HDC hDCMem = ::CreateCompatibleDC(hDC);//创建兼容DC      

	HBITMAP hBitMap = ::CreateCompatibleBitmap(hDC, rect.right - rect.left, rect.bottom - rect.top);//创建兼容位图      
	HBITMAP hOldMap = (HBITMAP)::SelectObject(hDCMem, hBitMap);//将位图选入DC,并保存返回值      

	::BitBlt(hDCMem, 0, 0, rect.right - rect.left, rect.bottom - rect.top, hDC, 0, 0, SRCCOPY);//将屏幕DC的图象复制到内存DC中      

	CImage image;//需要#include <atlimage.h>     
	image.Attach(hBitMap);
	image.Save(_T("E://B.bmp"));//如果文件后缀为.bmp,则保存为为bmp格式   
        //路径//文件名.bmp。。。。  
	image.Detach();

	::SelectObject(hDCMem, hOldMap);//选入上次的返回值      

	//释放      
	::DeleteObject(hBitMap);
	::DeleteDC(hDCMem);
	::DeleteDC(hDC);
}

 

柒 :后记

至此 单文档的基础内容我们也学习的差不多了   主要还是完成作业啊~~   

希望大家可以和我一样,继续加油,再接再厉,

即便孤独、迷茫、愤怒,

也请勇敢向前,

直到星与海的尽头,

直到梦与想的彼岸~~~~~

 

 

下面是我学习时借鉴和启发我的一些博客:

VC学习笔记:简单绘图

MFC设置对话框、字体对话框、颜色对话框

暴力解决VS2017MFC窗口分割问题

MFC框架类、文档类、视图类相互访问的方法

单文档窗口绘图保存为bmp文件的问题

将屏幕和MFC程序界面保存成bmp格式图片保存

有一些没发上去,感觉太多了,给出截图,自己体会:

 

  • 3
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值