升级原有MFC程序的方法之一是将原有程序封装入OCX控件,这样既能将OCX控件装入浏览器作为网络程序,也能将其装入C#、JAVA界面中,既保留原有的界面和逻辑也能使用更现代化的界面。在封装过程中会有一些问题,从网上可以找到如何将SDI程序封装为OCX然后嵌入其它程序中,并且在VS08中,可以使用相同方法将MDI程序装入OCX中。
顺带简单说一下方法:
1、重载doctemplate,重载onopendocument和createnewframe;
2、重载framewnd,在第三步中使用自己的framewnd;
3、 在newframe中将原有的loadframe改掉,改为createwindow将新的window作为frame使用,其中有几个valid_assert的类型验证改成自己的类型就行了,而且新创建的window要以olecontrol为parentwindow,也就是说一个ctrl对应一个frame;
4、自己写finddoctemplate,需要打开新的文档时,自己finddoctemplate,然后调用opendocument,就会进入自己的重载中,其中还可能有一些小的问题需要根据各自的情况解决。
但是在VS2012(2010没试过不知道)中,Microsoft在MFC11中增加了很多验证的流程,以保证MDI的层次结构。但这就导致了我们不能使用SDI的方式来欺骗系统了,解决方法其实很简单,就是将MDI改成SDI,具体的需要改两处,一个是doctemplate的父类改成singledoctemplate,另一个是framewnd不能从mutiframewnd继承,需要从framewnd继承。 再者,就是不在启动时创建那么多doctemplate,在用的时候再创建doctemplate。虽然简单,也困扰了我将近一周的时间。
而后我回头小研究了一下,在OCX中,有APP,有Ctrl,而因为OCX从本质上讲是一个DLL,而系统在一个进程中只会load一份DLL代码,所以进程无论几次load这个OCX,在进程中其实都只有一个OCX,这个就是那个APP,而出现不同window,是由于每次需要一个新的window的时候,OCX会动态创建一个ctrl, 从这个角度来讲,OCX本身的结构就是一个MDI的结构,所以在VS2012中Microsoft增加了新的验证机制保证每个窗口只能创建一个SDI的窗口。
记录一下备忘!:)