先破后立让MFC与.NET完美结合——经典与现代的结合:在MFC中集成.NET框架_第1页
先破后立让MFC与.NET完美结合——经典与现代的结合:在MFC中集成.NET框架_第2页
先破后立让MFC与.NET完美结合——经典与现代的结合:在MFC中集成.NET框架_第3页
先破后立让MFC与.NET完美结合——经典与现代的结合:在MFC中集成.NET框架_第4页
先破后立让MFC与.NET完美结合——经典与现代的结合:在MFC中集成.NET框架_第5页
已阅读5页,还剩8页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、先破后立,让MFC与NET完美结合经典与现代的结合:在MFC中集成.NET框架士口信大家都有过这样的童年经历:拆东西.I'口从自己的小玩具到自行车,从古老的机械闹钟到半导体收音机,往往没有能够逃过我们的双手的.后来,上中学的时候老师给我们讲了"庖丁解牛",让我们为庖丁"恢恢乎游刃有余"的技术而惊叹.童年时的拆解是为了满足自己的好奇心,庖丁的拆解是为了更快更多地得到牛肉;而对一项技术进行拆解,能得到什/厶呢宁答案是这个拆解的过程让我们更深入地理解了这项技术,进而将掌握到的原理应用在实践中,产生更加先进的技术.本期专题讨论的对MFO进行改造的技术就是

2、这个道理.在十几年前MFO曾帮助微软赢得了c/c+编译器和开发环境大战,在后来的很长一段时间内,Visualc+这款优秀的开发环境甚至成了它的代名词.尽管现在.NET的市场在不断扩大,但仍然有很多开发者热衷于MFO,仍7曩m2005旧是强大而稳定的.然而随着.NET技术越来越深入人心,8年来一直未有重大革新的MFO多少有些"人老珠黄",如何才能让它重获青春,在今天这种纷繁复杂的计算机世界中依旧发挥其强大的功效呢宁本期技术专题栏目的作者孙辉先生有着近十年的MFO开发经验,他对于MFO内部的机理非常熟悉,"解"MFO这头"牛"不在话下.然

3、而,孙辉比庖丁的高明之处在于,他不仅"解牛",还可以还"牛"以新生.在本期技术专题中,孙辉首先对传统的基于MFO框架的应用程序进行了解剖,得到了一个最简单的"骨架"和一大堆"零件"然后使用.NET控件和HTML,Flash等元素加工了新的"零件"并重新进行了"组装".经过此番"手术",传统MFO应用程序的老面孔换了新颜,同时与.NET,Flash等先进技术的紧密结合也使其在新的时代里更具生命力.作者/孙辉M经典与现代的结合在MFC中集成_NET框架本文讲述

4、了在MFC中使用托管扩展的基本方法,包括对偶.NET对象,宿主.NET控件和与.NET对象交互等技术.以这些技术将是贯穿本专题的基本技术脉络,以此为基础才能打造丰富,前卫的MFC应用程序.fCc+4.2至令将近8年的时间,MFC的主体特征没有出现明显的变化,依旧是"古老"的面孔,囡此关于这个类库的种种评论自然是情理之中的事情了.从我个人的观点上看,MFC功能依旧健壮,强大,而且是业界少有的,稳定的,经过足够长历史考验的开发框架.深入研究这个类库,你会找到酒越酿越醇的感觉.MFC的一个成功因素之就足提供了?套完整的Document/View框架,然而这一点电足许多针对MFC批

5、评的矛头指向.也许是由十这个框架太经典,使人仃】看上去MFC再"亭亭玉市",向是"人老珠黄",以于打开今天的VisualStudioIDE的时候,多少会有点不协调的感觉:比起其它基于.NET框架的开发语言,HMFCJ发会显得很"土气""孤独"没有RAD机制,明显的缺乏与其它时髦对象的"操作"能力,r而且严格恪守自己的领地.每当生成一个基丁文档的MFC程序,我们总是看到一张沧桑的面孔,女r像刘姥姥进入大观同,与周围时髦的c#,VB.NErr等存在明显的"代沟"j"不相

6、容".曾经有很多人川我MFC还有前途吗?是否已经行将就木?羌于是MFC还是.NET的讨论时隐时现,不绝r耳.CLR是个党满魅力的世界,这种魅力,使得C#,VB.NET等变得光彩夺目.然而,MFC并没有衰老,如果你深入的了解MFC,你会发脱,MFC完全l1J以C#,VB.NET争奇斗艳在MFC项目中使用托管扩展.4',i4/iqiJNETFralneWork提供的托管扩展芷持确保了住MFC项目踅持托管扩展(c】_R).开发者口J以使MFC工程(本文我们将使用Test作为工程名称)通过打开项口的托管扩展属性外关,来增加编译器的托管支持刈,I埘啄在打开托管扩展编译开关以后,您就可以

7、在MFC项日中使H托管对象了,通常的做法是:为每个重要的MFC埘象配一个托管对象以眵成个对偶对,彼此匹配的对象包含lIi'l对方的指针,这样,其他.NET对象可以通过对偶对中的.NET刈象操作ML,C埘象;而其他MFC对象可以通过对偶对中的MFC对象操作NET对象(如图1)存VisualStudioNET中,没有提供关于添加托管c+类埘象的向导,因此,你可以先添加个基f托管c+的Component对象(如罔2)图1:对偶托管对象200575图2:AddClass向导:增加托管C+Component对象添加了该tesDocObject托管组件对象之后,将该对象的基类改为Object,并删

8、除一些代码得到一个最小托管类:.gG嚣如1.s_.c一:【.c."f1v.l经过以上步骤,VisualStudio,NET生成的代码被装进了MFC程序,当然完全可以手动创建,h文件和.cpp文件,输入相应的代码,然后把它们添加到当前工程.由于以上步骤在托管扩展编程中经常遇到,因此,将上述过程自动化是必要的,有鉴于此,我们在附赠的光盘中提供了完整的添加,NET对象的Wizard.住MFCIF托铃类一tl定义托箭成泌变在MFC类中使用托管对象,提供对象的声明和初始化方法与传统的方法略有不同.以在文档类CtestDoc中添加一个托管成员变量为例,声明托管对象的代码如下0UD4G.gcroo

9、t<test:ttestOocOblect*>mDtestOocObJ,gcroot类型安全包装模板可以将托管参考类型指针作为成员变量嵌入到非托管类中,该变量就可以像其他类型的变量一样使用了.在CtestDoc的成员函数InitialDocument中创建这个对象,代码如下sragmapush盘mG.ro一,ew,.c.bw【l_testD(】_:()c#Dragmapopmacro(')由于testDocObject是一个托管参考类型,它总被分配在CLR堆上,所以自然不能使用在afx.h中定义的new操作符来直接初始化该对象以避免该托管对象在非托管的本地c

10、+堆上创建导致的错误.在托管对象中声明MFC对象,与常规方法一致.掌握了上述的基本托管类和对象在传统MFC项目中的对偶使就可以保证您充分使用.NET框架所提供的丰富的类库支鹈2005田J1厦HUxteIIOlIlgIVII?LPPitcatlOIISWIIFIme.1Framework)一书,相信会很有帮助.宿主.NET控件宿:t-1.NET控件的理沦基础在,NETFramework的世界里,功能丰富的NET控件无疑是光彩夺目的明珠,MFC程序自然想联姻这些华丽的事物.由于MFc框架不提供对.NET控件的直接支持,从而导致MFc后天的失落(缺乏类似C#,VB.NET特有的可视化设计机制以及自由

11、的控件组织功能),这一点多少成为MFC远离.NET世界的一种合理的客观原因.但是,我们注意到:,NET控件本质上就是ActiveX控件,二者之间的重要区别是注册方式不同Ac廿vex控件是全局的,在系统注册表中注册;而,NET控件既可以在全局AssemblyCache中注册,也可以放在局部的目录中,相应的,在程序中获取它们相关信息的方式是不同的.但是,一旦.NET控件的基本信息被我们"捕获",我们就可以使用与创建ActiveX控件一致的方法将,NET控件创建到MFC项目中.我们知道,MFC是通过COleControlSite类创建ActiveX控件的,由于针对用于Active

