Windows學習筆記6 視窗與訊息《四》

2021-06-19 18:20:09 字數 3257 閱讀 9923

訊息處理

1、一般在視窗過程中使用switch和case結構來確定視窗過程接收到的是什麼訊息,以及如何處理它,

注意:<1>視窗過程處理訊息後,必須返回0;

<2>視窗過程不予處理的所有訊息應該被傳遞給defwindowproc函式,從defwindowproc返回的值,再由視窗過

程返回,如:return defwindowproc(hwnd, message, wparam, lparam);

2、訊息介紹

<1>wm_create

這是視窗過程接收的第乙個訊息,也可能是其處理的第乙個訊息,

訊息觸發:windows在winmain中處理createwindow函式時,windows會呼叫應用程式的視窗過程(注意:此時wm_create訊息不是通過訊息迴圈進入視窗過程的),將視窗過程的第乙個引數設定為剛設定的視窗控制代碼,將第二個引數設定為wm_create,視窗過程執行完成後,將控制傳回給windows,windowss然後從cratewindow函式呼叫中返回到應用程式的winmain函式中,繼續執行winmain中下面的**。

注意:通常,視窗過程在處理wm_create訊息期間,進行一次視窗初始化。

<2>wm_paint

當視窗顯示區域的一部分顯示內容或者全部顯示內容變為無效,以致於必須「更新畫面」時,將會由這個訊息通知應用程式,

什麼時候視窗的顯示區域會變得無效?

1* 在最初建立視窗的時候,這時整個顯示區域都是無效的,因為程式還沒有在視窗上畫任何東西,視窗第一次接收到wm_paint訊息(通常發生在winmain中呼叫updatewindow時)指示視窗過程在螢幕上畫一些東西。

2* 在使用者改變視窗大小後,顯示區域的顯示內容重新變為無效。

3* 當使用者將視窗最小化,然後再次將視窗恢復為以前的大小時,windows不會儲存顯示區域的內容,而是令視窗無效,傳送wm_paint訊息給視窗過程,並自動恢復其視窗的大小。

4* 在移動視窗以致其與其他視窗相互重疊時,windows不儲存乙個視窗被另乙個視窗所遮蓋的部分,當這一部分不再被遮蓋之後,它就被標誌為無效,視窗過程接收到乙個wm_paint訊息,以更新視窗內容。

5* 應用程式自己修改視窗的內容。

發生以下幾種事件之一時,視窗過程將接收到乙個wm_paint訊息:

<1>在使用者移動視窗或顯示視窗時,視窗中先前被隱藏的區域重新可見;

<2>使用者改變視窗的大小(如果視窗類別中有cs_hredraw和cs_vredraw);

<3>程式使用scrollwindow和scrolldc函式滾動顯示區域的一部分;

<4>程式使用invaldaterect或invalidatergn函式刻意產生wm_paint訊息;

<5>在某些情況下,顯示區域的一部分被臨時覆蓋,windows試圖儲存乙個顯示區域,並在以後恢復它,但這不一定能成功,在以下情況,windows可能傳送wm_paint訊息:

windows擦除覆蓋了部分視窗的對話方塊或訊息框;

功能表下來出來,然後被釋放;

顯示工具提示訊息;

特別注意:在某些情況下,windows總是儲存它所覆蓋的顯示區域,然後恢復它,這些情況是:

滑鼠,游標劃過顯示區域;

圖示拖過顯示區域。

3、wm_destroy

這一訊息指示:windows正在根據使用者的指示關閉視窗,該訊息通常是使用者單擊close按鈕或者在程式的系統選單中選擇close時發生的。

視窗與訊息總結:

1、在windows程式設計中,程式的所有實際動作都發生在視窗過程中,windows程式的一切動作都是在回應傳送給視窗過程的訊息。

windows給視窗傳送訊息的實際含義是windows呼叫應用程式的視窗過程函式,並將訊息引數傳遞給該函式。

2、關於佇列化訊息與非佇列化訊息:

訊息分為佇列化的和非佇列化的,佇列化的訊息是指由windows放入到應用程式的訊息佇列中的,在程式的訊息迴圈中,重新傳回並分配給視窗過程;非佇列化的訊息是在windows呼叫視窗時,直接傳送給視窗過程的訊息,即:佇列化的訊息要經過訊息迴圈,再傳遞給視窗過程;非佇列化的訊息直接傳遞給視窗過程。

