在Office大戰中,國產軟件的確在一些方面與Microsoft進行較量,其實給人的感覺很勉強,界面上的似是而非,或用戶習慣方面的接近并不能解決根本的問題,一個好的軟件開發人員必須是一個軟件使用的高手,很難想象一個軟件操作水平很拙劣的開發人員能開發出高水平的軟件,我最早使用的軟件之一就是Microsoft Word,當時的版本是2.0,大概是1992年的事情,給我留下深刻印象的是集成于Word中的Word Basic,后來,我接觸到Excel 3.0,不出所料,Excel中集成的是Excel Basic,后來使用的Access中自然內置Access Basic 1.0,在這些軟件集成捆綁成Office之前,我就感覺這些產品的構思十分了不起,很具有Microsoft的風格,因為你知道,即使是一個DOS,Microsoft都要提供一個內置的QBasic或GW Basic。雖然關于Microsoft的產品評論很多,作為一個技術人員,我認為Microsoft的產品構思絕對是第一流的,從1994年早期的Office系列到1997年形成的Office 4.2,我認為,技術構思上均領先于我國2002年以后的Office產品,你聽說過如下說法嗎?"Dos 作為操作系統的時代,Windows是應用軟件;Windows是操作系統時,Office成為Dos時代的Windows;那么如果按此規律,Office會不會替代Windows而成為操作系統?",現在在開發領域Visual Studio( .NET)正在成為另一個Office,你注意到了嗎?控制Visual Studio( .NET)集成開發環境的仍然是一個Basic語言引擎(Visual Basic .NET)。
與許多公司不同的是,在技術體系上,Microsoft幾乎所有的產品是息息相關的,Windows、Office、Visual Studio .NET雖然各不相同,但公共的核心即將形成,我們已經看到,核心組件方面,Office與Visual Studio .NET日漸趨于一致,例如Microsoft正在將Office 2003的核心組件VBA 6.X逐步用新的Visual Studio Tools for Office替代,而我們依然在一些似是而非的現象上與Microsoft的產品比較差距,國家采購或政府采購支持的公司,不去鉆研核心技術,只是急功近利的采用短期行為急于與Microsoft相爭,不知是否有蚍蜉撼樹的感覺,個人的體驗是,先學習Microsoft,踏踏實實的學,了解Microsoft,深入的了解,然后再喊口號。
四、為什么用MFC?
經過若干年的競爭,Borland 的OWL幾乎消失了,這個OWL是個非常漂亮的C++類庫,在Borland C++ 3.1風光無限的年代,OWL真正的做到了獨領風騷。然而,Borland C++ 4.0錯過了進入32位程序的最佳時機,BC 4.0推出后不久,迎來了Win95,Borland倉促上陣,以一個小的"Pack"使得BC4可以編譯基于Win4的程序,當時的Visual C++是2.0版,支持Window16的版本為Visual C++1.51,有意思的是Borland可以用同一個編譯器同時支持Win16、Win32,而Microsoft卻不得不為Win16、Win32提供不同的編譯器。然而,非正式版本的Visual C++ 2.1與Visual C++ 2.2卻悄悄地支持了Win95的最新特征,即Win95新提供的一組公共控件,在我的印象中,Borland對Win95新特征的支持不利使得MFC與OWL的距離極大的縮短了。稍后到來的Borland C++ 4.5沒有改變這個狀況,盡管Borland C++ 5.0同時支持OWL與MFC,可是敗象已經顯露,Borland C++非常遺憾的只走到了5.5版。C++ Builder雖然形式上引入了Delphi的VCL庫,可是許多C++程序員并不買賬,因為許多以C++為樂的人更喜歡以編輯的模式進行編碼。Visual C++ 4.0的出現,在C++這個戰場上,Borland開始落敗了。
MFC發展到今天,已經十多年了,盡管褒貶不一,但可以肯定,十幾年的技術積累已經奠定了MFC的生存基礎,即使Microsoft的長角發布,MFC也不能推出Windows的舞臺,事實上,長角(Longhorn)之后的Visual Studio .NET仍將MFC作為一個重要的組成部分,在今年的Visual Studio .NET 2005中,MFC在C++中的位置依然如故。MFC的未來,應該不必擔心,只要你深入考察.NET類庫,你會發現,MFC的許多思想機制正悄然進入.NET,與此同時,Microsoft的第三方盟友十多年來已為MFC開發了大量的擴展庫,如果Microsoft是船,第三方盟友就是載舟之水。許多人認為MFC不發展了,其實是一種錯覺,Visual C++ 6的界面十分經典,特別是其中的Docking控制條機制,其實Visual C++ 6的IDE完全就是MFC寫的,可是MFC類庫中控制條相關的類功能很弱,為什么?你會看到許多與Microsoft友好的公司,他們很快的在MFC基礎上實現了Visual C++ 6 的Docking機制,這就是Microsoft的高明之處,Microsoft很會給盟友提供機會,其一貫的做法就是在自己的商品化產品中預先提供一些有趣的特征,使得其他一些公司進行模仿以帶動用戶群體。Borland不具備這樣的儲備。MFC第三方市場的繁榮,得益于Microsoft的策略與明智。MFC可否跨平臺?理論上完全可以,Microsoft不做,也是策略,但是有許多重要的產品Microsoft卻默許MFC移植到其他平臺,事實上,Microsoft的合作伙伴之一Mainsoft公司(Windows源碼就是從這家公司流失的),幾年來就是負責移植MFC程序移植到UINIX、Linux、AIX等操作系統之上。
新版的Visual C++中MFC已經支持.NET開發了,MFC與ATL的協作更好了。根據我的經驗,MFC、ATL與.NET庫三者完全可以融合在一起綜合應用到實際的開發工作中去,如果你是MFC行家,我希望ATL與.NET庫能成為你的忠實的左右手。那么有沒有同時支持MFC、ATL與.NET庫的程序?當然有,Visual Studio .NET IDE就是!而且Visual Studio .NET IDE還支持用ATL與.NET庫擴展的Addin,如果你希望用MFC管理ATL與.NET庫,請繼續支持我!
五、認識Application對象
如果你熟悉Microsoft Office,你應該進一步的剖析這個大型軟件,Microsoft Office中幾乎每個程序都是可二次開發的,這一點得益于Microsoft Office內置的二次開發機制,一個是基于COM機制的VBA模型,另一個是基于.NET框架的托管模型:Visual Studio Tools for Office。作為一名程序員,你應當在技術角度解析Office的技術結構。Microsoft的大多數軟件的對象結構可以通過Visual Studio提供的工具OLE/COM Object Viewer考察其類型庫得到,通過引用類型庫,你甚至可以得到描述對象信息的C++頭文件。這樣做真是好處多多。一個典型的Office通常都有一個Application對象(或其他一個與之相當的對象),這個對象相當于軟件樞紐,在這里,我們不討論Office,借此話題說說Application對象。大多數支持擴展(Addin、Plugin)的軟件都存在類似的構造。通常,一個系統得Application對象或者是一個COM對象,或者是一個.NET對象,如果你的系統存在這類對象,你的系統就基本具備支持Addin、Plugin的機制了。一個理想的做法就是在一個MFC系統中,內置一個ATL對象或.NET對象,稍后我們給出方案如何做到這一點。設計Application對象的關鍵是如何規劃這個對象的屬性、方法、事件。如果你希望系統具備良好的擴展性,Application對象是十分關鍵的,這也是構架藝術的體現。所謂Addin(Plugin),是系統運行時根據需要加載的對象庫,Addin(Plugin)之所以可以擴展系統,關鍵的因素就是系統加載Addin(Plugin)時,將Application對象傳遞給Addin(Plugin)庫,設想一下,如果Application恰到好處的觸發了系統事件,而Addin(Plugin)庫如愿的解釋了事件,一個Addin(Plugin)庫的任務不就OK了嗎!因此Application對象是系統設計的關鍵。
如果你精通ATL對象,在你的MFC系統中添加一個ATL對象,這個任務可以用VC Wizard完成。你已經接受了一個事實,就是MFC程序中存在一個CXXXApp對象(CWinApp的派生類),現在你要做的是增加一個對應得ATL對象。這個對象可以在CXXXApp::InitInstance()中創建,如果ATL對象的類是CXXXAppObject,建議你在CXXXApp對象對象中增加一個成員變量,例如:CComObject<CXXXAppObject>* m_pAppObj,然后可以入下初始化m_pAppObj:
m_pAppObj = new CComObject<CXXXAppObject>;
注意程序結束時在CXXXApp::ExitInstance()中釋放m_pAppObj,語句如下:
delete m_pAppObj;
你可以將系統得關鍵屬性設置成CXXXAppObject的屬性,例如系統得標題、是否為多文檔等等。系統希望外部調用的功能可以實現為CXXXAppObject的方法,這一點取決于你的需要。系統需要外部擴展的功能,表現為CXXXAppObject的事件,關鍵是在恰當的位置觸發事件以及提供的事件參數。例如,你可以在CXXXApp::InitInstance()觸發應用程序開始的事件OnStartUp,Plugin捕獲事件后,可以進行特定的初始化(身份確認、初始信息查詢等等);你可以在CXXXApp::ExitInstance()觸發應用程序結束事件,Plugin捕獲事件后,處理用戶需要的系統退出工作。所有的設計取決于具體設計。
如何加載Plugin,是一個有趣的問題,如果Plugin實現為一個COM范疇(Category),可以運用COM技術枚舉這個Category;可以將Plugin安裝到一個特定目錄,也可以通過注冊表。Plugin的實現可以用COM技術、也可以用.NET框架。適當的機會我會提供例子……
六、后記
一時心血來潮,就寫了這篇文章,很難說是有心,還是無意。幾天前我在新浪網上看應氏杯圍棋決賽,我覺得該贏了吧,作為一個圍棋迷,我們等了十幾年,等到了屬于國人的應氏杯。記得7、8年前在還在大學工作的時候,有一次,一位同事興致沖沖的走道我面前對我說:"嗨,昨天馬XX贏了李昌鎬!",當時我在系辦公室正在看報紙,那位仁兄見我頭都沒抬,非常不滿的搶下報紙,對我吼道:"喂!馬XX贏了李昌鎬!!你聽到沒有!!!",我對他說:"你大驚小怪個啥?!馬XX輸了李昌鎬多少盤,你知道嗎?",馬XX幾乎一直在輸給李昌鎬,人們已經不奇怪了,偶爾贏一次,國人就把他捧得北都找不到了,李昌鎬弱冠17的時候就傲視這個世界了,可至今面孔不變,幾天前的農心杯,中日聯軍5個人,被他打個落花流水,李昌鎬是公認的世界第一,以至于有的高手知道下一個對手如果是他,就會去訂回程機票。這次應氏杯,國人竟然感謝崔哲瀚,何也?因為這個弱冠19的小子,擋住了他的大哥李昌鎬才使得應氏杯有了懸念。當國人媒體在說韓國僅李昌鎬一人厲害的時候,不知道是出何居心還是自欺欺人,李昌鎬年方30,不知道要力壓中、日多少年!面對這個名字,真有點麻木了,這個太極虎!
軟件界又來了我們一向不齒的印度虎,2001年我們的軟件出口額僅是印度的四十分之一,我們震驚了,怎么可能呢?這個四十分之一水分很大,很可能更可憐!當時我在大連參加一個關于"大連軟件出口國內第一"的官方會議,那位大人在會上說:"據說,我們大連軟件出口國內排名第一,市有關領導希望今天的會議給出這個第一的數字依據,希望你們把數據報上來,去年的數據也可申報,注意,我們要的只是數據,你們仔細體會,我們根據數據,有獎勵,機會難得呀!"……。某一天,幾個朋友在我家看央視的對話節目,對話一方為國內的軟件大鱷們(用友、阿爾派等公司的老總們),另一方為印度軟件的一個代表團。當問及中、印軟件差距的時候,我們的劉老總(代表阿爾派)不以為然的說,據他的看法,我們已經快趕上(印度)了,……,言下之意頗有印度的水平不過如此的感覺,印度方的話我至今記憶猶新:"是否趕上,國際市場說的算!在中國看來,印度程序員的個性不足,技術也不怎么樣,其實是個錯覺,印度軟件首先注重個性,許多重要的美國商品化軟件都是在印度本土開發的……",我們的輿論總是將印度程序員的水平描述的平庸至極,可是差距日漸拉開,……,圍棋、足球(不好意思談,談不出口!)、軟件,我們被近鄰嚴酷的封鎖了,樂壞了記者們、給媒體帶來了生機……
日本江戶時代的圍棋,如果一個人要想世襲一個稱號(例如:本因坊),他必須戰勝所有的師兄弟,然后,住進師父家的內室,你知道以后的事情嗎?以后,這個棋手,就得為師父一家做飯、帶孩子、搞衛生……,其余的門人則一心一意的下棋,這樣的人、方式,造就了一代一代的本因坊,他們的棋譜大多數都流芳至今,這就是早期日本圍棋的悟道模式。軟件總共有多少語句?我最早接觸的計算機軟件教材是一本英文版的(影印的D版),不同于我們,那本書的作者構造了"X-語言",他們不講什么C、Pascal、Basic,一旦缺了什么機制,就給"X-語言"添加些成分。什么C、Pascal、Basic,你感覺差不多,但現在卻分出了等級!我們駕馭語言的能力弱得很,可是我們在語言的細微之處卻很講究,不知道對不對,許多程序員也許是出于虛榮而用C++,事實上,地球人到知道,做數據庫,Delphi、VB遠比C++勝任,鋪天蓋地的C++的書,寫的東西幾乎雷同,因為,有用的或者作者不寫、或者作者不懂。有時我在想,如果國內沒有內需,會怎樣?也許軟件內需的存在,造就了中國軟件的特色,我認為國內業界并沒有充分利用中國軟件內需的存在,也許中國軟件內需的存在是軟件落后的硬傷。
我記得一部電影《神辮》,那個英雄的大辮子被洋人炸掉了,最終他成了神槍手,戰勝洋人用大刀、秘籍是不行的,用洋的東西戰勝洋的技術才是正道。我覺得,一個好的程序員必須了解軟件的歷史,學習歷史,你知道你為什么弱,別人是如何強大的。我們正在另一個戰場上抗美(可笑的是我們卻要趕超印度!),無論Microsoft、Borland如何爭斗,無論他們誰統治誰,他們不影響美國的強大,朋友們,學習Microsoft,開發出讓國人感到牛的軟件!