12、:(控件的COleControlSite类不适用于.NET控件,因此必图3:MFC框架中ActiveX控件的创建须重新派生一个新类CWFControlSite来提供必要的支持,通过一个CWFControlWrapper类将一个.NET控件包装在一个CWnd窗体中,并将包装后的窗体"安置"在CwFControlSite内.CWFControlWrapper类代码如下:retn.【¨'Kc()nr.m=:黑S:i;毫.=.下一步,要设计一个通用的CUserCtrlView类(从CView类派生),使得在CWFControlSite中指定的.NET控件可以像在C

13、OleControlSite中指定的Active)控件一样显示给用户.正象每个Active)控件必需用一个CWnd对象进行创建一样,一个支持.NET控件的CView类需要一个对应的CWnd对象CWFControlWrapper就是针对这个目的设计的,图4:MFC框架中.NET控件的创建通过CWFControlWrapper对象,MFC程序可以得到NET对象对应的IUnknow,IDispatch.稍后我们介绍CUserCtrlView类的具体设计和使用方法.NET控件的消息处理一般而言,控件的对话框消息处理是一个极为关键的问题,在网上能找到的MFC中宿主控件的解决方法中,均没有实现NET控件的

14、对话框消息处理,一个明显的特征是不能处理.Tab,键消息.为此,我们重载了CUserCtrlView的PreTranslateMessage函数:BoOLbRet=ALSE'.:(s.KpPa>TransateAcceerat.r(pMsg)7TRUE?FALSE,f(CVlew+DreTransateMessagoMsg)returnTRUE,cFtameWnd*pFramewnd=GetTo#l_evetame()l(p#ramewndNlJLL&&DFrameWr>mHebMode)returnFALSE/startwi

15、thfirstparentfrqe0FtameWnd=GetiDarentFrame()器;.F:暑.6.Dar.n_.()FeturnbRet这样可以使得CUserCtrWiew可以正确的处理.NETc0ntrol的对话框消息.嘲If=lRAD世界接下来我们看看如何在工程中插入一个.NET用户自定义控件.我们增加一个新的托管类testControl,代码如下:篙:嚣.pucSystem:wr_d.ws:Foms:lusecon".%篓tem:w(efSystemComponentModelContainer*componentsthis>labef=newSystem

16、:.Windows:FoFms:Label()this>SusDendLayout().this>labef>Location=Sysfem:Drawng:.polnt(6,24his>labef一>Name=Sabefthis>labef>Size=System:Drawing:+Size(206,f6)this>labef一)TDbPndex0,this>label1一>Tet=S"WelcometoTZMFCNETI"thPs&a