注意:任何情況下,視窗過程都獲得視窗的所有訊息,包括佇列化的和非佇列化的,視窗過程是視窗的訊息處理中心。

佇列化訊息基本上是使用者輸入的結果,如wm_keydown,  wm_keyup, wm_char, wm_mouse, wm_lbuttondown等,還包括wm_timer, wm_paint, wm_quit等訊息。

非佇列化訊息是其他一些訊息,許多情況下,非佇列化訊息來自呼叫特定windows函式。例如,winmain中呼叫createwindow時,windows在其處理中直接給視窗過程傳送的wm_create訊息;當winmain中呼叫showwindow時,windows給視窗傳送的wm_size和wm_showwindow訊息;當winmain函式呼叫updadewindow函式時,windows給視窗過程傳送的wm_paint訊息等。

3、進一步理解視窗過程(重點)

從視窗過程的角度看,訊息是以一種有序的、同步的方式進出視窗過程函式的,視窗過程可以處理也可以不處理。

注意:<1>、雖然windows程式可以多執行序執行,但是訊息迴圈和視窗過程不是併發執行的。

每個執行序的訊息佇列只為視窗過程在該執行序中執行的視窗處理訊息,當乙個訊息迴圈從其訊息佇列中接收乙個訊息,然後呼叫dispatchmessage將訊息傳送給視窗過程時,直到視窗過程將控制傳回給windows, dispatchmessage 才結束執行。也就是說,在訊息迴圈進行下乙個迴圈從訊息佇列中取出訊息之前,上乙個取出的訊息已經被視窗過程處理完成了。

<2>、雖然訊息不能併發處理,但是訊息可以巢狀處理。

視窗過程是可重入的,例如視窗過程可以在處理某個訊息a時,呼叫乙個函式f來給視窗過程傳送另乙個訊息b,這時候,視窗過程必須在這個函式f返回之前完成對第二個訊息b的處理,在函式f返回後,視窗過程將繼續完成對第乙個訊息a的處理,(類似於函式的巢狀呼叫)。

<3>、注意由於<2>,引起的問題。

例如,在視窗過程處理某個訊息時,定義乙個static區域性變數c,然後呼叫乙個windows函式,在這個函式返回時,前乙個靜態變數c的值有可能已經改變。(可能呼叫的這個函式產生了另一條訊息d,並且視窗過程在處理訊息d時,改變了static區域性變數c的值),因此,當視窗過程必須儲存它從訊息中獲得的資訊,並要在處理另乙個訊息時使用這些資訊,這些資訊可以用視窗的static變數或全域性變數來儲存。

4、特別注意:雖然視窗過程函式是我們自己編寫的,但是別忘了最後還有defwindowproc部分的工作,應該將它考慮為我們訊息處理過程的一部分。

Windows學習筆記4 視窗與訊息《二》

windows最重要的三個子系統 三個dll kernel,user,gdi kernel 處理所有在傳統上由作業系統核心處理的事務 記憶體管理,裝置io,多工管理 user 是指使用者介面,實現所有視窗執行機制 gdi 實現圖形裝置介面,允許程式在螢幕或印表機上顯示文字和圖形。關於wndclass...

Windows視窗與訊息

進行windows程式設計,實際上是在進行一種物件導向的程式設計 oop 這一點在windows中使用得最多的物件上表現最為明顯。這種物件正是windows之所以命名為 windows 的原因,它具有人格化的特徵,甚至可能會在您的夢 現,這就是那個叫做 視窗 的東西。桌面上最明顯的視窗就是應用程式視...

Windows程式設計學習筆記(三) 視窗和訊息

messagebox函式會建立乙個 視窗 在windows中,乙個視窗就是螢幕上乙個矩形區域,它接收使用者的輸入並以文字或圖形的格式顯示輸出內容。messagebox函式建立乙個視窗,但只是乙個功能有限的特殊視窗。訊息視窗有乙個帶關閉按鈕的標題列 乙個選項圖示 一行或多行文字,以及最多四個按鈕。當然...