本博文内容是博文基于MFC框架的图像缩放算法示例的一部分(返回目录)。
MFC(Microsoft Foundation Classes)是微软公司提供的一个类库(class libraries),以C++类的形式封装了Windows的API,并且包含一个应用程序框架以减少应用程序开发人员的工作量。
这里不详细介绍MFC框架,相关信息可以自己搜索。本项目的开发平台是Visal Studio Community 2022版,注意MFC组件不是默认安装的,需要手动配置安装。
下面是基于MFC框架建立一个GUI(Graphic User Interface,图形用户接口)程序的步骤。
MFC可以生成单文档、多文档和基于对话框的GUI程序,我们的项目使用单文档程序作为示例。废话少说,直接上图。
选择好项目类型后,其他设置可以不修改,一直点击【下一步】直到完成项目创建,可以看到如下图所示界面。
项目创建完成后,Visual Studio为我们创建了一个完成的程序框架,也就是不用编写一行代码就可以运行一个完整的程序。点击下图中【本地Windows调试器】按钮,经过一段时间编译和构建,会自动运行如下图所示框架程序。
MFC单文档程序结构主要涉及四个核心类的对象,每个类的源码由一个类的头文件*.h和对应类的实现文件*.cpp组成。
(1)应用程序类CApp:负责处理消息,将收到的消息分发给相应的对象,是应用程序的最顶层模块。(下图右侧的MFC_SD_01.h和MFC_SD_01.cpp)
(2)主框架类CMainFrame:是视图CView的父窗口,视图CView类的对象就显示在CMainFrame类对象的客户区中。(下图右侧的MainFrm.h和MainFrm.cpp)
(3)视图类CMFC_SD_01View:用来显示文档类CTestDoc中的数据,并根据对视图类的操作修改文档类的数据。(下图右侧的MFC_SD_01View.h和MFC_SD_01View.cpp)
(4)文档类CMFC_SD_01Doc:用来保存和处理数据,一般具体的算法可以放在这里。一个视图类只能跟一个文档类相联系,而一个文档类可以跟多个视图类相联系。(下图右侧的MFC_SD_01Doc.h和MFC_SD_01Doc.cpp)
为简单起见,目前我们仅在CMFC_SD_01View类中添加我们的自定义代码。下面我们开始编写绘制正方形的代码,为了便于后面绘制图像的用途,我们选择一个很简单的函数来完成正方形的绘制,即基于Windows GDI库的SetPixel()函数绘制一个彩色正方形。
点击右侧栏的MFC_SD_01View.cpp,打开CView类的实现文件,找到OnDraw()函数,这是一个消息响应函数,即在应用程序的界面需要更新(包括启动时,移动或隐藏再显示等操作)操作系统会发送相关的消息我们的应用程序,程序就会调用OnDraw()函数处理相关的绘制工作,当然这里包括用户区的绘制,也就是step06显示的界面中间大片空白区域。
//void CMFCSD01View::OnDraw(CDC* /*pDC*/)
void CMFCSD01View::OnDraw(CDC* pDC)
{
CMFCSD01Doc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
if (!pDoc)
return;
// TODO: 在此处为本机数据添加绘制代码
//1.使用DC在指定坐标(x=150,y=200)位置绘制一个红色的点,颜色由RGB宏指定
pDC->SetPixel(150, 200, RGB(255, 0, 0));
//2.调用SetPixel函数绘制一个颜色渐变的正方形
// 正方形边长为255像素,左上角坐标(100,100)
for (int i = 0; i < 256; i++) {
pDC->SetPixel(100, 100+i, RGB(255, 0, 0)); //红色
pDC->SetPixel(100+255, 100+i, RGB(255,0, 255)); //混合色
pDC->SetPixel(100+i, 100+255, RGB(0, 255, 0)); //绿色
pDC->SetPixel(100+i, 100, RGB(0, 0, 255)); //蓝色
}
}
上面的代码在OnDraw()函数内添加绘制一个正方形的代码,也就是在程序启动或需要更新界面的时候就会调用这部分代码绘制相应的图形。
有几个地方需要注意的,原OnDraw()包含一个参数是默认被注释了(CDC* /*pDC*)
,也就是这个pDC是不能使用的,而我们的代码正好用到的就是这个CDC类的对象指针,所以需要取消原函数的注释,修改为(CDC* pDC)
才能在函数内部使用pDC。// TODO:
下面才是我们自己编写的代码,上面的部分是应用程序框架生成的时候系统添加的,无需改动。
CDC(DC:设备上下文)类是Window提供的GDI(图形设备接口)的一个绘制图像的重要工具,这里我们不具体讨论,有兴趣的同学可以自己搜索学习相关内容。我们的工程仅仅用到其中的一个函数SetPixel(),它的函数原型如下所示,功能是在用户工作区的指定坐标位置int x,int y
绘制一个指定颜色COLORREF crColor
的点。
COLORREF CDC::SetPixel(int x,int y,COLORREF crColor);
坐标位置好理解,x代表横坐标,y代表纵坐标,需要注意是绘图坐标系的原点是在用户工作区的左上角,而y的正方向向下,与一般的直角坐标系(即笛卡尔坐标系)不同。
指定颜色COLORREF时我们使用RGB宏,即颜色由Red,Green和Blue三种不同分量(0~255表示)的单色混合成各种五彩缤纷的颜色,例如RGB(255,0,0)
代表纯红色,RGB(255,0, 255)
代表红色和蓝色的混合色,其他类似。
因为pDC是一个指针,所以调用它的方法要用指针的引用方式,即pDC->SetPixel(...)
,每调用一个这个函数就会绘制一个点,而一条直线由多个点组成,一个正方形由四条直线段构成,因此我们用了一个for循环来完成绘制操作,大家可以参考源码仔细体会。
再次点击Visual Studio的【本地Windows调试器】按钮,经过一段时间编译和构建,会自动运行显示下图所示图形界面。可以看到在用户绘制了一个有四个不同颜色的边构成的正方向和一个红色的点(不易看到,图中用灰色手绘圆圈进行了重点标记!!!)
到此为止,我们利用CDC类的SetPixel函数成功绘制了一个彩色正方形。需要指出的是,这里使用的SetPixel方法是比较笨的方法,目的是为后面讨论绘制BMP图像的单个像素打基础。CDC还有其他更方便的函数绘制线条,比如LineTo()等,大家可以自己学习,这里不再赘述。
学完如何基于Visual Studio的MFC框架搭建一个单文档的GUI程序,并在消息响应函数OnDraw()利用系统提供的绘图工具CDC* pDC
绘制一个彩色正方形,大家以在以上程序的基础稍作修改就可以绘制多种多样的程序。比如: