📄 c-c++ mfc.htm
字号:
</P>
<P
align=justify> CFrameWnd:Create在函数中调用CreateEx(CWnd有这个成员函数,但其派生类CFrameWnd并没有,所以这里调用的实际上是CWnd:CreateEx);后者又调用PreCreateWindow虚拟函数(它在CWnd及其派生类CFrameWnd都有定义,所以实际上调用的是CFrameWnd::PreCreateWindow),这个函数调用了AfxDeferRegisterClass宏,它表示如果变量afxRegisteredClass的值显示系统已经注册了fClass
这种窗口类,MFC啥也不做,否则就调用AfxEndDeferRegisterClass(fClass){它调用两个函数完成实际的窗口类注册操作,一个是RegisterWithIcon,一个是AfxRegisterClass},准备注册之。
</P>
<P align=justify> 窗口显示与更新;
CMyFrameWnd::CMyFrameWnd结束后,窗口已经诞生出来;程序又回到CMyWinApp::InitInstance,于是调用ShowWindow函数令窗口显示出来,并调用UpdateWindow函数令Hello程序送出WM-PAINT
</P>
<P align=justify>CWinApp::Run----程序生命的活水源头 </P>
<P
align=justify>Run又是CWinApp的一个虚拟函数,我们没有改写它(大部分情况下也不需要改它),所以上述操作相当于调用CWinApp::Run
</P>
<P align=justify>WinMain已由MFC提供,窗口类已由MFC注册完成,连窗口函数也都由MFC提供 </P>
<P align=justify>把消息与处理函数连接在一起:Message Map机制 </P>
<P
align=justify>MFC提供给应用程序使用的“很方便的接口”是两组宏,以Hello为例,第一个操作是在Hello.h的CMyFrameWnd加上DECLARE-MESSAGE-MAP;第二个操作是在Hello.cpp的任何位置(当然不能在函数内)使用宏
</P>
<P align=justify>BEGIN_MESSAGE_MAP(CMyFrameWnd, CFrameWnd) </P>
<P align=justify>ON_COMMAND(IDM_ABOUT, OnAbout) </P>
<P align=justify>ON_WM_PAINT() </P>
<P align=justify>END_MESSAGE_MAP() </P>
<P align=justify>来龙去脉总整理 </P>
<P align=justify>程序的诞生 </P>
<P align=justify>Application object 产生, 内存于是获得配置,初值亦设立了。 </P>
<P align=justify>AfxWinMain执行AfxWinInit,后者又调有AfxInitThread,把消息队列尽量加大到96
</P>
<P align=justify>AfxWinMain执行InitApplication。这是CWinApp的虚拟函数,我们通常不改写它 </P>
<P align=justify>AfxWinMain执行InitInstance。这是CWinApp的虚拟函数,我们必须改写它 </P>
<P align=justify>CMyWinApp::InitInstance “new”了一个CMyFrameWnd对象 </P>
<P
align=justify>CmyFrameWnd构造函数调用Create,产生主窗口。我们在Create参数中指定的窗口类是NULL,于是MFC根据窗口种类,自行为我们注册一个名为“AfxFrameOrView42d”的窗口类。
</P>
<P align=justify>回到InitInstance中继续执行ShowWindow,显示窗口 </P>
<P align=justify>执行UpdateWindow,于是发出WM-PAINT </P>
<P align=justify>回到AfxWinMain,执行Run,进入消息循环。 </P>
<P align=justify>程序开始运行: </P>
<P align=justify>程序获得WM-PAINT消息(由CWinApp::Run中的::GetMessage循环) </P>
<P align=justify>WM-PAINT经由::DispatchMessage送到窗口函数CWnd::DefWindowProc中。
</P>
<P align=justify>CWnd::DefWindowProc将消息传递到消息映射表格 </P>
<P
align=justify>传递过程中发现有相符项目,于是调用项目中对应的函数。此函数是利用BEGIN_MESSAGE_MAP和END_MESSAGE_MAP之间的宏设立起来的。
</P>
<P align=justify>标准消息的处理程序亦有标准命名,例如WM-PAINT必由OnPaint处理 </P>
<P align=justify>程序的死亡: </P>
<P align=justify>使用者单击File/Close,于是发出WM-CLOSE </P>
<P align=justify>CMyFrameWnd并没有设置WM-CLOSE处理程序,于是交给默认的处理程序 </P>
<P align=justify>默认函数对于WM-CLOSE的处理方式是调用::DestroyWindow,并因而发出WM-DESTROY
</P>
<P align=justify>默认的WM-DESTROY处理方式是调用::PostQuitMessage,因此发出WM-QUIT </P>
<P
align=justify>CWinApp::Run收到WM-QUIT后会结束内部之消息循环,然后调用ExitInstance,这是CWinApp的一个虚拟函数;如果CMyWinApp改写了ExitInstance,那么CWinApp::Run所调用的就是CMyWinApp::ExitInstance,否则就是CWinApp::ExitInstance
</P>
<P
align=justify>最后回到AfxWinMain,执行AfxWinTerm,结束程序</P></TD></TR></TBODY></TABLE><BR>
<TABLE height=6835 cellSpacing=1 cellPadding=1 width=758 align=center
bgColor=#000000 border=0>
<TBODY>
<TR bgColor=#5f7189>
<TD background="C-C++ MFC.files/bg_bar.gif" bgColor=#ffffff
height=24><FONT color=#000000><STRONG>应用MFC开发高级应用程序<FONT size=4><A id=VC4
name=VC4></A></FONT></STRONG><FONT
color=#000000>(文章来源:龚建伟老师的技术主页http://www.gjwtech.com)</FONT></FONT></TD></TR>
<TR bgColor=#5f7189>
<TD width="22%" bgColor=#ffffff height=6812><FONT
color=#000000><STRONG>目次</STRONG>:<A
href="http://skygray.ee.tokushima-u.ac.jp/~wangfei/research/vc/vc-1.html#VC41">一、使用C/C++及VC与VB之比较</A>
<A
href="http://skygray.ee.tokushima-u.ac.jp/~wangfei/research/vc/vc-1.html#VC42">二、MFC编程综述</A>
<A
href="http://skygray.ee.tokushima-u.ac.jp/~wangfei/research/vc/vc-1.html#VC42">三、使用单文档-多视结构</A>
</FONT><FONT color=#000000><A
href="http://skygray.ee.tokushima-u.ac.jp/~wangfei/research/vc/vc-1.html#VC44">四、使用DDE服务</A>
<A
href="http://skygray.ee.tokushima-u.ac.jp/~wangfei/research/vc/vc-1.html#VC45">五、使用3D控制</A>
<A
href="http://skygray.ee.tokushima-u.ac.jp/~wangfei/research/vc/vc-1.html#VC46">六、使用自定义消息</A> </FONT><FONT
color=#000000><A
href="http://skygray.ee.tokushima-u.ac.jp/~wangfei/research/vc/vc-1.html#VC47">七、使用不带文挡-视结构的MFC应用</A>
<A
href="http://www.gjwtech.com/vcandc/vc3cvbcompare.htm#%B0%CB%A1%A2MFC%D3%A6%D3%C3%B5%C4%C8%CB%B9%A4%D3%C5%BB%AF">八、MFC应用的人工优化</A></FONT>
<P align=left><FONT
color=#000000><BR><STRONG>[摘要]</STRONG>:目前在Windows下开发应用程序的工具虽然很多,但是C/C++作为一种非常成熟和高效的开发语言在大型复杂项目的开发中仍然得到了广泛应用。为了减轻程序开发负担,提高开发效率,各种流行的C++都提供了类库,本文就是针对如何在Visual
C++环境中使用MFC类库来开发高级程序所需要解决的一些问题进行了的探讨,重点讨论了利用MFC开发单文档多视应用程序和DDE应用程序的方法。</FONT></P>
<P align=left><FONT color=#000000><A id=VC41
name=VC41><B>一、使用C/C++</B></A></FONT></P>
<P align=left><FONT
color=#000000> 随着Windows系列操作系统的日益普遍,传统的基于DOS编程逐渐转向Windows下编程已经成为必然趋势。目前在Windows下开发应用程序的工具很多,典型的如Borland
C++、Visual C++、Visual
Baisic以及Delphi等等。每种开发工具都各有其特点,一般来讲用户可以根据自己的使用习惯和开发项目的性质来选择具体的开发语言。</FONT></P>
<P align=left><FONT color=#000000> Visual
Basic是一个被软件界称之为划时代的革新产品,该软件改变了人们开发Windows程序的方式,它采用交互式的可视化操作,使得人们开发Windows程序的每一过程都有直观形象的反馈,从而加速整个开发进程。Visual
Basic使得Windows程序设计人员不再只依赖于复杂的SDK编程,使得开发Windows程序非常容易,可以说,用户学习并使用VB来开发Windows应用的时间是最短的。Visual
Basic版本几经演变,目前已经发展到5.0。在4.0版本中,由于完全使用了面向对象的编程概念,同时具有Windows 3.1和Windows
95下的版本,因而使得其开发复杂程序的功能逐渐增强。VB5.0则抛弃了Windows
3.x的用户,只能在32位Windows中使用,据悉,该版本吸收了Delphi的成功策略,引入了本地代码(Native
Code)编译器,从而使得程序执行速度大大加快,克服了以往版本由于执行文件采用P-Code代码而导致运行速度慢的特点,根据微软的声明,该版本的采用本地代码编译后得到的应用程序在某些情况下执行速度较以往提高了10~20倍,执行速度可以直逼与采用Visual
C++编写的应用,而应用开发速度则是VB的强项,因此Visual Basic 5.0非常具有竞争性。目前Visual
Basic非常广泛地用于开发各种Windows程序,如数据库前端应用程序和多媒体应用等。但是,在作者看来,采用VB也有一定的缺点,原因有以下几点:</FONT></P>
<P align=left><FONT color=#000000>1. Visual
Basic来源于Basic语言,虽然经过微软的不断增强,但是仍然缺乏非常灵活的数据类型和编程策略,因而在开发一些项目必须的复杂数据结构遇到麻烦,如链表、图和二叉树等等。由于在中大型项目开发后期,开发工作不再以界面为主,而是在算法设计和底层软硬件工作,这就使VB开发项目的后期工作量大幅度增加,为了达到项目要求,经常需要再转向C/C++开发一些专用的动态连接库来解决问题。</FONT></P>
<P align=left><FONT color=#000000>2. Visual
Basic运行速度慢,前文讲过,采用P-Code代码虽然执行文件很小,但是在运行时需要解释执行,并且,它的运行必须有对应的VBRUN.DLL和所使用的VBX或者OCX支持。对于浮点操作密集或者循环嵌套很多的应用来说,VB没有采取特别的优化,因而执行速度远不如用C/C++和Fortran开发的应用速度快。VB
5.0虽然通过引入本地代码编译器大大弥补了这个缺陷,但是由于其只能运行于32位Windows环境因<BR>而在16位Windows上速度问题仍然得不到解决。虽然目前转向32位Windows的趋势非常强劲,但是不容忽视由于硬件的限制或者使用习惯等诸多原因,还有许多用户仍然在16位Windows上工作。在计算机十分普及的美国,96年使用16位Windows的用户仍然超过了使用32位Windows的用户,任何进行系统软件设计的人员都应该照顾到这些仍然使用16位Windows的用户。</FONT></P>
<P align=left><FONT color=#000000>3.
VB不能灵活地使用系统资源。熟悉Windows编程的人都知道,如果要直接访问硬件或者要编写对系统进行有效访问的应用程序,没有Windows
API函数的帮助则非常困难,但是令VB程序员失望的是,API函数是用C语言和汇编语言实现的,是为C编程准备的,如果要在VB里面使用这些上千个API函数则比较麻烦,特别是,如果设计人员不懂C语言则尤其困难。由于API函数的复杂性,而其本身不是为了方便VB编程而提供的,因此在VB里面调用API函数需要一定的技巧,这些技巧足够用一本很厚的书来表述。VB程序员可以从书店里找到好多本类似的书籍。可以说,任何一个VB程序员发展到一定阶段都需要与众多的API函数打交道。另外,由于VB不支持端口操作,因此,如果要编写类似数据采集等需要与硬件交互的程序则需要求救于C/C++语言。<BR><BR>4.
Visual
Basic项目分发和管理困难,其原因同上讲的,VB应用的运行不能脱离VB的运行库和所使用的控件,因此,如果开发人员要将VB应用分发给用户那么一定要带上VB的运行库和所使用的控件,并且要保证正确安装,这就导致即使一个非常简单的应用也需要附带大量其它相关支撑库程序,对于VB
4.0及更高版本,由于大量的使用了OLE控件(在VB中称为OCX),其安装更为复杂。</FONT></P>
<P align=left><FONT
color=#000000> Delphi软件是国际宝兰公司(Borland)的得意之作,也是备受软件界推崇,与VB一样,它完全是一个交互式的可视化开发平台,支持Client/Server应用程序的开发,其最新版本2.0可以开发Windows
3.x、Windows 95和Windows
NT的应用程序。Delphi开发速度也非常快,与VB相比,由于具有本地代码编译器因此它产生的可执行文件执行速度大大加快。Delphi软件是一个非常有竞争力的软件,采用的是面向对象的Object
pascal语言,支持硬件操作和API调用。但是由于采用的编程语言为Pascal,这种语言并不非常流行,许多程序设计人员完全不熟悉这种语言,因此极大地限制了该软件的使用,如果宝兰公司能够将Delphi软件提供的RAD开发机制引入到其Borland
C++中,则可能会形成一个非常成功的产品(目前该版本已经推出,即C++ Builder,笔者注)。</FONT></P>
<P align=left><FONT
color=#000000> VB和Delphi引入的可视化开发方法还有一个共同的缺点就是各个版本之间的兼容问题。一般来讲,采用这些可视化开发工具开发的应用程序在移植到高版本时不会遇到太大困难,但是一旦往相反方向移植则困难重重,有时甚至不可能。C/C++语言则不具有这种局限性,各个版本之间的相互移植并不困难,高版本往低版本移植一般只需重建工程文件即可大功告成。综上所述,根据作者的观点,如果要开发一个大型复杂的应用程序首选的还是C/C++,特别是在16位Windows下。虽然这会使前期工作增加,但是在项目的中后期将逐渐会领略到其优越性和开发效率,其灵活高效的执行代码适合于对速度和应用程序之间的协同性要求很高的场合。纯粹基于Windows
SDK来开发Windows程序是一项艰巨的工程,值得庆幸的是目前各种流行的C/C++开发工具都提供了类库开发框架来简化整个开发过程而又不失其固有的灵活高效性,不同的开发语言所提供的类库开发框架不同,如Borland
C++提供的OWL(Object Windows Library)和 Visual C++提供的MFC(Microsoft Fundmental
Class),这两种类库都封装了大量的Windows
API和Windows的开发元素而使得开发任务简化,两种类库各有其优点,据作者掌握的资料,采用MFC编写的应用程序执行代码更小,执行速度也更快,这大概是因为该软件的开发者是开发Windows操作系统的Microsoft公司的缘故吧,现在MFC正逐渐成为Windows下的类库开发标准,正被越来越多的其它C/C++编译工具所支持,如Watcom
C++。使用MC类库同时配合Visual
C++提供的AppWizard、ClassWizard和AppStudio可以大幅度提高开发效
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -