经过一段紧张的忙碌,TangramLite的第一个测试版本终于出炉了你可以在https://sourceforge.net/projects/tangramlite中下载源代码,TangramLite最初的定位是给团队里的年轻人提供一个学习Tangram框架开发思路的内部教材,基本工作在2004年8月份完成,以后一直闲置在机器里,也许是一个思路上的盲点,我近两年来一直没有真正认真考虑过这个东西的命运。两个月前,当我找到这个东西的备份时,有一种说不清楚的感觉,大体是:这些年来一直在埋头工作,却很少想给每个工作一个很具体的着落,同时也对这个框架感到陌生了,许多当初的构思已经记不清楚了……。TangramLite的原始框架是基于Visual Studio 2003中的C++框架开发的,关键的部分用ATL/MFC/Managed C++代码混合写成,可以支持Microsoft Visual Basic for Application集成。伴随着对关键代码的逐步解释,我逐渐意识到,这个框架还是具有一定实用价值的,因此,在团队里其他人熟悉这个框架的过程中,我有意识的将这个东西系统化,使之能够成为一个使多人受益的轻量级别的开发框架。
用什么样的思路介绍Tangram系列构思,是一个令我头痛多年的问题,我的许多朋友,包括CSDN的蒋涛、孟岩、袁德俊等都有许多不同的感受,这些技术出身的朋友,反馈中有许多微妙的差别。TangramLite里面包含Tangram的一些关键的构思,技术路径差别很大,也许更适合现在的开发者,因此,希望能够从这里找到一个思路上的突破。
TangramLite能做什么?同样也是一个不易表达的问题,因此从什么地方找介绍点,是这两个月煞费苦心的难点,最终,还是选择了从Microsoft的Internet Explorer作为出发点。经过多番改进,TangramLite已经从最初的在VS2003上的工作移植到Visual Studio 2005上,截止到2006年8月18日,已经完成了COM框架上的绝大多数工作,计划9月完成.NET框架下的开发工作。最终我们决定将这个框架的大部分工作作为一个基于GPL协议的开源项目,没有开源的部分,例如:Microsoft VBA相关的部分,由于与GPL协议相悖,故将来打算作为非开源性质的工作进行商业化。
TangramLite的出发点是从MFC的文档视图框架开始的,Document/View框架,是MFC类库最重要的特征之一,也是MFC框架最有争议的地方,传统的MFC框架的关键部分对Document/View框架的依赖性是众所周知的,这部分内容成就了MFC今天的地位,然而这部分工作,太“MFC”化了,以至于除了MFC系列应用之外,基本上对其他应用开发(例如VB、Delphi、.NET等等)几乎是毫无用处,此外,传统的MFC框架,特别是MDI框架由于关联于一个文档模板队列,使得软件的表现力大大的受到局限,TangramLite的基本技术出发点就定位在这里。
为什么许多MFC框架里的好的技术无法运用到VB、Delphi等开发环境之中?许多软件应用,在MFC框架中自然的可以被表示成一个文档,然而,更多时候,有用的文档却无法自然的体现为一个控件,这是MFC框架的一个不足,如果有一种办法,可以使得基于MFC开发的文档在另一个场合下能够体现为一个控件、.NET控件或IE插件,问题不就迎刃而解了吗?简单的说,TangramLite的核心构思就在这里。如图所示,几个MFC文档作为IE插件的情况:
在传统的MFC开发中,每个软件都有一个主窗口,典型的情况是一个经典的CMainFrame对象,之所以经典,是因为10几年来,这个名字几乎没有改变,这个对象,是MFC程序运行时的一个具体的可见表示,两个不同程序,体现为两个几乎完全不同的主框架窗口。有时如果需要整合这两个程序,由于主窗口分属不同的进程,因此,我们不得不寻求其他的解决办法。我们的问题是,有没有更好的开发办法,使得表示一个具体、局部应用的主框架窗口可以在运行时以某种方式自然的体现为另一个窗口(例如VB开发的窗口)的一个组成部分?我们的想法是设法使得主窗口与对应的应用程序的EXE文件实现分离,即在一个Dll中实现主窗口,然后让exe文件运行时与关联的主窗口对接,这样,传统的EXE文件仅仅是选择一个针对一个特定主窗口而言的加载方式,只要合理的进行构造,其他应用系统,例如IE、基于VB、Delphi等开发的应用系统以及C++开发的系统,均可以以自己的方式在关联进程中加载对应的主框架窗口,这一设想决定了TangramLite的一个基本策略是实现主框架窗口与特定exe文件进行剥离,这样在适当的时候,该主窗口可以被其他宿主系统(例如IE)自然接纳。基于同样的道理,每一个具体的文档类型也可以与特定的应用系统实现分离,分离后的文档模板,可以形成一个庞大的公共组件集合,同样可以被其他宿主系统(例如VB、Delphi、MFC、IE等等)动态加载、应用。这样,我们就形成了对TangramLite的基本动机的描述:实现一个特定MFC软件系统的exe、MainFrame、Document/View等3个层次的自然分离,使得一个特定的exe可以选择一个加载MainFrame、Document/View模板的方式。
TangramLite的应用程序是用特定的Wizard生成的,从结构上看,这类程序几乎是最小的,除了一个派生的CWinApp对象之外,你基本上看不到其他对象,这个对象重载了CWinApp类的函数,可以使得将来与Microsoft Visual Basic for Application自然对接。在框架内部,作为一个功能入口点,该对象作了必要的初始化工作,同时也作了其他工作,例如负责加载一个基于Flash动画的Splash:
(基于Flash的动感启动界面)
以及初始化一个个性化的MDI客户区背景(可以用HTML、Flash等对象作为一个个性化背景)。如果打算生成一个应用程序,只需在Visual Studio 2005 IDE中使用TangramLite提供的Wizard,你就可以直接得到一个应用程序框架:
在TangramLite中,几乎所有的东西都有对应的Wizard,在今后的工作中,我们会提供更多的代码向导。
根据Microsoft的.NET框架的构想,每个应用程序都会有一个配置文件,这个文件相当于局部的注册表,文件名为:App.exe.config,这里,App.exe为对应的可执行文件名称,这个文件是一个xml文件。在TangramLite框架中,这个文件十分重要,TangramLite可执行文件需要根据这个配置文件定位运行时的框架窗口,一个用于TangramLite框架的框架窗口与常规的MFC框架窗口几乎没有区别,之所以在一个组件库里实现这个对象是因为适当的时候,我们希望该对象能够体现为一个控件或插件,这一点与传统的MFC框架有相当大的差别,用TangramLite提供的Wizard,你可以直接生成一个MFC/ATL库,里面包含主框架的基本实现,便以后,需要在应用系统的配置文件中指定这个框架窗口的ID值,一个典型的配置文件如下:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
</appSettings>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<probing privatePath="bin;usercontrol;component;doctemplate"/>
</assemblyBinding>
</runtime>
<Tangram
MainAppType = "com"
MainAssemblyLib = "TangramLiteMainFrameExD"
MainAssemblyCategory= "TangramLiteMainFrameExD"
MainFrameAssembly = "TangramLiteMainFrameExD.Application.1"
ExternalAppAssembly = ""
VBAComponent= ""
DotNetComponent = ""
WorkSpaceGUID = "{9905F281-9C5D-440b-89AF-EE61D3FA548A}"
>
<Caption>Welcome To Tangram World!</Caption>
<WorkSpace>TangramLiteMainFrameD.App</WorkSpace>
<BackgroundType>html</BackgroundType>
<BackgroundFile>Background.htm</BackgroundFile>
<RegistryKey>TangramLiteMainFrameEx</RegistryKey>
<StdProfileSettings>4</StdProfileSettings>
<RunModel></RunModel>
<Skin>Merlin ENI/Merlin ENI.uis</Skin>
</Tangram>
</configuration>
其中“MainFrameAssembly = "TangramLiteMainFrameExD.Application.1"”用来指定主框架对象,这里,"TangramLiteMainFrameExD.Application.1"是主框架对象关联的ATL对象的ID值,配置文件中,MainAppType = "com"表明该应用系统是基于COM框架的,MainAssemblyCategory= "TangramLiteMainFrameExD"指定一个目录,这个目录在“x:/program files/Tangramuniversedocument/your company/app name”之中,这里,“your company”在应用程序的CwinApp对象在初始化过程中指定,“app name”是应用程序名称,每个基于TangramLite框架的应用系统都需要一个这样的目录,以便保存相关的信息,例如,应用系统的文档模板信息,就是保存在这个目录的DocumentTemplate文件夹中,具体的细节请考察“x:/program files/Tangramuniversedocument”的结构,我们会提供相关的文档对配置文件进行详细的解释。
基于同样的考虑,每个常规的文档/视图结构也是由MFC/ATL组件库实现的,我们也提供了相关的Wizard,每个文档模板需要一个xml文件进行配置,这些xml文件包存在“x:/program files/Tangramuniversedocument/your company/ app name /MainAssemblyLibcategory/ DocumentTemplate”之中,一个典型的文档模板配置如下:
<?xml version="1.0" encoding="utf-8" ?>
<Tangram
DocViewID="TangramLiteForm.DocTemplate.1"
DocObjID = ""
ExtDocObjID = "TangramLiteFormExtender.docextender.1">
</Tangram>
其中,DocViewID指定文档模板对应的ATL对象,ExtDocObjID用来指定文档的Extender对象。一旦你生成一个文档模板对象,只要写出对应的xml配置文件,并复制到指定的目录,任何一个TangramLite开发的应用系统都可以打开、创建对应的文档。
关于IE扩展,在TangramLite框架中,提供了3个Wizard用来实现IE的ExplorerBar,你可以用这些Wizard生成自己的IE ExplorerBar,我们提供了若干例子,关于如何配置自己的IE ExplorerBar,清参考“x:/program files/Tangramuniversedocument/TangramLiteExplorerBarD”文件夹的目录结构以及其中的xml文件,这些文件包存在Vband、Hband文件夹中。