帮你快速理解什么是MFC(Windows环境下)

 ​​​​​​​​​​​​​​​​​​​​​

 我是荔园微风,作为一名在IT界整整25年的老兵,今天总结一下Windows环境下的MFC到底是一个什么技术。

早在1998年,MFC绝对是技术界的一个热门名词,现在似乎提的人很少。但其他MFC的很多程序仍在世界上各个角落运行着。做为一名系统架构师,你仍然不能忽视MFC的存在。但后来接触技术的人大多不太了解这个,那我们一起来看看。

大家对VC++ 不陌生,1992年VC++是1.0,集成了MFC2.0。1998年推出了VC++6.0,集成了MFC6.0。2005年是VC++8.0,2009年是VC++9.0,2010年是VC++10.0。

MFC是一个类库,它是VC++的核心,中文叫做微软基础类库。那它是干什么用的呢?程序员可以利用MFC类库实现自己想要的功能,如菜单、工具栏、状态栏的创建,还有窗口的注册、创建与显示、更新功能。针对这些功能,下面详细介绍下窗口类。

MFC应用程序有3种类型,基于单文档、基于多文档、基于对话框。前两种都会有窗口,而第3种的对话框不是窗口。所以学习窗口类对学好MFC至关重要,它也是MFC类库中最基本的。MFC程序员写程序常用的3个类:CRect、CPoint、CString。

这3个类之所以会被经常应用,是因为当被要求在窗口中画一些长方形,或者是限定一个区域。比如,只能在窗口中的某一个方形范围中操作,就要用CRect类来圈定一个范围,同时读者还可以将它的功用衍生到其他领域。而对于CPoint类,一般在系统的开始界面中,都会贴一张图片以示美观,但是确定图片的放置位置就是确定左上角和右下角点的二维坐标值。因此这时位置点的坐标值至关重要,而CPoint类就可以创建这样一个对象,它可以定义一个点的二维坐标值。最后说说CString类,它就是将C++中的对string的各种操作封装起来变成一个只能在MFC下使用的类。在MFC中用CString当然要比直接用string省事多了。而它经常被运用的场合,就是当一个项目的开始界面中要显示一段文字时,需要在内存中声明一个CString对象来存储这段文字的值。

经常用到的控件编程中,有一种控件是静态文本编辑框。当用户输入信息时,程序必须实时地获取编辑框中的信息,而此信息就需要被存放到一个变量中。由于获取编辑框中文本信息的函数决定了这个变量的类型必须是CString类型的,因此熟悉它的应用也就是情理之中了。
 

1.窗口类WNDCLASS
WNDCLASS结构体包含了所有窗口类的特征,如下是窗口类的原型。

typedef struct {
UINT style;  //窗口类型
WNDPROC lpfnWndProc;  //窗口处理函数
int cbClsExtra;  //窗口类扩展字节
int cbWndExtra;  //窗口实例扩展字节
HINSTANCE hInstance;  //当前实例句柄
HICON hIcon;  //窗口图标
HCURSOR hCursor;  /窗口光标
HBRUSH hbrBackground;  //窗口背景色
LPCTSTR lpszMenuName;  //窗口菜单名
LPCTSTR lpszClassName;  //窗口类名
} WNDCLASS,*PWNDCLASS;  //第一个是实体类型,第二个是指针类型

震惊吗?

Windows环境中的窗口居然就是我们C语言中的结构体!!

两者看似没有关系,居然本质是一样的。

最后一行表明这个结构体既可以被当作一个实体类型来用,也可以作为指针被定义,具体用哪种就要看应用场合了,但经常会被作为实体应用。熟悉它的定义后,下面介绍下它的应用实例,如下代码:

WNDCLASS wndclass;         //创建一个窗口类
wndclass.cbClsExtra=0;  //窗口类无扩展
wndclass.cbWndExtra=0;  //窗口实例无扩展
wndclass.hbrBackground=(HBRUSH)GetStockObject(BLACK_BRUSH);  //窗口背景为黑
wndclass.hCursor=Loadcursor (NULL,IDC_ARROW);  //窗口采用箭头光标
wndclass.hIcon=LoadIcon (NULL,IDI_APPLICATION);        //窗口的图标为缺省状态
wndclass.hInstance=hInstance;  //当前实例句柄
wndclass.lpfnWndProc=WinHouProc;  //定义窗口处理函数
wndclass.lpszClassName="VC++";  //窗口类为“VC++”
wndclass.lpszMenuName=NULL;  //窗口无菜单
wndclass.style=CS_HREDRAW | CS_PARENTDC;  //设置窗口类型

RegisterClass(&wndclass);  //注册窗口类

HWND hwnd;
hWnd=CreateWindow("VC++","消息机制",WS_OVERLAPPEDWINDOW,
                      .0,0,600,400,NULL,NULL,hInstance,NULL);  //创建窗口

ShowWindow (hwnd,SW_SHOWNORMAL);  //显示窗口
UpdateWindow(hwnd);  //更新窗口

大家看注释就知道程序的意思,前12行重新赋值完窗口类的各种属性,就要注册这个新的窗口类,就像一群小伙打算创业,刚开始有了初步构思决定开个公司,就要去有关部门注册公司以示合法。这里也一样需要注册这个新的窗口类以示在系统内合法。这就有了RegisterClass();这句。

注册窗口类后,这个注册身份还得依附一个实体上。接下来小伙子们就要去找办公地点,而程序员要为窗口类找一个可以依附的窗口,所以就有了第15行的创建窗口。就有了hWnd=CreateWindow();这句。

公司有了办公地点这个实体后,小伙子们就开始营业了,并且时刻关注本领域的销售市场变化,好让辛苦成立的公司运行下去,而MFC的窗口也就是靠着上述最后两句程序存在在你的电脑内。
  
2.CRect类
CRect类是由tagRECT结构派生来。此类包含的成员变量是一个长方形的左上角和右下角的点坐标。它有6个重载的构造函数。下面举例介绍如何创建一个长方形,CRect类的其中一个构造函数如下:

CRect(
int l,  //定义长方形的左上角点的x坐标
int t,  //定义长方形的左上角点的y坐标
int r,  //定义长方形的右下角点的x坐标
int b  //定义长方形的右下角点的y坐标
)

应用如下,它定义了一个左上角在(0,0)、右下角在(10,50)处的长方形。
CRect rect(0,0,10,50);

3.CPoint类
CPoint类由tagPOINT结构派生来。此类的成员变量是点的x和y坐标。它有5个重载的构造函数。CPoint类的其中一个构造函数如下:

CPoint(
int initX,  //点的x坐标值
int initY  //点的y坐标值
)

创建一个位于坐标系中(20,30)处的一个点,代码如下。
CPoint pt(20,30);  

 4.CString类
CString类没有基类,它有6个重载的构造函数。下面代码的作用是取出定义好的一个CString对象的长度。

 CString name="Microsoft";  //定义一个CString对象并赋值
 int name length =0;  //定义一个整型变量,并初始化
 name_length=name.GetLength();  //将名字的长度值存放到整型变量中

好了,说到这里,再让我们来看看visual c++常见应用程序框架,

对于刚入门的读者来说,最常用的工程有4种:

Win32应用程序、

Win32控制台程序、

MFC应用程序、

MFC动态链接库。

我们来一个一个看一下。

一、Win32应用程序(Win32 Application)
首先得声明下Win32 Application的入口函数是WinMain()。另外它是基于Windows平台的32位开发环境开发的应用程序,也是普通的窗口应用程序。因此要有注册窗口、创建窗口、显示窗口、消息处理等动作。
1.创建项目
新建一个Win32 Application 工程,打开VS开发环境,选择“文件—新建—项目...”命令,出现新建项目对话框。左上角“项目类型”选择Visual C++的Win32,其对应的模板选“Win32项目”。左下方的名称可以自己决定,存储位置也是随便定。单击“确定”按钮之后,出现Win32应用程序向导,单击对话框左侧的“应用程序设置”选项,在选项“应用程序类型”中应是“Windows应用程序”。“附加选项”中选中“空项目”复选框,弄好后单击右下方的“完成”按钮。
2.如何编写程序
一个基本的Win32 应用程序要包括两个函数,即WinMain()和实现窗口操作的函数。如果程序员没有写这两个函数,该程序是不会被执行,也不会有窗口出现的。因此介绍下这两个函数的基本形式。
(1)WinMain()函数
这个函数在一个项目中有且只能有一个,下面代码是它的函数体。

int WINAPI WinMain(
    HINSTANCE hInstance,/指向当前实例的句柄
    HINSTANCE hPrevInstance,//指向先前实例的句柄
    LPSTR lpCmdLine, //命令行
    int nCmdShow//显示状态
)
{
...    //具体代码写入区
} 

在这个函数中,首先要创建一个窗口类,然后给这个窗口类的各种属性赋值,之后注册窗口类、显示窗口、更新窗口。这样基本工作已经做好,但最重要的是建立消息的循环,否则窗口是不会时刻显示当前界面的。
(2)实现窗口操作函数
消息循环有了,还得有消息的触发,这就是实现窗口的操作函数,那它的函数定义体如下代码。这里的函数名字可由你随便定,这里用WinConProc()。

LRESULT CALLBACK WinConProc(
    HWND hwnd,  //窗口句柄
    UINT uMsg, //消息标识符
    WPARAM  wParam,   //第一个消息参数
    LPARAM  lParam   //第二个消息参数
)
{
...    //具体代码写入区
} 

3.应用场合
Win32应用程序是针对需要重新编写窗口,觉得MFC的窗口不美观,或者想实地考察下MFC运行原理的程序员使用。


二、Win32控制台程序(Win32 Console Application)
Win32 Console Application的入口函数是mainO,它的运行结果窗口是MS-DOS的样子,因为它是基于DOS平台开发的应用程序。
1.创建项目
不再说这块了,大家都知道。
2.如何编写程序
此项目必须要有也只能有一个main()函数,如果读者的代码量很大,可以将main()里的代码分成几个小块,然后分属于不同的函数,不过这些函数要在main()前面声明一下。
3.应用场合
Win32控制台程序适用于刚接触VS的读者用来练手,或者是那些需要测试完善的代码,以便移植到其他框架下使用。

三、MFC应用程序(MFC Application)
如果读者想做界面并且不想自己从头开发的话,第一个接触的就是MFC应用程序。MFC应用程序的入口函数也是WinMain(),虽然大家在工作区的文件中看不到WinMain(),但WinMain()是真实存在的。大家可以设置断点找到WinMain()。
1.创建项目
新建一个MFC Application项目,打开VS,选择“文件一新建→项目...”命令,左上角“项目类型”选择Visual C++的MFC,其对应的模板选择"MFC应用程序”。左下方的名称可以自己决定,如取名为"MFC_Application”,存储位置也是随便定,也可以单击“浏览”按钮选择。最后单击“确定”按钮之后出现MFC应用程序向导,单击对话框左侧的“应用程序类型”选项,在“应用程序类型”选项区域中选择“单文档”。“MFC使用”等选项都默认,再点完成按钮。
这里需要重点介绍的是“MFC使用”的两种情况:
(1)在共享DLL中使用MFC:当项目进行到后期要做个.exe 的可执行文件,此时 MFC的一些DLL并没有被包含在.exe 文件中,而运行时会用到这些文件。因此当用户的计算机上没有安装相应的开发环境时就会出现“无法启动程序….,由于应用程序配置不正确,未能启动此应用程序”这样的错误。
(2)在静态库中使用MFC:在生成.exe 文件时就将DLL中的相关代码写入了.exe文件,所以在没有安装开发环境的计算机上也可以运行,缺点是这样的.exe 文件大小比“在共享DLL中使用MFC”大。
此时就创建好了一个MFC应用程序,在不添加任何代码时,这样一个MFC单文档程序就能运行生产一个窗口,窗口中会有左上角图标、标题、菜单、工具栏、状态栏,都是默认情况下的运行结果。可以根据公司的需求或个人喜好修改出更漂亮的界面。
2.如何编写程序
这个项目虽然也有入口函数,但它不需要大家去修改,而只需在适当的函数中添加自己代码或修改原有的代码即可。下面举两个例子简单介绍用何种函数具体写什么去修改界面中的何处。
(1)修改菜单、工具栏和状态栏
函数:
int OnCreate (LPCREATESTRUCT lpCreateStruct);
所在文件:MainFrm.cpp
代码类型:参看文件中原始代码,并找MSDN寻求帮助。
(2)修改界面中的空白区
函数:
void OnDraw(CDC* pDC):
所在文件:MFC_ApplicationView.cpp
代码类型:贴图、输出文字等代码。
3.应用场合
 以MFC应用程序为基本框架继续开发自己的软件,可以省去程序员一大部分工作内容。

四、创建MFC动态链接库(MFC DLL)
MFC DLL是针对MFC应用程序的动态链接库,它的入口函数是DllMain()。DllMain()就类似于MFC应用程序中的WinMain(),在自动生成的文件也是看不到的,必须追踪到内部文件,因此也不必去重新编辑这个函数。要做的就是找到接口函数写入相应的代码即可,下面简单介绍 MFC DLL如何创建、怎样编写及它的应用场合。
1.创建项目
新建一个名为MFC DLL的MFC DLL项目,打开VS开发环境,选择“文件→新建→项目..”命令,出现新建项目对话框。左上角“项目类型:”选择Visual C++的MFC,其对应的模板选择"MFC DLL"。左下方的名称可以自己决定,本项目取名为"MFC DII”,存储位置也是随便定,读者也可以单击“浏览”按钮选择。最后单击“确定”按钮之后出现MFC动态链接库向导,单击对话框左侧的“应用程序设置”选项,在选项“DLL类型”中选择“使用共享MFC DLL的规则DLL”单选按钮。其他的都保持默认状态,弄好后单击右下方的“完成”按钮。
这种项目运行结果是没有窗口的,因为它生成的并不是可执行文件,而是以.dll、.lib为后缀名的两上文件。如果想看结果,只需要将其复制粘贴到可执行程序的当前路径下,并且让可执行程序调用其结果即可。
2.如何编写程序
它的操作与MFC应用程序相似。
3.应用场合
当所编写的程序不希望被权限之外的人看到源代码,以期保护原作者的权益,或者代码被封装成接口让别人使用,这样即使不懂源代码原理的读者也可以凭借知道的输入与输出参数运用它。

各位小伙伴,这次我们就说到这里,我感觉我写的还是不够简单易懂,等我重新想一下,看看有没有什么其他写法能让大家再好懂一些。下次我们再深入研究windows MFC,相信你一定能喜欢上windows MFC。

作者简介:荔园微风,1981年生,高级工程师,浙大工学硕士,软件工程项目主管,做过程序员、软件设计师、系统架构师,早期的Windows程序员,Visual Studio忠实用户,C/C++使用者,是一位在计算机界学习、拼搏、奋斗了25年的老将,经历了UNIX时代、桌面WIN32时代、Web应用时代、云计算时代、手机安卓时代、大数据时代、ICT时代、AI深度学习时代、智能机器时代,我不知道未来还会有什么时代,只记得这一路走来,充满着艰辛与收获,愿同大家一起走下去,充满希望的走下去。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值