MFC制作Windows画图程序(二)

《MFC制作Windows画图程序(一)》

7 颜色填充功能

油漆桶功能主要应用了FloodFill函数,该函数的功能是用当前刷从点(x, y)开始向四周填充到颜色为crColor的边界。其中形参m_PointBegin.x和m_PointBegin.y记录了鼠标单击时的位置,m_PenColor记录了之前绘制图形所用的铅笔颜色,这样FloodFill函数就会从鼠标单击时的位置开始如同漫水一样漫向四周,直到之前的铅笔颜色为止。这样就实现了颜色填充功能。
具体实现代码如下:

OnLButtonUp() 中添加如下代码:
	case DrawType::Fill:  
	{
		CClientDC dc(this);
		CBrush newBrush(m_BrushColor);
		oldBrush = dc.SelectObject(&newBrush);
		dc.SelectObject(newBrush);
		dc.FloodFill(m_PointBegin.x, m_PointBegin.y, m_PenColor);
		dc.SelectObject(oldBrush);
	}

实现效果:
在这里插入图片描述

8 选择画笔颜色

在设置画笔颜色的时候我们首先要定义一个CColorDialog对象,这是一个对话框,包含系统定义的颜色的列表,如图所示。当dlg.DoModal()==IDOK时,也就是说对话框弹出来了,并且你点击了对话框上的OK按钮,然后就执行m_PenColor=dlg.GetColor(),将画笔的颜色设置为你选择的颜色。
具体实现如下:

void CMFC_PAINTView::OnMenucolor() 
{
	CColorDialog dlg;
	if (IDOK == dlg.DoModal()) //弹出对话框
{
		m_PenColor = dlg.GetColor();//得到颜色
}
}
//在OnMouseMove()中和OnLButtonUp()中都需要添加以下代码:
CPen newPen, *oldPen;	
newPen.CreatePen(PS_SOLID, m_PenSize, m_PenColor);
oldPen = dc.SelectObject(&newPen);
//因为是局部变量,所以可以同名。
//在函数最后加dc.SelectObject(oldPen);

效果如下:
在这里插入图片描述
在这里插入图片描述

9 设置画笔粗细

画笔的粗细设置也和颜色相类似,我们先创建一个对话框,调用GetWindowText函数获取用户输入的值,然后将m_PenSize的值设置为获取到的值,这样就改变了画笔的粗细。

//首先需要创建一个对话框,然后添加一个示例编辑框,给这个框添加一个类CSetPenSizeDialog和变量m_Edit
void CSetPenSizeDialog::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	DDX_Control(pDX, IDC_EDIT1, m_Edit);

	CString str;
	m_Edit.GetWindowText(str);
	m_PenSize = _ttoi(str);
}
//添加事件处理程序,生成函数OnMenuSize(),在View.cpp中得包含头文件“CSetPenSizeDialog.h”
void CMFC_PAINTView::OnMenusize() 
{
	CSetPenSizeDialog dlg;
	if (IDOK == dlg.DoModal()) {
		this->m_PenSize = dlg.m_PenSize;
	}
}

效果如下:
在这里插入图片描述
在这里插入图片描述

10 将绘制出来的图形保存的实现

1、CreateCompatibleDC 该函数创建一个与指定设备兼容的内存设备上下文环境(DC);
2、filterindex是“打开”或“另存为”对话框(CommonDialog控件)中的一个缺省的过滤器,来打开或者保存文件的文件扩展名。要使用这个属性值,就必须先给filter属性赋值。

