Win32窗口機制和消息機制整體流程

[摘要] 本節課通過一張圖,詳細的介紹了Windows的窗口機制和消息機制整體流程,讓你一目瞭然。 Windows系統,是窗口作爲基礎的系統,以消息機制作爲運轉機制的系統。我們學習Windows編程(Win32編程)也就必須先掌握這兩個根本機制即窗口機制和消息機制。

    Windows系統,是窗口作爲基礎的系統,以消息機制作爲運轉機制的系統。我們學習Windows編程(Win32編程)也就必須先掌握這兩個根本機制即窗口機制和消息機制。
    本節課結合一張Win32程序內部運作機制的整體流程圖,來講述整體的流程。

Windows窗口機制和Windows消息機制

    我們本節課就是把這張圖講清楚。
    我們在WinMain函數中寫這個代碼,也就是入口函數寫這個代碼。在上一節課《Windows零基礎入門:2.6 Win32第一個程序和計時文字閃爍》有完整代碼。我們的代碼要完成的功能就是創建一個窗口,然後完成計時和閃爍的功能。
    Windows中窗口如何創建出來,可不是一個CreateWindow函數就簡單創建出來的。它經歷了很多。我們應該深入學習,而不只是用一個函數,去記這個函數那些參數。這樣學習是沒用的,會讓你始終不知所以然,總是摸不透。我們C++技術網推出的這個課程,會深入淺出的帶你領略這般精彩。我相信,當你學完這些深入的背景知識後,即使你不用記住這些背景知識,有個印象,就足以讓你在日後使用這些函數時胸有成竹,而不是雲裏霧裏。我們的課程要讓你知道,是什麼,怎麼用,更重要的是爲什麼!!
    Windows編程中,窗口機制部分和消息機制,是最爲根本的兩個技術點。我們這裏就來整體上都串通來介紹,讓你一開始就知道是怎麼一回事。
    以上那張圖,請仔細看幾遍,然後對照下面的介紹來理解。這個圖,沒有太多的標註,需要文章來解釋,一開始看不懂是正常的。
    我們以代碼爲主線來講解。我們的代碼,就是WinMain中的代碼,這些代碼創建了一個窗口,同時有一些功能。這些代碼在入口函數中。我們啓動一個程序,系統就建立一個進程。我們的exe沒有運行的時候,就是一個文件而已。運行起來,系統給他在內存分配一些空間,這些內存就是進程的內存空間。這個進程就是在內存中執行的程序了。我們就把進程理解爲我們的程序。而進程只是提供一個程序執行需要的內存空間以及相關的資源場所。這些內存空間和資源場所都是提供給進程的線程來使用的。
    打個比方,進程就像我們的家,線程就像家裏的成員。代碼是在線程中執行的,因爲線程的東西纔會跑到CPU裏,進程就是一個場所,不會動的。而每一個進程至少有一個線程,就是主線程了。那麼我們的WinMain函數就是在主線程裏了。在上圖中,就顯示爲主線程代碼。途中只是一部分,實際上,窗口過程也在主線程中,我們這個程序就是一個線程的程序。這些進程線程的理論知識,請學習操作系統課程的進程部分。
    我們程序有了這個主線程,就可以執行代碼了。
    1.註冊窗口類,執行RegisterClass。必須要註冊窗口類,我們才能創建我們自己的窗口。實際上,窗口類有三種:系統窗口類、應用程序全局窗口類和應用程序局部窗口類
    系統窗口類中一部分是系統內部使用的,而另一部分是可以供系統所有進程使用的,這些窗口類就是基本的控件窗口類。後面會詳細介紹。
    應用程序全局窗口類,就是註冊窗口類時以CS_GLOBALCLASS標誌註冊的窗口類,這個窗口類在這個進程中,所有模塊都可以使用。模塊一般是dll模塊。我們知道的程序的皮膚庫,很多都是以這種形式實現的,dll中註冊的應用程序全局窗口類,我們程序就可以直接使用這些漂亮的皮膚庫提供的控件了。
    應用程序局部窗口類則是沒有CS_GLOBALCLASS標誌註冊的窗口類,這個窗口類只在模塊範圍內使用。我們的EXE如果加載了其他的dll模塊,此時EXE的主線程註冊的應用程序局部窗口類對於dll來說,是看不見的,也就不能使用這個局部窗口類來創建窗口。
    如果你對dll這些不懂,也不要緊,只要知道它就是被加載到進程中的一個部件而已。就像你把冰箱放在了你的房子一樣。冰箱只能看到它冰箱內的東西和房子全局的東西。
    RegisterClass函數在圖中的三個箭頭分支,表示他可以註冊應用程序全局和局部的窗口類,系統窗口類由系統來處理,不要我們來創建和銷燬。註冊窗口類其實就是在對應的窗口類表填寫一個窗口類的信息而已,供創建窗口時查找使用。
    2.創建窗口,執行CreateWindow。這個函數就是根據指定的窗口類來創建一個窗口。你可以指定爲系統窗口類來創建標準的控件,比如按鈕控件,此時就不需要執行註冊,因爲系統會自動幫我們註冊。只有我們要根據我們自己定製的窗口類創建窗口時,才需要先註冊窗口類。不管是創建標準控件還是你定製的窗口類,都是要去窗口類表查找對應的窗口類信息的。執行的順序就是:應用程序局部窗口類 -> 應用程序全局窗口類 -> 系統窗口類。也就是說,創建窗口就需要去按照這個順序查找你指定的窗口類名稱,找到就不再往後查找,否則就一直往後,如果最後都找不到,那麼創建窗口就會失敗。這個就是圖中標註了1,2,3箭頭的意思。
    3-4.顯示窗口。創建好窗口後,就要顯示它。執行的是ShowWindow和UpdateWindow函數。這個就是將窗口顯示出來。
    以上就是窗口的創建過程。窗口顯示後,我們要操作窗口,這就是消息機制完成的。
    5.獲取消息。一個窗口對應一個窗口的消息隊列,隊列裏的消息都是窗口的,窗口都要處理這些消息的。處理了這些消息,就實現了交互,實現了功能。在主線程函數中,GetMessage函數循環不斷地從消息隊列不斷的獲取消息,如果獲取到的消息是WM_QUIT,循環就停止,也就意味着程序結束了。如果消息隊列中沒有消息了,系統會將這個程序掛起來,直到有消息了,才喚醒它來處理消息。
    6.獲取了消息之後,要對消息進行處理,有些消息是原始消息,直接無法處理,需要轉換一下。
    7.轉換成正確格式的消息後,就要把消息發給合適的地方來處理了。分發了這個消息之後,就進入下一輪的獲取消息,不斷循環。分發的路線就是先根據消息裏的窗口句柄,找到窗口,然後去查找這個窗口由哪個窗口類創建,找到窗口類後,就找到這個窗口類指定的窗口過程函數,這樣這個消息就分發給這個窗口過程了。5-7三步構成的循環就是我們聽說的消息循環了。
    而窗口過程中,就是通過switch來分類處理消息,完成一些功能的。Win32程序的功能,都在這個窗口過程中完成。
    那麼最後一個問題,窗口消息如何來的?
    我們窗口顯示之後,我們的單擊窗口、拖動窗口等,系統都會捕捉到我們的光標在窗口上面有動作,系統就識別出來了,然後就處理成標準的消息,投遞到這個窗口的消息隊列中。還有一種就是窗口過程處理消息的過程中,爲了完成一個複雜的功能,要做一系列的基本動作,只要有一個動作功能,就要產生一個新的消息,這個消息也會投遞到窗口消息隊列中。其他的進程也可以向我們的窗口發送消息,進而實現進程間的通信。
    以上就是整個窗口窗口機制和消息機制的一個整體過程。更詳細的講解,請繼續學習後面的課程內容,這裏只是一個大概的流程結果,重在整體的流程邏輯,一些細節,可能有所忽略,也是讓整體流程更加的清晰。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章