一、前言
公元一九九五年某個夜黑風高的晚上,我的一位老師跟我說:“小楊呀,以後寫程序就和搭積木一樣啦。你趕快學習一些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 的存儲結構;容易擴展。 結構太松散,容易造成數據的損壞或丟失。以上兩個方案,都有嚴重的缺陷,怎麼解決那?如果能有一個新方案,能夠合並前兩個方案的優點,消滅缺點,該多好呀......微軟是作磁盤操作系統起家的,於是很自然地他們提出了一個非常完美的設計方案,那就是把磁盤文件的管理方式移植到文件中了------復合文件,俗稱“文件中的文件系統”。連微軟當年都沒有想到,就這麼一個簡單的想法,居然最後就演變出了 COM 組件程序設計的方法。可以說,復合文件是 COM 的基石。下圖是磁盤文件組織方式與復合文件組織方式的類比圖:
圖一、左側表示一個磁盤下的文件組織方式,右側表示一個復合文件內部的數據組織方式。
三、復合文件的特點
四、浏覽復合文件
VC6.0 附帶了一個工具軟件“復合文件浏覽器”,文件名是“vc目錄CommonToolsDFView.exe”。為了方便使用該程序,可以把它加到工具(tools)菜單中。方法是:ToolsCustomize...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() 在