天天看點

Windows視窗開發原理(視窗的建立&消息機制)

在windows應用程式中,視窗是其非常重要的一個元素。并且視窗是通過視窗句柄來辨別的。句柄(HANDLE)是windows程式中一個重要的概念,其辨別各種資源,包括圖示句柄(HICON)、光标句柄(HCURSOR)和畫刷句柄(HBRUSH)。

下面以一個帶有自定義的畫刷、光标和圖示的windows視窗為例,講解win32視窗的建立過程。

windows程式是基于事件驅動方式的程式設計模式,主要是基于消息的。比如當使用者在視窗中畫圖的時候,按下滑鼠左鍵,此時os會感覺到這一事件,于是将此事件包裝成一個消息,投遞到應用程式的消息隊列中,然後應用程式從消息隊列中取出消息,經過transltor翻譯、分發消息,然後交由os調用

視窗過程函數(應用程式注冊的回調函數)或(DefWindowProc系統預設的回調處理函數)進行處理。

視窗的特征是由WNDCLASS結構體來定義的,其定義了這個視窗的基本屬性,是以我們隻需填充結構體各成員資訊即可。

Windows視窗開發原理(視窗的建立&消息機制)
Windows視窗開發原理(視窗的建立&消息機制)

View Code

這裡要首先說明下各類型定義

其中的第二個成員變量lpfnWndProc是一個函數指針,指向視窗過程函數,視窗過程函數時一個回調函數。該函數簽名如下:

故視窗函數按照如下簽名定義,實作如下:

回調函數機制:

⑴定義一個回調函數(WindowProc);

⑵提供函數實作的一方在初始化的時候,将回調函數的函數指針注冊給調用者(注冊wc.lpfnWndProc = WindowProc);

⑶當特定的事件或條件發生的時候,調用者使用函數指針調用回調函數對事件進行處理(eg輕按兩下滑鼠按鈕時間發生後,os調用視窗過程函數進行處理)。

 通過ATOM WINAPI RegisterClass( _In_ CONST WNDCLASS*lpWndClass);進行視窗類注冊。形參為WNDCLASS位址。傳回值為ATOM.

 建立視窗通過CreateWindow函數來實作,該函數API資訊如下:

Windows視窗開發原理(視窗的建立&消息機制)
Windows視窗開發原理(視窗的建立&消息機制)
Windows視窗開發原理(視窗的建立&消息機制)
Windows視窗開發原理(視窗的建立&消息機制)

 建立完視窗後,要對視窗進行具體的顯示。

顯示函數API如下:

在調用ShowWindow函數之後,需要調用UpdateWindow來重新整理視窗。

注意:UpdateWindow函數通過發送一個WM_PAINT消息來重新整理視窗,UpdateWindow将WM_PAINT消息直接發送給了視窗過程函數進行處理,而沒有放到消息隊列中。

在建立視窗、顯示視窗、更新視窗後,我們需要編寫一個消息循環,調用GetMessage函數不斷從消息隊列中取出消息,并進行相應。

消息結構體:

Windows視窗開發原理(視窗的建立&消息機制)
Windows視窗開發原理(視窗的建立&消息機制)

代碼如下:

此處的Windows應用消息的消息處理機制如下圖:

Windows視窗開發原理(視窗的建立&消息機制)

(1)os接收到應用消息的視窗消息【比如當使用者在視窗中畫圖的時候,按下滑鼠左鍵,此時os會感覺到這一事件,于是将此事件包裝成一個消息】,将消息投遞到該應用消息的消息隊列中。

(2)應用程式在消息循環中調用GetMessage函數從消息隊列中取出一條一條的消息。取出消息後,應用程式可以對消息進行一些預處理,比如放棄對某些消息的相應或調用TranslateMessage産生新的消息。

(3)應用程式調用DispatchMessage将消息回傳給os。消息MSG結構體中包含接受消息的視窗的句柄。是以DispatchMessage函數總能進行正确傳遞。

(4)os利用WNDCLASS結構體的lpfnWndProc成員儲存的視窗過程函數的指針調用視窗過程,對消息進行處理(即“系統給應用程式發送了消息”)。

Windows視窗開發原理(視窗的建立&消息機制)
Windows視窗開發原理(視窗的建立&消息機制)

繼續閱讀