Utensil按:上個星期做了很多事,包括實現了文件傳輸、實現了透明蒙版(用於選定要截屏的控件)、開始了q到r的revision,還有就是寫成了這篇文章。是在寫着寫着原定計劃介紹怎麼編譯wxWidgets一章的時候,發現必須對wxWidgets做一份自己的介紹,網上流傳的那些介紹都感覺不夠帶勁。文中保留了自己的偏頗之處。
這篇東西是用Word排版的,我只是簡單的拈貼進來,不做走位格式的整理,全書寫成之後,會以pdf文檔的形式發佈。保留所有版權,轉載請評論,或告知[email protected]。
什麼是wxWidgets?一個簡單的回答就是它是一個免費、源代碼開放、跨平臺的提供本地觀感的圖形用戶界面(GUI)的類庫(主要是C++,同時也有其他各種語言的綁定版本)。
免費這一點,對於用慣破解軟件的我們而言,似乎並不那麼令人動心。但當你成爲一個公司的職員,開始做項目的時候,你就會發現License成爲你很頭痛的問題,因爲公司的行爲會受到中國日益完善的打擊盜版的法律體系的制約。想想爲什麼在幾乎家家用的都是盜版Windows的情況下,微軟照樣能在中國賺回大把大把的錢?靠的就是政府和公司這些大客戶。而且身在其中的你不購買它的授權還不行,不用打官司,飛個律師函過來就夠你老闆頭疼的了。在公司裏,你用個WinRAR都會招致律師函的……所以,免費絕對是使用wxWidgets進行開發的最大好處——更妙的是,雖然免費,可它經過十餘年的發展,已經非常成熟,趨於完善,而且還在繼續被開源社區的程序員們熱火朝天地開發着。
源代碼開放又意味着什麼呢?
只需要從SVN上檢出(check out)最近的源代碼,然後編譯,就能獲得最新版的wxWidgets。如果你是個高手,還可以修復你發現的Bug並提交補丁(Patch)。
在國外,你在論壇上提問時,可能會有人叫你RTFM或RTFS,它們是Read the fantastic manual和Read the fantastic source的縮寫,意思是讓你去讀文檔和源代碼。這是一種良好的學習習慣,先自學和自行查找(搜Google和搜論壇),然後再向其他人求助。
wxWidgets的文檔相當完善,例程也非常豐富,基本能滿足使用者的需要。但是對一些細微之處的理解,閱讀擁有豐富註釋的源代碼會比閱讀文檔中更爲抽象的描述要好理解的多。——唯一遺憾的是wxWidgets的文檔目前沒有一個翻譯團隊對其進行中譯,英文不好的同好可能就比較鬱悶了。
這裏所說的編程風格,包括代碼的書寫風格,也包括設計模式(Design Patern)。作爲開源軟件,良好的代碼書寫風格是起碼的要求。而就我目前對wxWidgets的構架的瞭解,它也是學習設計模式的一個絕好的教材[1]。
跨平臺,意味着你用wxWidgets寫的程序,只寫一次,就能在各個操作系統上用各編譯器編譯運行。目前,wxWidgets支持Windows(包括最新的Vista)、蘋果的Mac OS(Carbon接口和Cocoa接口)、Linux(GTK+接口和X11接口)、 Unix(Motif接口)、OS/2甚至 WinCE和PalmOS。當然,這需要你在寫程序的時候就對這一點多加註意,採用一些可以適用於各個平臺的寫法,比如不要指定一個Button的絕對大小和絕對位置,而是用Sizer進行佈局,再比如程序的圖標,最好使用xpm格式而非Windows專有的ico格式,等等。不過,如果你只需要在一個特定平臺下編程,也可以使用一些平臺專有的特性——wxWidgets也提供了一些類封裝了各平臺的一些專有特性。
同一個用wxWidgets寫的程序,在Windows下會長得跟其他Windows程序一樣,在蘋果下則會長得跟其他蘋果程序一樣,這是因爲在wxWidgets內部是用各操作系統本地的API實現的,而不是用同一套wxWidgets自己的實現(當然,如果你喜歡,也可以使用同一套wxWidgets自己的實現,即wxUniversal)。本地觀感是我們應該選擇wxWidgets而非其它跨平臺GUI庫的最重要的一點。
與本地觀感相併列的一點,是本地實現。我們在後面會看到,wxWidgets不僅僅是GUI,它在許多功能中都採用相應操作系統的本地實現,這樣,你的程序可以更高效,也能和本地的其他程序更協調地工作。
在Windows下,有不少人使用wxWidgets來作爲MFC[2]的一個更爲優雅的替代者。MFC由於微軟的強勢,被廣泛使用,但任何一個使用過它的人,都會鬱悶於它出於歷史原因而殘留下來的很多醜陋的地方。何況在微軟鑽進.net的衚衕裏之後,它的官方支持已經日漸式微。wxWidgets的類繼承結構與MFC很相似,你幾乎找不到MFC中有而wxWidgets中沒有的東西(想想你同時在多少個平臺上獲得了同樣的東西),而且你會看見它們被以更優雅的形式封裝起來,並使用了清晰整齊美觀的命名(類名通常是加上wx前綴的完整英文單詞,接口函數名也通常是完整的英文謂賓結構,每個單詞的首字母都大寫,每個參數的類型和名字也都有很強的指示作用——哪像MFC,動輒LPLVHITTESTINFO這樣的參數類型,誰看着能舒服?用wxWidgets寫的程序,不用註釋都能看懂大半。)更加驚喜的是,有太多在你用MFC編程時需要求助於第三方類庫的功能,內建在wxWidgets裏,並被封裝得很順手。
wxWidgets使用C++寫成。我個人非常熱愛C++,雖然現在Java很火,但我不喜歡它的許多莫名其妙的語法和功能簡化帶來的對編程的限制,不喜歡它強迫我們寫被託管的代碼,不喜歡自己的程序被放進一個砂箱裏(只要一個功能Java虛擬機或Java API不支持,我們就永遠做不了),不喜歡它表象混亂的指針模型和事實上也相當混亂的類庫結構。Java對 C++的許多“改進”,不應當由語言來做,而應該靠程序員自律(良好的編程風格)、編譯器特別支持(如垃圾回收)和類庫(如智能指針)來完成。
C++的發展歷史中,相當遺憾的一筆,是它沒有及時發展出自己的類庫,標準庫遲遲才建起,而跨平臺GUI類庫這一塊,更是被Java先聲奪人了。C++有了wxWidgets,是真正的如虎添翼,不僅不再在這方面被Java壓一頭,而且反過來彰顯了C++的優越性——本地觀感與本地實現。
然而wxWidgets不只是C++語言的類庫,它還有多種語言的綁定版本,包括Perl、Python、Ruby、Lua、Basic、C#、Euphoria甚至JavaScript,真是琳琅滿目。
作爲GUI類庫,wxWidgets提供了
l 你所能想到的各類窗體(Window、Frame或Panel,包括MDI[3],甚至啓動畫面、每日提示、嚮導等)
l 各類對話框、各類控件及相關的數據交換與驗證
l 可浮動可停靠的窗體、可由用戶定義的佈局
l 菜單、工具欄、狀態欄以及對系統托盤欄的訪問
l 各種GDI[4]類和DC[5]類,乃至於對OpenGL的支持
l 用Sizer進行的佈局框架
l 良好設計的事件處理(靜態事件表和動態事件掛鉤)、快捷鍵設置
l 剪貼板和拖放(Drag&Drop)操作支持
l 文檔/視圖框架
l 在線幫助框架
l 完整的打印框架,包括打印預覽、頁面設置以及對PostScript的支持
l ……
這些我不打算在這裏詳細介紹,你可以在官方文檔[6]、Julian Smart等著的《wxWidgets跨平臺GUI開發》[7]或後續的教程中找到它們的詳細介紹。
然而,wxWidgets庫遠遠超出一個單純的GUI類庫,而是一個多才多藝的類庫,提供了:
l 完善的Unicode支持、各種編碼的相互轉換
l 對編寫國際化(多語言)程序的支持
l 各類數據結構,包括GUI需要用到的數據結構(如點、一個不規則區域、光標)、實用的數據結構(如日期時間、64位整數、可變類型)、基本的容器(如鏈表、Hash族容器)、支持Unicode的字符串等。
l 多進程、多線程程序開發支持
l 對載入動態庫(Window下是動態鏈接庫dll、*nix平臺則是共享對象庫so)的支持
l 完整的Socket網絡編程支持,包括IP、TCP、UDP、HTTP和FTP等。
l 對Windows的DDE[8]、ActiveX(OLE)的支持
l ODBC數據庫訪問支持,SQL支持。
l 文件、文件夾、路徑相關的各種操作
l 虛擬文件系統,可用於訪問壓縮文檔、HTTP或FTP等因特網上的文件以及把內存當作一個虛擬文件來訪問。
l 各類流的支持
l 對zip和tar壓縮文檔的讀寫支持
l 對bmp、jpg、gif、png等圖片格式的讀寫支持,乃至可以播放gif和ani動畫
l 以本地多媒體支持爲後端的多媒體播放功能
l 富文本編輯控件
l 可進行多種編程語言語法高亮、代碼摺疊等功能的代碼編輯控件
l XRC(XML-based resource,基於XML的資源文件)系統,使用它可將GUI設計存儲進文本文件,並在運行時讀取,從而實現用戶界面與程序功能得更好的分離。
l 正則表達式解析、命令行參數解析(Parser)、字符串標記化(Tokenizer)
l 一整套HTML的解析、顯示、打印支持
l XML解析支持
l wxWidgets自己的運行時類型信息機制(RTTI)
l 各式智能指針
l 內建的內存管理、檢測系統、大量的調試(debug)宏支持,甚至包括可在程序崩潰時輸出可視化調試報告的控件
l 一整套日誌記錄功能(包括可視化的和基於文件或標準流的)
l 對將用戶設置保存爲配置文件(Windows下可用註冊表)的支持
l ……