添加事件处理程序,生成函数OnFileSave():
void CMFC_PAINTView::OnFileSave()
{
	CClientDC dc(this);
	CRect rect;
	BOOL  showMsgTag;   //是否要弹出”图像保存成功对话框" 
	BOOL saveTag;
	CString saveFilePath;
	GetClientRect(&rect);                  //获取画布大小
	HBITMAP hbitmap = CreateCompatibleBitmap(dc, rect.right - rect.left, rect.bottom - rect.top);
	//创建兼容位图
	HDC hdc = CreateCompatibleDC(dc);      //创建兼容DC,以便将图像保存为不同的格式

	HBITMAP hOldMap = (HBITMAP)SelectObject(hdc, hbitmap);
	//将位图选入DC,并保存返回值 
	BitBlt(hdc, 0, 0, rect.right - rect.left, rect.bottom - rect.top, dc, 0, 0, SRCCOPY);
	//将屏幕DC的图像复制到内存DC中
	CImage image;
	image.Attach(hbitmap);                //将位图转化为一般图像
	saveTag = FALSE;
	if (!saveTag)                      //如果图像是第一次被写入,则打开对话框
	{
		showMsgTag = TRUE;
		CString  strFilter = _T("位图文件|*.bmp|JPEG 图像文件|*.jpg|GIF图像文件 | *.gif | PNG图像文件 | *.png |其他格式| *.* |");
		CFileDialog dlg(FALSE, _T("bmp"), _T("iPaint1.bmp"), NULL, strFilter);
		if (dlg.DoModal() != IDOK)
			return;
		CString strFileName;          //如果用户没有指定文件扩展名,则为其添加一个
		CString strExtension;
		strFileName = dlg.m_ofn.lpstrFile;
		if (dlg.m_ofn.nFileExtension = 0)               //扩展名项目为0
		{
			switch (dlg.m_ofn.nFilterIndex)
			{
			case 1:
				strExtension = "bmp"; break;
			case 2:
				strExtension = "jpg"; break;
			case 3:
				strExtension = "gif"; break;
			case 4:
				strExtension = "png"; break;
			default:
				break;
			}
			strFileName = strFileName + "." + strExtension;
		}
		saveFilePath = strFileName;     //saveFilePath为视类中的全局变量,类型为CString
	}
	else
	{
		showMsgTag = FALSE;

	}
	//AfxMessageBox(saveFilePath);               //显示图像保存的全路径(包含文件名)
	HRESULT hResult = image.Save(saveFilePath);     //保存图像
	if (FAILED(hResult))
	{
		MessageBox(_T("保存图像文件失败!"));
	}
	else
	{
		if (showMsgTag)
			MessageBox(_T("文件保存成功!"));
	}
	image.Detach();
	SelectObject(hdc, hOldMap);
}

效果如下:
在这里插入图片描述
在这里插入图片描述

11 添加位图

添加图片时,我们先调用GetPathName函数获取选择的文件的文件路径,然后通过LoadImage函数加载图片,用Attach(hBitmap)把位图资源句柄附加到hBitmap对象上,然后创建一个基于位图的画刷,最后就可将位图绘制在客户端。

//添加事件处理程序,生成函数OnFileOpen():
void CMFC_PAINTView::OnFileOpen()
{
	m_DrawType = DrawType::myLoadImage;
	CString strPath, filter;          //打开文件,获得图片路径
	filter = "bmp图片(*.bmp)|*.bmp||";
	CFileDialog dlg(TRUE, NULL, NULL, OFN_HIDEREADONLY);
	if (dlg.DoModal() == IDOK) {
		strPath = dlg.GetPathName();
	}
	HBITMAP hBitmap = (HBITMAP)::LoadImage(NULL, strPath, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);  //加载图片
	CBitmap loadImageBitmap;
	loadImageBitmap.Attach(hBitmap);
	BITMAP bitMap;
	loadImageBitmap.GetBitmap(&bitMap);
	CBrush newBrush, * oldBrush;
	newBrush.CreatePatternBrush(&loadImageBitmap);
	CClientDC dc(this);
	oldBrush = (CBrush*)dc.SelectObject(&newBrush);
	dc.Rectangle(0, 0, bitMap.bmWidth, bitMap.bmHeight);
	dc.SelectObject(oldBrush);
}

效果如下:
在这里插入图片描述


版权声明:本文为qq_50533078原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。