构造最小的MFC程序
我们还希望这两类对象能够独立于程序存在,需要的时候能够在程序的合适位置创建即可。从纯粹MFC的角度解决所提到的两类对象是完全可能的,但这样会带来很大的局限,也十分可惜。因此,结合现代的软件技术,我们应该从更广泛的意义上考虑这个问题,由此挖掘出MFC框架与现在主流软件技术的强有力的结合点。我们着重考虑基于COM、.NET、Java等框架考虑实现这两种对象的可能性;本文中,我们工作的基础是.NET。
步骤/方法
- 01
我们就开始一个精简MFC程序的过程吧。我们记如下类型代码段为(a): CMultiDocTemplate* pDocTemplate; pDocTemplate = new CMultiDocTemplate( IDR_MsdnPluginSamplTYPE, RUNTIME_CLASS(CMsdnPluginSampleDoc), RUNTIME_CLASS(CChildFrame), RUNTIME_CLASS(CUserCtrlView)); if (!pDocTemplate) return FALSE; AddDocTemplate(pDocTemplate); 而将如下类型代码段记为(b): CMainFrame* pMainFrame = new CMainFrame; if (!pMainFrame || !pMainFrame->LoadFrame(IDR_MAINFRAME)) return FALSE; m_pMainWnd = pMainFrame; pMainFrame->ShowWindow(m_nCmdShow);
- 02
我们的思路是,首先在常规MFC多文档程序中删除上述与主窗口和文档相关的创建代码,使原生应用程序空无一物。然后,创建新的工程,在其中完成主窗口和文档的创建工作;最后一步自然是把它们装回去。 先进行第一步,我们按照常规的步骤生成一个标准的MFC多文档程序,将(a)、(b)对应的代码删除掉,再删除所有与(a)、(b)相关的所有文件(注意保留应用程序对象对应的文件),并适当调整使这个程序能够正确编译。经过以上处理,将得到一个最小的MFC程序,这个程序中除了一个应用程序对象和一个CAboutDlg之外,什么都没有。因此,运行时什么都不会发生。
- 03
现在,一个有意思的问题出现了:如何寻找一个合适的途径,使得(a)、(b)中的代码合理地“回归”到我们刚刚得到的最小的MFC程序中?我们回顾一下:(a)的目的仅仅是要填充一个队列。如果忽略具体的软件需求,只要是一个有效的CMultiDocTemplate*指针,只要这个指针能够顺利地传递到(a),填充就能顺利进行,并且填充过程不具备排斥性。这意味着什么?这意味着如果能找到合适的办法,你就可以填充任意多数量的文档模板! (b)的目的是实例化一个窗口对象,创建、加载并匹配给MFC的主线程,但并不局限于规定的窗口类型。虽然这个过程对每个程序的运行时只有一次,正像一个人或者一个公司可以根据意愿选择自己的住所或办公地一样,如果找到合适的办法,一个程序完全可以根据场合匹配适当的主窗口。为了实现(a)、(b)回归到原来的程序,我们需要在原始程序的初始化工程中嵌入两个“回调机制”:一个用于加载(a),另一个用于加载(b)。 现在,可以形成策略了:我们需要两类“对象”,一类用来解决(a),另一类用来解决(b)。