H's profile什么PhotosBlogLists Tools Help

Blog


    3/10/2006

    备查——元素周期表

    元素周期表
      IA     碱金属 碱土金属 过渡元素              

    0

    1 H IIA   主族金属 非金属 稀有气体       IIIA IVA VA VIA VIIA He
    2 Li Be                     B C N O F Ne
    3 Na Mg IIIB IVB VB VIB VIIB

    VIIIB

    IB IIB Al Si P S Cl Ar
    4 K Ca Sc Ti V Cr Mn Fe Co Ni Cu Zn Ga Ge As Se Br Kr
    5 Rb Sr Y Zr Nb Mo Tc Ru Rh Pd Ag Cd In Sn Sb Te I Xe
    6 Cs Ba La Hf Ta W Re Os Ir Pt Au Hg Tl Pb Bi Po At Rn
    7 Fr Ra Ac Rf Db Sg Bh Hs Mt Uun Uuu Uub            

    镧系 La Ce Pr Nd Pm Sm Eu Gd Tb Dy Ho Er Tm Yb Lu    
    锕系 Ac Th Pa U Np Pu Am Cm Bk Cf Es Fm Md No Lr    
    3/6/2006

    春暧花未开

          南京的天气喜怒无常,前几天刚刚下过鸭毛大雪,这两天气温又开始飙升。怎奈我不争气,喉咙发炎,头疼,脖子疼,还发烧。我想起来就对自己摇头——哎,老了!早晨睡到8:40还不想起来,真想就这么睡过去,睡到明天早上。可是……(没有原因,糊里糊涂的)就起来了。起来浑身难受,脖子和耳朵后面上还起了小包。胡乱收拾一下决定跑去校医院看看。挂了号(5年来第二次在校医院挂号,本科的医疗费都浪费了),来到2楼。外科的门全都关着,我探头探脑看了半天确定大夫确实有空,我才推门进去。大夫阿姨在旁边拿起了一只吃龙虾、香辣蟹用的塑料手套在我脖子上和脑后按了好一会,坐下来镇静的对我说:“去省人民医院门疹大厅问一下导医台的人,问一下就知道挂哪科了。”……我一小小蒙,你连看哪科都不知道啊!我心底蹦出4个字,你个SB,破口而出……的却是:”谢谢大夫“-。|||这就是咱博士大人的修养。
          省人民医是我再熟悉不过的地方了。从去年五一开始我就没少到那报到。不过看到我的人很多都会觉得我不应该会得病啊,可是事实就是事实。其实我也挺无奈的,哦,对了,应该说那是相当无奈!(师兄左的教导)又扯远了。来到院里(这样称呼既亲切又省事)轻车熟路,在一堆毫无排队意识的患者中间迅速挂了号。一看,号单和原来不一样了!于是不禁感叹到,果然是大医院啊!想我们在黄山实习时还用60年代的表格呢!拿着单子杀到2楼外科(其实我对急诊外科更熟一点),胡乱找了位人最少的大夫。这里有必要说明一下,不了解省院的人大概不知道,一般来说,病人经常见到四种大夫:急诊(实习)值班大夫,普通大夫,专家,高级专家。最重要的区分方式是挂号费不同。正因为如此,在这边随便找哪个人看都一样,反正你来复诊他也不会等着你。又跑题了的说……大夫什么工具也没带,用手随便按了几下,让我转转脖子,问我有没有发炎什么的。最后说,是淋巴节,发炎引起的。吃点消炎药就行了……
      不严重当然好了,不过却实很疼,直接导致之后我两晚失眠,三晚半失眠。痛苦。
     
      回到学校本来应该去上课,不过对于这种事我从来都不热心,所以一点也不急。因为发炎的关系,一直发烧,所以还穿着大衣。毕竟是春天了,被太阳一照,身上多少还是有点热。那点热就是春天的感觉~
      难得会一个人在学校里乱晃,还真发现了不少东东。每天都在学校里走过,对很多东西都已经熟视无睹。其实我们的校园还是很精彩的,一年到头都在不断的变化着。就像三水三电那的几株竹子,分布在校园各处的几棵腊梅,石头缝里的野花……说是春暧花未开,只是那些最引人注意,最着人喜欢的那些花。事实上腊梅那毫不起眼的小花和一些野花已经开始悄悄地开放了,即使没人注意。
         
    3/4/2006

    关于COM和.NET的一些问题

     

    何谓.NET框架?

    .NET框架是微软COM技术与互联网技术的完全综合。.NET框架组件能够实现服务型的接口,使得应用可以不在客户机上装载功能组件而通过互联网直接使用它们。

     

     

    何谓C#?

    C#结合了C++的功能性和VB的易用性,是一种微软新开发的语言。开发者使用它可以创建鲁棒性强、 面向对象的应用,而代码行却比C++的短,这样一来,就减少了引入错误的机会。C#的设计就是为了 实现与.NET框架融合工作。

     

     

    框架的出现意味着组件终结吗?

    不。实际上,.NET(包括Win Forms,Web Forms和ASP+)是依赖组件提供服务的。 本质的变化是组件的位置(在服务器上)和这些组件的使用是如何注册的。当你安装一个服务器端 用户接口组件时,例如,一个网络服务器,你就要向组件提供接口。这些接口(属性、方法和事件) 以Web Form服务的形式提供,但本质的功能都是由组件提供的。

     

     

    可以在我已有的COM应用实例中使用.NET组件吗?

    当然。.NET框架允许使用CCW。.NET组件可以由现有的组件/应用调用。这实现了标准的COM接口, 这样就可以调用应用了,而.NET组件"看起来"就象是COM组件。

     

     

    哪些其它编程语言可以与.NET一起使用?

    .NET框架的设计使得多种开发环境可以在框架中使用。唯一的要求是这些语言是.NET的用户。 已成为.NET用户的语言有FORTRAN、COBOL、RPG、所有的Visual Stdio中的可视化语言, 还包括新的C#。

     

     

    何谓EJB组件?

    企业级JavaBean(EJB)组件就是在分布式环境中运行的JavaBean组件。EJB组件在Java Application Servers 中运行,适用于分布式的、可扩展的商业逻辑配置。一般地,EJB组件封装了中间层的商业逻辑。

     

     

    JavaBean与EJB的区别?

    这种区别是显著的。JavaBean组件一般是客户端组件,在Java虚拟机上运行。它们与父类应用联系紧密。 而设计企业级JavaBean是为了使其运行在分布环境中的应用服务器上,因此服从环境的需求、内容和限制。 从实现的角度,JavaBean通常为用户提供界面功能和客户端的商业逻辑。EJB则提供分布的、中间层的商业逻辑。 因此可根据实际情况确定是创建/使用JavaBean组件还是EJB组件。

     

     

    何谓COM组件?

    COM组件来自于微软的组件对象模型。COM组件可以是ActiveX控件(OCX)、ActiveX DLL或In Process Servers (DLL), 还可以是ActiveX EXE或Out of Process Servers (EXE)。实际上,基于已有的功能,任何COM组件都可以从适当的环境中取用, 例如Basic,VC++,IIS等等。

     

     

    何谓COM?

    COM是微软的组件对象模型。它运用其它过程为开放的属性、方法和应用事件建立运行界面。这是构造ActiveX 组件(可以让开发者同样重视其它COM组件的能力)和OLE(对象连接和嵌入--应用实例可以共享数据, 比如把一个电子表格嵌入word文档中)的核心技术。

     

     

    何谓服务器组件?

    服务器组件就是可以安装在服务器上的组件。这包括为ASP网络服务器优化的COM组件, 可以运行在java应用服务器上的EJB组件,以及为了提供分布组件功能而设计的 微软事务处理服务器(MTS)组件。当大多数服务器组件已经被限制在商业逻辑中时, 微软的.NET框架既可以由服务器端用户使用,也可用于商业逻辑中。

     

     

    何谓VCL组件?

    可视组件库(VCL)来自Borland公司的的组件模型,可以利用它可以创建可复用的Delphin和 C++ Builder组件。VCL组件可以在微软的窗式平台上运行。

     

     

    何谓CORBA?

    公用对象请求代理体系结构(CORBA)是对象管理组织(OMG)为分布的、可扩展的组件特别创建的 规格说明。它定义了CORBA对象如何通过适用于CORBA的ORB相互通信。

     

     

    我需要特别的软件来使用CORBA组件吗?

    是的,你需要CORBA对象请求代理(ORB)。ORB是存贮CORBA组件的中间层服务器。 ORB是建立在CORBA规范的特别版本上的,例如象2.0或3.0。版本号决定了一个CORBA组件 是否可以运行在给定的ORB上。ORB类似于EJB应用服务。实际上,很多EJB应用服务也包括 CORBA ORB软件,使它们既可以运行EJB组件也可以运行CORBA组件。

     

     

    所有的CORBA组件都是CCM组件吗?

    不是。CORBA组件模型(CCM)是服务器端组件模型的规范,用于建立企业级应用, 例如一套内联组件并把它安装到适应于CCM的运行环境中。CORBA 3.0规范中定义了 CCM组件规范。安装CCM组件的所有要求就是适应CORBA 3.0的ORB。

     

     

    应用程序和组件有什么区别?

    组件是应用程序的“建造材料”。它们提供一系列分散的操作,被应用程序一次次地使用。 任何给定的应用程序可以包含许许多多的组件,每个都提供特别的商业逻辑功能或用户界面功能。 以一个数据库应用为例:数据输入的窗口上可能包含许多用户界面组件,通过它们来提供按钮、 菜单、表格等。可能也有很多商业逻辑组件提供数据确认和计算功能,还有些组件将数据写入数据库。 最后,为了查看窗口中的表格或为了打印,可创建一些组件从数据中得出报告。

     

     

    何谓基于组件的开发(CBD)?

    基于组件的开发是利用可重用的组件建立应用的过程,因此可以节省时间和成本。它是面向对象编程(OOP)的延伸, 并将“购买之前重用,新建之前购买”的哲学具体化。在特殊的商业逻辑建立时,它就应为将来的开发而被组件化。 当一个应用要求的功能超过了开发者的能力时,从开发组织其他部分中得到的组件或从第三方得到的组件就起到了作用。

     

     

    何谓可重用组件?

    为使组件得到广泛的重用,你应该做到两点:一、发现它;二、明白组件的用途。组件自身应该是一个“黑匣子” (即,二进制/字节码),可通过接口访问它提供各种功能。但是使组件可重用还需要另外的信息。为了能发现组件, 你需要一个众所周知的场所(即,一个组件资源市场)和与组件相关的一系列标准分类信息,包括技术特征和各种 兼容性要求。要知道组件的用途,怎样使用组件,你需要各种使用信息和文档,包括功能说明书、分布和部署手册、 购买和注册信息、应用使用实例和示范、配置和扩展文档等。

     

     

    我们的应用软件产品本身可以卖100,000美元,为什么我还要去购买150美元一个的组件?

    第三方市场上的组件都是由专家设计,具有特定的功能的。实际上,大多数150美元的组件都没有装入“关键任务”代码。 或者说它们只是增强了用户的界面效果更为合适。但是,还是有许多第三方组件是装入了关键任务代码的,象金融核算组件。 在这些情况下,实际上依靠这些测试过时间效率的专业组件是更为安全的,而不是你自己写,尤其是在它的许多功能是 超出你能力所及的时候。

     

     

    如果我们在Java和VB的混合环境中运作,仍旧可以使用组件吗?

    完全可以。不同的组件在不同的层次上发挥作用,你可以精挑细选你要使用的组件和要使用它们的地方。 XML标准允许在不同平台间进行数据交换,而且还有COM-to-Java Bridges转换桥可以用来结合这两种环境。

    COM 组件设计与应用(一)[转]

    COM 组件设计与应用(一)
    起源及复合文件

    作者:杨老师

    一、前言

      公元一九九五年某个夜黑风高的晚上,我的一位老师跟我说:“小杨呀,以后写程序就和搭积木一样啦。你赶快学习一些OLE的技术吧......”,当时我心里就寻思 :“开什么玩笑?搭积木方式写程序?再过100年吧......”,但作为一名听话的好学生,我开始在书店里“踅摸”(注1)有关OLE的书籍(注2)。功夫不负有心人,终于买到了我的第一本COM书《OLE2 高级编程技术》,这本800多页的大布头花费了我1/5的月工资呀......于是开始日夜耕读.....
    功夫不负有心人,我坚持读完了全部著作,感想是:这本书,在说什么呐?
    功夫不负有心人,我又读完了一遍大布头,感想是:咳~~~,没懂!
    功夫不负有心人,我再,我再,我再读 ... 感想是:哦~~~,读懂了一点点啦,哈哈哈。
    ...... ......
    功夫不负有心人,我终于,我终于懂了。
    800页的书对现在的我来说,其实也就10几页有用。到这时候才体会出什么叫“书越读越薄”的道理了。到后来,能买到的书也多了,上网也更方便更便宜了......

      为了让VCKBASE上的朋友,不再经历我曾经的痛苦、不再重蹈我“无头苍蝇”般探索的艰辛、为了VCKBASE的蓬勃发展、为了中国软件事业的腾飞(糟糕,吹的太也高了)......我打算节约一些在 BBS 上赚分的时间,写个系列论文,就叫“COM组件设计与应用”吧。今天是第一部分——起源。

    二、文件的存储

      传说350年前,牛顿被苹果砸到了头,于是发现了万有引力。但到了二十一世纪的现在,任何一个技术的发明和发展,已经不再依靠圣人灵光的一闪。技术的进步转而是被社会的需求、商业的利益、竞争的压力、行业的渗透等推动的。微软在Windows平台上的组件技术也不例外,它的发明,有其必然因素。什么是这个因素那?答案是——文件的存储。
      打开记事本程序,输入了一篇文章后,保存。——这样的文件叫“非结构化文件”;
      打开电子表格程序,输入一个班的学生姓名和考试成绩,保存。——这样的文件叫“标准结构化文件”;
      在我们写的程序中,需要把特定的数据按照一定的结构和顺序写到文件中保存。——这样的文件叫“自定义结构化文件”;(比如 *.bmp 文件)
      以上三种类型的文件,大家都见的多了。那么文件存储就依靠上述的方式能满足所有的应用需求吗?恩~~~,至少从计算机发明后的50多年来,一直是够用的了。嘿嘿,下面看看商业利益的推动作用,对文件 的存储形式产生了什么变化吧。30岁以上的朋友,我估计以前都使用过以下几个著名的软件:WordStar(独霸DOS下的英文编辑软件),WPS(裘伯君写的中文编辑软件,据说当年的市场占有率高达90%,各种计算机培训班的必修课程),LOTUS-123(莲花公司出品的电子表格软件)......
    微软在成功地推出 Windows 3.1 后,开始垂涎桌面办公自动化软件领域。微软的 OFFICE 开发部门,各小组分别独立地开发了 WORD 和 EXCEL 等软件,并采用“自定义结构”方式,对文件进行存储。在激烈的市场竞争下,为了打败竞争对手,微软自然地产生了一个念头------如果我能在 WORD 程序中嵌入 EXCEL,那么用户在购买了我 WORD 软件的情况下,不就没有必要再买 LOTUS-123 了吗?!“恶毒”(中国微软的同志们看到了这个词,不要激动,我是加了引号的呀)的计划产生后,他们开始了实施工作,这就是 COM 的前身 OLE 的起源(注3)。但立刻就遇到了一个严重的技术问题:需要把 WORD 产生的 DOC 文件和 EXCEL 产生的 XLS 文件保存在一起。
     

    方案

    优点

    缺点

    建立一个子目录,把 DOC、XLS 存储在这同一个子目录中。 数据隔离性好,WORD 不用了解 EXCEL 的存储结构;容易扩展。 结构太松散,容易造成数据的损坏或丢失。
    不易携带。
    修改文件存储结构,在DOC结构基础上扩展出包容 XLS 的结构。 结构紧密,容易携带和统一管理。 WORD 的开发人员需要通晓 EXCEL 的存储格式;缺少扩展性,总不能新加一个类型就扩展一下结构吧?!

    以上两个方案,都有严重的缺陷,怎么解决那?如果能有一个新方案,能够合并前两个方案的优点,消灭缺点,该多好呀......微软是作磁盘操作系统起家的,于是很自然地他们提出了一个非常完美的设计方案,那就是把磁盘文件的管理方式移植到文件中了------复合文件,俗称“文件中的文件系统”。连微软当年都没有想到,就这么一个简单的想法,居然最后就演变出了 COM 组件程序设计的方法。可以说,复合文件是 COM 的基石。下图是磁盘文件组织方式与复合文件组织方式的类比图:

    图一、左侧表示一个磁盘下的文件组织方式,右侧表示一个复合文件内部的数据组织方式。

    三、复合文件的特点

    1. 复合文件的内部是使用指针构造的一棵树进行管理的。编写程序的时候要注意,由于使用的是单向指针,因此当做定位操作的时候,向后定位比向前定位要快;
    2. 复合文件中的“流对象”,是真正保存数据的空间。它的存储单位为512字节。也就是说,即使你在流中只保存了一个字节的数据,它也要占据512字节的文件空间。啊~~~,这也太浪费了呀?不浪费!因为文件保存在磁盘上,即使一个字节也还要占用一个“簇”的空间那;
    3. 不同的进程,或同一个进程的不同线程可以同时访问一个复合文件的不同部分而互不干扰;
    4. 大家都有这样的体会,当需要往一个文件中插入一个字节的话,需要对整个文件进行操作,非常烦琐并且效率低下。而复合文件则提供了非常方便的“增量访问”能力;
    5. 当频繁地删除文件,复制文件后,磁盘空间会变的很零碎,需要使用磁盘整理工具进行重新整合。和磁盘管理非常相似,复合文件也会产生这个问题,在适当的时候也需要整理,但比较简单,只要调用一个函数就可以完成了。

    四、浏览复合文件

      VC6.0 附带了一个工具软件“复合文件浏览器”,文件名是“VC目录\Common\Tools\DFView.exe”。为了方便使用该程序,可以把它加到工具(tools)菜单中。方法是:Tools\Customize...\Tools卡片中增加新的项目。运行 DFView.exe,就可以打开一个复合文件进行观察了(注4)。但奇怪的是,在 Microsoft Visual Studio .NET 2003 中,我反而找不到这个工具程序了,汗!不过这恰好提供给大家一个练习的机会,在你阅读完本篇文章并掌握了编程方法后,自己写一个“复合文件浏览编辑器”程序,又练手了,还有实用的价值。

    、复合文件函数

      复合文件的函数和磁盘目录文件的操作非常类似。所有这些函数,被分为3种类型:WIN API 全局函数,存储 IStorage 接口函数,流 IStream 接口函数。什么是接口?什么是接口函数?以后的文章中再陆续介绍,这里大家只要把“接口”看成是完成一组相关操作功能的函数集合就可以了。
     

    WIN API 函数

    功能说明

    StgCreateDocfile() 建立一个复合文件,得到根存储对象
    StgOpenStorage() 打开一个复合文件,得到根存储对象
    StgIsStorageFile() 判断一个文件是否是复合文件

     

    IStorage 函数

    功能说明

    CreateStorage() 在当前存储中建立新存储,得到子存储对象
    CreateStream() 在当前存储中建立新流,得到流对象
    OpenStorage() 打开子存储,得到子存储对象
    OpenStream() 打开流,得到流对象
    CopyTo() 复制存储下的所有对象到目标存储中,该函数可以实现“整理文件,释放碎片空间”的功能
    MoveElementTo() 移动对象到目标存储中
    DestoryElement() 删除对象
    RenameElement() 重命名对象
    EnumElements() 枚举当前存储中所有的对象
    SetElementTimes() 修改对象的时间
    SetClass() 在当前存储中建立一个特殊的流对象,用来保存CLSID(注5)
    Stat() 取得当前存储中的系统信息
    Release() 关闭存储对象
     

    IStream 函数

    功能说明

    Read() 从流中读取数据
    Write() 向流中写入数据
    Seek() 定位读写位置
    SetSize() 设置流尺寸。如果预先知道大小,那么先调用这个函数,可以提高性能
    CopyTo() 复制流数据到另一个流对象中
    Stat() 取得当前流中的系统信息
    Clone() 克隆一个流对象,方便程序中的不同模块操作同一个流对象
    Release() 关闭流对象
     
    WIN API 补充函数 功能说明
    WriteClassStg() 写CLSID到存储中,同IStorage::SetClass()
    ReadClassStg() 读出WriteClassStg()写入的CLSID,相当于简化调用IStorage::Stat()
    WriteClassStm() 写CLSID到流的开始位置
    ReadClassStm() 读出WriteClassStm()写入的CLSID
    WriteFmtUserTypeStg() 写入用户指定的剪贴板格式和名称到存储中
    ReadFmtUserTypeStg() 读出WriteFmtUserTypeStg()写入的信息。方便应用程序快速判断是否是它需要的格式数据。
    CreateStreamOnHGlobal() 内存句柄 HGLOBAL 转换为流对象
    GetHGlobalFromStream() 取得CreateStreamOnHGlobal()调用中使用的内存句柄

    为了让大家快速地浏览和掌握基本方法,上面所列表的函数并不是全部,我省略了“事务”函数和未实现函数部分。更全面的介绍,请阅读 MSDN。
    下面程序片段,演示了一些基本函数功能和调用方法。
    示例一:建立一个复合文件,并在其下建立一个子存储,在该子存储中再建立一个流,写入数据。

    void SampleCreateDoc()
    {
    	::CoInitialize(NULL);	// COM 初始化
    				// 如果是MFC程序,可以使用AfxOleInit()替代
    
    	HRESULT hr;		// 函数执行返回值
    	IStorage *pStg = NULL;	// 根存储接口指针
    	IStorage *pSub = NULL;	// 子存储接口指针
    	IStream *pStm = NULL;	// 流接口指针
    
    	hr = ::StgCreateDocfile(	// 建立复合文件
    		L"c:\\a.stg",	// 文件名称
    		STGM_CREATE | STGM_WRITE | STGM_SHARE_EXCLUSIVE,	// 打开方式
    		0,		// 保留参数
    		&pStg);		// 取得根存储接口指针
    	ASSERT( SUCCEEDED(hr) );	// 为了突出重点,简化程序结构,所以使用了断言。
    				// 在实际的程序中则要使用条件判断和异常处理
    
    	hr = pStg->CreateStorage(	// 建立子存储
    		L"SubStg",	// 子存储名称
    		STGM_CREATE | STGM_WRITE | STGM_SHARE_EXCLUSIVE,
    		0,0,
    		&pSub);		// 取得子存储接口指针
    	ASSERT( SUCCEEDED(hr) );
    
    	hr = pSub->CreateStream(	// 建立流
    		L"Stm",		// 流名称
    		STGM_CREATE | STGM_WRITE | STGM_SHARE_EXCLUSIVE,
    		0,0,
    		&pStm);		// 取得流接口指针
    	ASSERT( SUCCEEDED(hr) );
    
    	hr = pStm->Write(		// 向流中写入数据
    		"Hello",		// 数据地址
    		5,		// 字节长度(注意,没有写入字符串结尾的\0)
    		NULL);		// 不需要得到实际写入的字节长度
    	ASSERT( SUCCEEDED(hr) );
    
    	if( pStm )	pStm->Release();// 释放流指针
    	if( pSub )	pSub->Release();// 释放子存储指针
    	if( pStg )	pStg->Release();// 释放根存储指针
    
    	::CoUninitialize()		// COM 释放
    				// 如果使用 AfxOleInit(),则不调用该函数
    }

    图二、运行示例程序一后,使用 DFView.exe 打开观察复合文件的效果图

    示例二:打开一个复合文件,枚举其根存储下的所有对象。
    #include <atlconv.h>	// ANSI、MBCS、UNICODE 转换
    
    void SampleEnum() 
    {	// 假设你已经做过 COM 初始化了
    
    	LPCTSTR lpFileName = _T( "c:\\a.stg" );
    	HRESULT hr;
    	IStorage *pStg = NULL;
    	
    	USES_CONVERSION;				// (注6)
    	LPCOLESTR lpwFileName = T2COLE( lpFileName );	// 转换T类型为宽字符
    	hr = ::StgIsStorageFile( lpwFileName );	// 是复合文件吗?
    	if( FAILED(hr) )	return;
    
    	hr = ::StgOpenStorage(			// 打开复合文件
    		lpwFileName,			// 文件名称
    		NULL,
    		STGM_READ | STGM_SHARE_DENY_WRITE,
    		0,
    		0,
    		&pStg);				// 得到根存储接口指针
    
    	IEnumSTATSTG *pEnum=NULL;	// 枚举器
    	hr = pStg->EnumElements( 0, NULL, 0, &pEnum );
    	ASSERT( SUCCEEDED(hr) );
    
    	STATSTG statstg;
    	while( NOERROR == pEnum->Next( 1, &statstg, NULL) )
    	{
    		// statstg.type 保存着对象类型 STGTY_STREAM 或 STGTY_STORAGE
    		// statstg.pwcsName 保存着对象名称
    		// ...... 还有时间,长度等很多信息。请查看 MSDN
    
    		::CoTaskMemFree( statstg.pwcsName );	// 释放名称所使用的内存(注6)
    	}
    	
    	if( pEnum )	pEnum->Release();
    	if( pStg )	pStg->Release();
    }
    六、小结

      复合文件,结构化存储,是微软组件思想的起源,在此基础上继续发展出了持续性、命名、ActiveX、对象嵌入、现场激活......一系列的新技术、新概念。因此理解和掌握 复合文件是非常重要的,即使在你的程序中并没有全面使用组件技术,复合文件技术也是可以单独被应用的。祝大家学习快乐,为社会主义软件事业而奋斗:-)

    留作业啦......
    作业1:写个小应用程序,从 MSWORD 的 doc 文件中,提取出附加信息(作者、公司......)。
    作业2:写个全功能的“复合文件浏览编辑器”。

    注1:踅摸(xuemo),动词,北方方言,寻找搜索的意思。
    注2:问:为什么不上网查资料学习?
    答:开什么国际玩笑!在那遥远的1995年代,我的500块工资,不吃不喝正好够上100小时的Internet网。
    注3:OLE,对象的连接与嵌入。
    注4:可以用 DFView.exe 打开 MSWORD 的 DOC 文件进行复合文件的浏览。但是该程序并没有实现国际化,不能打开中文文件名的复合文件,因此需要改名后才能浏览。
    注5:CLSID,在后续的文章中介绍。
    注6:关于 COM 中内存使用的问题,在后续的文章中介绍。