17、mp;gt;Controls一>Add(this>labef1,this一>Name=StestCoRtro'this>Size=SystemDrawing:.Size(240.f60)lthis一>Resumerayout(false);注意,testControl类继承自UserContml类,用户控件是开发者创建的任何控件,您可以将多个NET控件组织在一起,添加功能代码,然后把它作为一个更综合一些的控件来使用,使用每一个用户控件和使用其他的.NET标准控件的步骤都是没有区别的.在上面的代码中,我们自定义的用户控

18、件仅包含了一个.NETtabel控件.到目前为止,我们已经可以在原生MFC项目中成功插入.NET控件.然而,因为上面的.NET控件的插入是纯手工方式的,不直观且很难驾驭,一个聪明的办法是实现一个集成在VisualStudio.NETIDE中的Wizard,以使得MFC工程中可以直接使用可视设计器,在随机光盘中,我们提供了相关的wizard,安装后您就可以直接在MFC项目中插入并可视化设计.NET用户控件了.通过集成的Wizard,传统的MFC可以与现代的NETRAD机制完美的结合在一起,使得你既可以得到传统c+的优雅,又可以享有现代RAD机制的风韵,对资源的整合力度也极大地扩展了.使用CUse

19、rCtrlView类御建.豫示.NET控件我们为每个MFC文档类增加一个与之对偶的托管对象类从而得到了一对对偶对.这个与MFC一个托管对象字典,每一个需要在文档中创建的托管控件会根据一个别名舔加到这个字典中备查.当文档对象被实例化的时候,其对偶的托管对象也将被实例化,而且有待创建的控件也会被实例化并插入到相关的字典中,同时该对偶托管对象被传递给MFC应用程序对象中的指针变量mpManagedCnnObj,CUserCtrlVbw类在调用OnInitialUpdate时,会通过垒局变量theApp得到mpManagedCnnObj,m.pManagedCnnObj就是与MFC文档对偶的托管对象,

20、然后用.NET机制根据别名检索从m_pManagedCnnObj得到所要创建的控件的实例,之后调用SetControl函数将该控件创建出来:voldCUserCtrVlew:SetC0ntr0SystemO"ect*contrd)mControDUnkContro=reiRterDretCaSt<IUnknown*>(System:Runtime;IqterooServices:Margha:-GetlUnknownForObiec(contro1)ToPointer0),2005m雾dnCISIDCIs;d=0,0.0,0,0,0,0,00,0,0dsi

21、d,0,WSVISIBIEWSCHILD,mControlModifyStvleEx(0,WSE×00NR0LPAREN_n,CUserCtrWiew的OnInitiaUIX:late代码如下voidCt0sentrlVew:?0nlntlalUPdate(Jif(mbCtIC日ted&&m一."WlnCtrll=T(?)ftleA一pm;GDMeanagedCnsnOcb)nrj->eGetT.yObiect'0口:NewObiect*2Jr0ect)ObJ=NUIIString*pString:NewSFing*1;

22、roString0l_;mStrWInCtrll,ISroDert!Rfom【)oDertFlnfo=t)Ge1Pr0O0rty(sPnltem')DOb1)ProDerylrfo->GetValue(theApDrnpM8nagedCnnoDj,pStrlng)if(oO0l1P=pO,a1=DString,theApompMahagedCiYObI,PCStrirlgstrlrlfoexp>Message现在,你可以在MFC程序中创建.NET控件了,我们的第一个宿主.NET控件的程序运行结果如图:Eil.1lt3iIi?bD口l忘l国tl隆95"

23、;7铺疆瓣:髂竺竺!Il:,'llr|.由厂厂一厂图5:运行时NET控件检索.NETJt|JI控仆一个MFC应用中可能包含多个UserControI76m15d2005这些控件一般以动态链接库的形式存在.由于.NET控件一般不在全局注册,因此,.NET程序需要一种组件检索机制,使得它们能够正确的发现运行时用到的组件.NET框架支持为每一个应用程序提供一个XML格式的配置文件,配置文件的名称是"程序名.exe.config,例如,名为test.exe的应用程序的配置文件为:test.exe.config,配置文件相当于局部的注II表,该文件必须与可执行文件位于同一个目录中.开发

24、者可以在这个文件中更改,保存程序的设置,设置程序集绑定策略和其他的应用程序配置信息.NET框架提供了专门的类以帮助开发人员操作该文件.下面是一段典型的配置文件片段:<?xmlversion=10encoding=.UTF-8'><c0nTgra0n)(t1e)<assemt/lyB,ndlngIn='uFn.schemas-mrc,rosott-com-asmv)<'probing0iratePath=bin.usercontrol,COmDonen【0cte0ate/><assembls/Bnding></runtime></corotguration><con丘guration>元素是CLR和.NETFramework应用程序所使用的每个配置文件中的根元素.<runti

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论