前言
也許,你是一個頑固的SDK簇擁者;
也許,你對MFC抱著無比排斥的態度,甚至像我一樣對它幾乎一無所知;
也許,你符合上面兩條,而且正在尋求著一種出路;
也許,你找到了一條出路——WTL,但是仍然為它的技術支持、它的上下兼容性感到擔憂;
也許,你還有著更多的也許;
也許,這時候你看到了李馬的這篇文章。
世界上的故事,往往就是由各種“也許”交織而成的。
我的轉型
歷史告訴我,在向別人推薦一樣東西的時候,首先應該告訴別人你從中獲益了多少,如是才能夠使這一切更加具有說服力。比如我告訴你,我自從用了ATL之後,腰不酸了、腿不疼了、走路也有勁兒了,那麼你沒准兒就會對ATL產生些許的好感。是的,在《前言》的這一節裡,我將以我自身的Win32 GUI程序設計經歷來向你不遺余力地推薦ATL——因為我的這一系列連載就是以它為主題的。
2000年,我開始用Visual Basic學寫Win32下(嚴格地說,當時的Windows 95並不能算是純粹的Win32系統,它只是一個16/32位Windows的雜種)的程序。到了2001年,我開始厭倦它的運行庫與運行效率,於是轉投了Delphi。也許是Borland的粉絲不好做,也許是我厭倦了PASCAL的嚴謹,又也許是那種“真正的程序員用VC”的幼稚思想在作怪——總之,我又投向了VC。
一方面是我忒摳門兒,不捨得花錢買好書;另一方面,中國的MFC書籍琳琅滿目魚龍混雜而使我無法提起學習的興致——反正不知道什麼時候開始,我就開始強烈抵觸MFC這個本無過錯的Framework,而僅僅憑著雜志報紙上寥寥的幾篇SDK文章和全英文的MSDN 6.0開始了我艱難的學習長征。所幸,這一路上雖然磕磕絆絆,但最終我還是到達了屬於我的陝北。如果您於此期間曾經在網上或其它媒體上看到過我的Win32技術文章,就應該會發現這其中我極少涉獵MFC的任何內容——我不否認我對它存在著狹隘的偏見,雖然我在2005年完成的畢業設計是用MFC編寫的。
SDK終究不是一個讓人舒適的歸宿,我想SDK的粉絲們都應該有著深深的體會。哪怕是你的代碼增加到1000行,你都會覺得維護這些東西的難度非常之大——臃腫、堆砌、全局、耦合、復用性差——有太多丑陋的詞語都可以用在這上面。是的,我的確說過我不喜歡MFC,但是我也同樣不能否認用MFC編寫的程序結構清楚、分流明晰——當然,如果你不是深入到MFC內部去看的話。舉個例子來說,我所編寫的進程查看器July的2.11版本就是用SDK編寫的(這個版本是開源的),才1000行出頭的代碼就已經使得我難以駕馭它們了,以致於後來我不止一次地想重寫之——我想過用MFC,甚至Delphi的VCL。不過,運行庫的限制和龐大的EXE體積還是使我放棄了這些想法。
如果說MFC和VCL是生長在深宮名門的大家閨秀,那麼WTL就可以算是一位浪跡天涯的絕色歌女。我在2004年的時候,曾與它不經意地邂逅。精良的設計、輕巧的EXE、無與倫比的效率——如果不是它的兼容性存在問題的話(如果不修改的話,WTL 7.1連它自己附帶的某幾個sample都無法通過編譯),我幾乎就要拜倒在它的石榴裙下了。
於是我繼續迷茫,這種迷茫一直持續到了2005年我畢業之後。2005年8月的時候,為了研究不借助MFC調用ActiveX控件的技術,我接觸了WTL的發端——為開發COM組件而設計的ATL。時至今日我似乎已經無法回憶起當時的景況,只記得一個月之後,用ATL重寫的July v2.20就誕生了。
比起大家閨秀和絕色歌女,ATL則更像是一位溫柔賢惠的樸實女子。
對症下藥
說歸說,ATL終究不是萬靈之藥。它是否適合你,且看你是否已經存在以下病症(當然,我也為你列出了其它可選藥物):
看重程序獨立性,不喜歡程序運行庫。顯然,.net和Visual Basic都不適合你。除ATL外,你還可以選擇VCL、MFC(靜態鏈接),當然還有WTL。
看重程序效率。Visual Basic絕對不適合你。由於VCL與MFC內部會為窗口控件維護對象鏈,所以可能也不適合你。在這一方面,ATL和WTL會是不錯的選擇。
看重EXE的大小。沒的說,VCL和靜態鏈接的MFC不能列入你的選擇,ATL和WTL仍是最佳選擇。當然,如果你不計較Windows自己捆綁的MFC運行庫的話,MFC動態鏈接也可以。
你不得不在沒有MFC的Windows環境下編寫代碼。有這樣的環境嗎?也許你要問。是的,Smartphone 2003正是這樣一個環境。ATL是你最佳的選擇,當然你還可以選擇.net Compact Framework。
此外,你需要做好准備迎接以下這些使用了ATL以後可能帶來的並發症:
向導支持較少。可以說,VC的IDE就是完全為MFC程序設計准備的。它為ATL的支持甚少,似乎只有幾個窗口消息處理器可以用。所以,有很多的消息映射可能需要你自己手工完成。
技術支持有限。畢竟ATL是為COM組件開發准備的,所以關於用ATL進行GUI開發的資料非常少,除了MSDN上的說明和網上寥寥的幾篇文章之外,似乎就很難找到了。
最後,我為你列出ATL較之WTL更優秀的幾點:
代碼兼容性強。比如VC6.0寫出的代碼在大多數情況下(我暫未遇到少數情況)都可以不經修改地在VS2003下編譯運行。
消息分流簡單。我是前說過,VC對ATL的向導支持是很有限的。這樣一來,WTL豐富的消息分流反而成了累贅。如果你用WTL寫過程序,相信你會有相同的感覺——手工編寫那批多種多樣消息處理函數並不是一件輕松的事情。
當然,我本人對WTL並沒有偏見,但WTL的不為官方所支持也是它自身不爭的一個事實。相信還有很多人對WTL的官方化望眼欲穿,然而他們還是遲遲不能如願。如果WTL真有那麼一天(我也認為肯定會有那麼一天),關於代碼兼容性、向導支持、技術支持的這些問題都將不會是問題。
關於本系列連載
《ATL的GUI程序設計》這一系列的文章是李馬為ATL/WTL之間的矛盾而做出的一個折中,也是李馬在2006年為大家獻上的一份禮物,希望大家能夠喜歡,也希望它們能夠成為大家邁入WTL之門的引領者。
閱讀本系列文章有兩個先決條件:第一,你需要了解C++的模板技術,因為ATL的技術基礎就是建構於模板之上的;第二,你需要了解Win32 SDK程序設計,這方面的經典教材是Charles Petzold的《Programming Windows》(中譯《Windows程序設計》),有關這方面的基礎知識我在本系列文章中不再進行任何解釋。
本系列文章將會介紹如何使用ATL進行Win32的GUI程序設計方法,包括ATL的GUI基礎使用方法、高級主題以及對ATL的擴展。此外,本系列文章還會對ATL/WTL的某些關鍵實現技術進行解說,這些內容的理解與否並不影響使用ATL進行GUI程序設計,你可以根據個人情況來選擇閱讀。
本系列文章中所有附帶的源代碼都是在Visual C++ 6.0 sp4和Visual Studio 2003.net上編譯通過的,但主要環境仍然基於VC6.0之上,VS2003則只供驗證之用。
就這樣了!我謹用一句呼應開頭的話來結束這段稍嫌冗長的開場白:
——也許,認識ATL之後,以前的“也許”將不再是“也許”……