# 控制臺和圖形用戶界面
`Hello world` 恐怕是家喻戶曉的編程語言第一堂課了,當你開始照書上的例子編寫`Hello world`時,很快就會問出這個問題。回想平時見到的那些程序,他們通常都有標題欄,有菜單和工具欄,可以用鼠標在上面點來點去好像還有很多別的功能。可是這個程序似乎完全不同,難道出了什么問題?其實沒有問題,這是一個控制臺程序。
世界上有各種各樣的程序。幾乎所有的程序都要和用戶交流,接受用戶的輸入,輸出運行的結果,但它們接受和輸出的方式是不一樣的,程序與用戶交流的方式被稱為界面。還記得早期科幻電影里那種出現在計算機屏幕上可以和人對話的巨大人臉嗎?或者《貝克街的亡靈》中被稱為「繭」的游戲——那就是界面的一種。事實上這種界面到現在還沒有實現,人類的想象力總是能超前實際技術很多。
界面有很多種,有些程序不需要界面,因為它們根本不必和用戶交流,它們和其它的程序交流,你可以叫它無界面,典型的例子就是驅動程序,你什么時候見過驅動程序運行的樣子?一般在Windows和Mac OS X下的程序所使用的則稱為圖形用戶界面(GUI: Graphics User Interface),Linux下同樣也有很多采用GUI的應用程序。簡單來說,就是所有的輸入和輸出都使用圖形的方式。它接受用戶圖形化的輸入,譬如用戶用定位設備(鼠標、軌跡球、手寫板)輸入坐標、繪圖,把程序的輸出反映在可以顯示圖形的設備上,譬如顯示器、打印機、頭戴式監視器,通常這種程序會提供菜單、工具條等方式而極大地方便用戶。這種程序直觀明了,一般用戶能很容易的掌握使用,只需要點擊就可以完成大部分的任務。魔獸世界和Word就是典型的GUI程序。
雖然GUI程序便于一般人使用,但其實圖形界面的編程是相當復雜的。你能想象每次你都要畫出顯示器上所有的東西有多困難。窗口移動縮放時,你需要重畫窗口里的每一樣東西;在多窗口并存的時候,如果你的窗口被別人的窗口擋住了一部分(這是很常見的情況),你需要控制窗口上哪些部分被顯示、哪些被遮擋;鼠標移動的時候,你需要把被鼠標遮住的部分蓋住,并重畫鼠標;當鼠標點擊時,你需要判斷鼠標的位置,還要判斷這個點擊是你的程序的,還是別人的;當鼠標點擊到菜單的時候,你要確定是菜單還是按鈕,以及是哪個菜單項,然后執行相應的操作。所有這些情況,都必須一一解決。其中有些是可以由操作系統解決的,但你要知道怎樣利用操作系統提供的資源才能讓它幫你做,還有些就必須你自己想辦法,種種問題使得圖形界面的編程變得異常復雜。
與此同時,由于圖形處理的需要,圖形界面對計算機硬件的要求也比較高。畫面絢麗的3D游戲,遠比記事本程序對系統的要求要高的多。雖然現代的計算機早已能夠滿足這些要求,但早期的計算機并不是這樣強大的。所以,在早期(也不是很遠,大約是上世紀七、八十年代)的時候,程序的界面并不是圖形,而是字符的。用戶在鍵盤上輸入文字,比如dir,系統找到相對應的命令,然后執行,執行的結果也是以一行行文字的形式輸出在可以輸出文字的設備上(當然也主要是顯示器),用戶閱讀文字,進行下一步的操作。
現代的一些科幻片,在表現黑客侵入或者是操作高級設備(比如美國國防部的核武器系統)時,往往出現操作員在啪啪啪啪快速打字,然后突然一回車,就大功告成的場景,很少會出現卡通化的菜單和工具欄。想想黑客帝國的那個接線員,你見過他什么時候抓著鼠標嗎?這種方式就叫命令行界面(CLI: Command Line Interface),由于操作員通常是坐在一個操作臺前,而這個操作臺確實可以控制整個系統,所以也被稱為控制臺界面(Console Interface)。控制臺下運行的程序,就是控制臺程序;運行控制臺程序的系統,就叫控制臺環境。控制臺看起來很高級,很酷很眩,黑客們操作的時候也顯得很高深,其實反倒是比較容易編程實現的。因為你只要處理和輸出字符就可以,系統自然會把字符放在屏幕上適當的位置。你不用去管字體大小顏色這些事,更甭提窗口、菜單和鼠標這些不存在的東西,只要把注意力全部放在程序的功能上。電腦系統也不用消耗資源來畫圖,系統自然比較高效。所以,命令行界面一出現,就得到了廣泛的應用,它的歷史可比圖形界面古老多了。和GUI程序比起來,命令行的程序通常不那么漂亮,對普通用戶來說操作也不直觀。**但由于它的高效和快捷**,命令行方式的程序迄今仍然在使用,命令行方式不但沒消失,相反,有許多系統反而更加加強這部分的功能,譬如 Windows7 下的 [Windows PowerShell](http://zh.wikipedia.org/wiki/Windows_PowerShell),按下“Windows”徽標鍵(鍵盤左下側類似一個窗戶的圖案),輸入PowerShell試試,進入后試試ls & tab,可以像Linux的終端一樣自動補全噢~
在很多時候,人們寧可使用命令行的程序來完成某些工作,這一點在BSD、 Linux和其它的UNIX系統中體現較為明顯。DOS就是一個標準的控制臺環境,Windows系的操作系統,也提供了控制臺環境,不過連雞肋都不如就是。還有很多的GUI程序,借鑒控制臺方式,仍然保留有直接使用鍵盤操作的方法。比如魔獸爭霸,幾乎每個命令都有快捷鍵以加速操作。
實際上,很多系統管理員更偏愛控制臺程序,除了它比圖形界面程序更高效之外還有一個原因:同樣要增加實現一個選項,控制臺只要增加一個輸入字符作為開關,而圖形界面至少需要增加一個按鈕。想想看,屏幕上是可以增加的按鈕多還是可以增加的字符數多呢?**所以控制臺程序往往更能實現紛繁復雜的功能,只要你記得住相應指令。**
讓我們在Windows下打開一個控制臺環境并使用幾個控制臺程序感受一下。Linux下的后邊附錄部分會單獨截圖演示。假如你使用的是Windows XP,點擊開始,找到程序->附件,在里面有一個叫“命令提示符”的快捷方式,點擊運行它。Windows7下類似,也可以點擊開始后輸入`cmd`. 還可以同時按住「Windows」徽標鍵和R,在彈出的窗口中輸入`cmd`。
你是不是看到了一個窗口,沒有菜單,沒有工具欄,只有標題欄和最大最小化的按鈕,這就是Windows下的控制臺環境,在這里就可以運行控制臺程序。現在,輸入`dir`,然后回車。你看到了輸出吧,這就是控制臺程序的運行了。只要輸入命令再回車,就可以運行了。再來運行一個,`time`,再來一個,`ipconfig`。最后再來一個,`help`。他給出了當前系統提供的各種命令,你可以看著提示分別試一試。其實不止可以運行這些,試試 `notepad`,你發現了什么?`explorer`, `calc`等等都是可以這樣運行的哦。玩夠了,好吧,輸入`exit`,再回車,控制臺環境就被關閉了。有沒有發現 Windows對命令行界面一點也不友好,相比之下Linux和MAC OS則對命令行界面友好地多,所以也才會有了cygwin之類的軟件出現。
控制臺程序容易編寫,易于理解,所以對于初學者,控制臺程序是比較好的選擇。在學會了控制臺程序的基礎上,再轉到窗口程序就比較輕松了。
### 圖形用戶界面編程
黑客們很偏愛Console,但對于普通用戶來說,圖形界面是他們更熟悉的。我們大多數人也喜歡編寫GUI程序,因為那看起來似乎更友好也似乎更有成就感,那怎樣才能編寫GUI程序?
每一個操作系統,都會提供一套API,如果該系統支持GUI,那么它的API中就會有一個圖形子系統和窗口管理子系統。其中圖形子系統包括了基本圖形元素的繪制,比如畫點線面、顯示文字圖片和上色渲染等等,窗口管理子系統首先會包含圖形子系統,再增加包括窗口和窗口元件的繪制、窗口的遮蓋、移動調整,以及鼠標點擊這類事件的傳遞處理等等這些內容。Windows下,圖形子系統就叫[GDI](http://zh.wikipedia.org/wiki/%E5%9B%BE%E5%BD%A2%E8%AE%BE%E5%A4%87%E6%8E%A5%E5%8F%A3)(Graphics Device Interface)。為了高效處理多媒體編程,微軟在Windows95發布前夕開發出了[DirectX](http://zh.wikipedia.org/wiki/DirectX)——除了圖形之外它還整合了很多其它功能,用它搞出了大量的Windows游戲。另一套著名的圖形API則是跨平臺&跨編程語言的[OpenGL](http://zh.wikipedia.org/wiki/OpenGL),渲染能力很強!!
另外值得一提的就是微軟自Vista發布以來廣泛用于界面開發的WPF,WPF 是下一代圖形API 在桌面上的延伸。以WPF 撰寫應用程序,具有更高的視覺品質,Win7豐富的界面效果很大程度上要歸功于[WPF](http://zh.wikipedia.org/wiki/Windows_Presentation_Foundation)的應用。
即使有圖形庫窗口管理庫,GUI編程仍然是相當的繁瑣。首先是要完成某個工作必須填寫大量按部就班的代碼,而且這些代碼在程序內部和各個程序之間重復著,這提示人們應該在圖形庫的基礎上作進一步的抽象。簡單來說就是要在畫點畫線函數的基礎上做出畫二次曲線畫立方體的模塊。幸運的是,這些工作已經有人完成了,而且是不止一套。這些東西按照功能強弱,有的叫圖形用戶界面庫,有的則叫應用程序框架。在Windows下,使用VC++的人可以選擇[MFC](http://zh.wikipedia.org/wiki/VC%2B%2B)[ATL](http://zh.wikipedia.org/wiki/Active_Template_Library),如果你選擇.NET陣營,[.NET Framework](http://zh.wikipedia.org/wiki/.NET%E6%A1%86%E6%9E%B6)就是你最好的選擇,結合C#開發比較方便。
如果你希望程序不止在Windows使用,那么跨平臺的[Qt](http://zh.wikipedia.org/wiki/Qt), [GTK+](http://zh.wikipedia.org/wiki/GTK%2B), [wxWidgets](http://zh.wikipedia.org/wiki/WxWidgets) 都是你的好選擇。它們在保證效率的同時,適當抽象,撫平了底層操作系統的差異。對于學習C++的人來說,上述庫都是可以用的,當然也有其它語言支持——比如Python。這三個平臺相對來說QT的資料會多一些,但是有一定的版權問題困擾,不過個人使用沒有問題。
- Introduction
- Part I Introduction to Programming
- 第一章-編程所謂何物
- 第二章-咋學編程
- 第三章-編程進階-數據結構與算法
- 第四章-操作系統及項目開發雜談
- 控制臺和圖形用戶界面
- 工程和單個文件的關系
- 第五章-編程語言
- 第六章-編程方法論雜談
- 好書哪里找
- 高效使用搜索引擎
- 好習慣
- 文本編輯器
- 版本控制
- 編程開發
- 第七章-教材推薦及其它
- 數據結構與算法類
- Operating System
- C
- C++
- Java
- Python
- Golang
- Network
- 數據庫
- Web-前端
- Web-后端
- 機器學習
- Linux
- GUI
- Android開發
- 數據挖掘與分析
- Spark
- 雜項