進行Windows程序設計,實際上是在進行一種對象導向的程序設計(OOP)。這一點在Windows中使用得最多的對象上表現最為明顯。這種對象正是Windows之所以命名為「Windows」的原因,它具有人格化的特征,甚至可能會在您的夢中出現,這就是那個叫做「窗口」的東西。
桌面上最明顯的窗口就是應用程序窗口。這些窗口含有顯示程序名稱的標題列、菜單甚至可能還有工具列和滾動條。另一類窗口是對話框,它可以有標題列也可以沒有標題列。
裝飾對話框表面的還有各式各樣的按鍵、單選按鈕、復選框、清單方塊、滾動條和文字輸入區域。其中每一個小的視覺對象都是一個窗口。更確切地說,這些都稱為「子窗口」或「控件窗口」或「子窗口控件」。
作為對象,使用者會在屏幕上看到這些窗口,并通過鍵盤和鼠標直接與它們進行交互操作。更有趣的是,程序寫作者的觀點與使用者的觀點極其類似。窗口以「消息」的形式接收窗口的輸入,窗口也用消息與其它窗口通訊。對訊息的理解將是學習如何寫作Windows程序所必須越過的障礙之一。
這有一個Windows的消息范例:我們知道,大多數的Windows程序都有大小合適的應用程序窗口。也就是說,您能夠通過鼠標拖動窗口的邊框來改變窗口的大小。通常,程序將通過改變窗口中的內容來響應這種大小的變化。您可能會猜測(并且您也是正確的),是Windows本身而不是應用程序在處理與使用者重新調整窗口大小相關的全部雜亂程序。由于應用程序能改變其顯示的樣子,所以它也「知道」窗口大小改變了。
應用程序是如何知道使用者改變了窗口的大小的呢?由于程序寫作者習慣了往常的文字模式程序,操作系統沒有設置將此類消息通知給使用者的機制。問題的關鍵在于理解Windows所使用的架構。當使用者改變窗口的大小時,Window給程序發送一個消息指出新窗口的大小。然后程序就可以調整窗口中的內容,以響應大小的變化。
「Windows給程序發送消息。」我們希望讀者不要對這句話視而不見。它到底表達了什么意思呢?我們在這里討論的是程序代碼,而不是一個電子郵件系統。操作系統怎么給程序發送消息呢?
其實,所謂「Windows給程序發送消息」,是指Windows呼叫程序中的一個函數,該函數的參數描述了這個特定消息。這種位于Windows程序中的函數稱為「窗口消息處理程序」。
無疑,讀者對程序呼叫操作系統的做法是很熟悉的。例如,程序在打開磁盤文件時就要使用有關的系統呼叫。讀者所不習慣的,可能是操作系統呼叫程序,而這正是Windows對象導向架構的基礎。
程序建立的每一個窗口都有相關的窗口消息處理程序。這個窗口消息處理程序是一個函數,既可以在程序中,也可以在動態鏈接庫中。Windows通過呼叫窗口消息處理程序來給窗口發送消息。窗口消息處理程序根據此消息進行處理,然后將控制傳回給Windows。
更確切地說,窗口通常是在「窗口類別」的基礎上建立的。窗口類別標識了處理窗口消息的窗口消息處理程序。使用窗口類別使多個窗口能夠屬于同一個窗口類別,并使用同一個窗口消息處理程序。例如,所有Windows程序中的所有按鈕均依據同一個窗口類別。這個窗口類別與一個處理所有按鈕消息的窗口消息處理程序(位于Windows的動態鏈接庫中)聯結。
在對象導向的程序設計中,對象是程序與數據的組合。窗口是一種對象,其程序是窗口消息處理程序。數據是窗口消息處理程序保存的信息和Windows為每個窗口以及系統中那個窗口類別保存的信息。
窗口消息處理程序處理給窗口發送消息。這些消息經常是告知窗口,使用者正使用鍵盤或者鼠標進行輸入。這正是按鍵窗口知道它被「按下」的奧妙所在。在窗口大小改變,或者窗口表面需要重畫時,由其它消息通知窗口。
Windows程序開始執行后,Windows為該程序建立一個「消息隊列」。這個消息隊列用來存放該程序可能建立的各種不同窗口的消息。程序中有一小段程序代碼,叫做「消息循環」,用來從隊列中取出消息,并且將它們發送給相應的窗口消息處理程序。有些消息直接發送給窗口消息處理程序,不用放入消息隊列中。
如果您對這段Windows架構過于簡略的描述將信將疑,就讓我們去看看在實際的程序中,窗口、窗口類別、窗口消息處理程序、消息隊列、消息循環和窗口消息是如何相互配合的。這或許會對您有些幫