Windows精解:視窗類別釋疑

來源:互聯網
上載者:User

從上一篇我轉載如何進行Windows SDK編程開始,我希望可以藉此補充一下Windows編程的一些背景知識。之所以這樣,是因為在我前面介紹“SW系統的視窗類別”時,假設了讀者對Windows介面編程已經有一定的瞭解。

上一篇主要從介紹“如何用”的角度闡述Windows編程。但是我個人習慣“打破沙鍋問到底”,很多東西是靠“悟”,而不是“記”。所以這一篇我們聊聊Windows SDK為何會是如今這個樣子的。

對於一個經典的WinMain函數,通常包含三步:

  1. 註冊視窗類別(RegisterClass)。
  2. 建立並顯示視窗(CreateWindow and ShowWindow)。
  3. 訊息迴圈(MessageLoop)。即:取得訊息 -> 指派訊息 -> 處理訊息。

視窗程序需要“建立並顯示視窗”,這顯而易見。關於“訊息迴圈”也容易理解,並且我們在“SW系統簡介”中描述已經得非常詳細。

我相信最令人迷惑的是:“視窗類別”是什麼概念?為什麼需要RegisterClass?

有人回答:“視窗類別”是同類視窗的公用屬性,是這一類視窗的共用資料
有人回答:“視窗類別”是同類視窗的預設資料(屬性)

回答視窗類別資料是共用資料的,錯誤。因為我們知道每一個視窗都有自己獨立的菜單、表徵圖、視窗過程(WindowProc,這個最重要了)等等。它們並不存在共用關係。回答是預設資料(屬性)的,正確,但沒有回答為什麼需要預設屬性,更沒涉及到更為重要的原因。

我們先來看看CreateWindow與CreateDialog的原型:

HWND CreateWindow(
    LPCTSTR lpClassName,
    LPCTSTR lpWindowName,
    DWORD dwStyle,
    int x,
    int y,
    int nWidth,
    int nHeight,
    HWND hWndParent,
    HMENU hMenu,
    HINSTANCE hInstance,
    LPVOID lpParam
);

 

HWND CreateDialog(      
    HINSTANCE hInstance,
    LPCTSTR lpTemplate,
    HWND hWndParent,
    DLGPROC lpDialogFunc
);

為什麼普通視窗(Window)的建立不是象對話方塊(Dialog)一樣,直接把視窗過程(WindowProc)傳進去,甚至把其他視窗類別相關的資料全部直接在CreateWindow時傳入?也許有人回答說,這是為了減少CreateWindow的參數個數。——呵呵,我還真不知道怎麼去證明這種說法是錯的。但是我固執的認為我下面給出的理由要充分些。

聽說過序列化(Searialize)技術嗎?有讀者馬上回答:知道,這是MFC中把對象寫入磁碟和從磁碟中讀入並還原出這些對象的技術。這個回答我給它4分(滿分5分)。是的,序列化(Searialize)是對象持久化和還原的技術。但這不是MFC才開始有,而是DOS下Turbo Vision就已經有的一個技術。

對話方塊是什嗎?對話方塊其實是支援了序列化(Searialize)技術的特殊視窗,它在初始化的時候,從資源中還原(建立)出它的各個子視窗。只是,與普通序列化(Searialize)不太一樣的是,對象持久化過程不是對話方塊做,而是對話方塊編輯器負責的。

無疑,基於對話方塊進行可視化編程是相當友好的。那麼,從支援這種可視化編程的角度來看,我們需要支援序列化(Searialize),需要從磁碟中建立視窗。我們再回頭看看CreateWindow函數的原型,你將發現,這些參數是“可序列化(可存檔)”的。而且,你立刻意識到,視窗過程(WindowProc)是不可序列化的。

我們知道,序列化技術需要RuntimeClass技術進行對象的動態建立。而所謂的RuntimeClass技術,無非是建立了類唯一標識(如類名、GUID等)到類建立函數(其他的附屬資料是比較次要的)的映射而已。

現在到了關鍵:為了支援從磁碟還原視窗對象,Windows需要引入視窗類別名,並建立它與視窗過程(WindowProc)的映射。——這正是RegisterClass存在的意義。而RegisterClass中其他的視窗類別屬性是次要的,並且也許前面說得沒錯,這些屬性的存在,只是為了減少CreateWindow函數的參數個數。

補充:點擊這裡瞭解RuntimeClass與Searialize的實現機理。

補充:“紳士亦花心”提到了GDI資源的共用問題。應當承認,我前面說“視窗類別資料是共用資料”這種說法錯誤,是比較武斷的說法。是的,Windows必須面對GDI資源的共用問題,不同視窗亦存在資源共用的事實。更為合理的說法是:每一個視窗可以獨立設定自己的菜單、表徵圖、視窗過程,但菜單/表徵圖等GDI資源是可以共用的。因為我們知道,Windows對GDI資源的共用策略是,視窗不擁有GDI資源(菜單/表徵圖等)的所有權,使用者必須為GDI資源的生命週期負責。換句話說,視窗只擁有菜單/表徵圖控制代碼。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.