window窗口詳解


一、    窗口

  在圖形化的基於win32的應用程序,窗口是屏幕的矩形區域,應用程序顯示輸出並接收來自用戶的輸入,因此,一個圖形化基於win32的應用程序的首要任務之一就是創建一個窗口。

  窗口與其它窗口共享屏幕,[本事]包括來自其它應用程序的窗口,每次只有一個窗口可以接收來自用戶的輸入,用戶可以使用鼠標、鍵盤或其它輸入設備與此窗口以及擁有該窗口的應用程序進行交互。

二、    關於窗口

  這個概述描述了應用程序用來創建和使用窗口的編程單元;管理窗口之間的關系;以及大小、移動、和顯示窗口;概述包括以下主題:

三、    桌面窗口

  當你啟動系統時,它自動創建桌面窗口。桌面窗口是一個系統定義的窗口,它描繪了屏幕的背景,並作為所有應用程序顯示的所有窗口的基礎。

  桌面窗口使用位圖來描繪屏幕的背景。由位圖創建的圖案成為桌面牆紙。默認情況下,桌面窗口使用位圖來自在注冊表中指定的a.BMP作為桌面壁紙。

  一個系統配置應用程序,例如一個控制面板小程序,使用GetDesktopWindow函數返回桌面窗口的句柄。使用SystemParametersInfo函數通過wAction參數設置為SIP_SETDESKWALLPAPER和lpvParam參數指定一個位圖文件名改變桌面牆紙。SystemParametersInfo然后從指定的文件中加載位圖,使用位圖來繪制屏幕的背景,並在注冊表輸入新的文件名。

四、    應用程序窗口

  每個圖形化的基於win32應用程序至少創建一個窗口,成為主窗口,它充當用戶和應用程序之間的主要接口。大部分應用程序也或直接或間接地創建其它窗口,以執行與主窗口相關的任務。每個窗口在顯示輸出和接收來自用戶的輸入起作用。

  當你啟動一個應用程序,系統還會將一個任務欄按鈕與應用程序關聯起來。任務欄按鈕包含程序圖標和標題。當應用程序處於活動狀態時,它的任務欄按鈕以推送狀態顯示。

  本節包含以下主題:

1)  應用程序窗口的組件

  應用程序窗口包括元素,像標題欄,菜單欄,窗口菜單(以前成為系統菜單),最小化按鈕,最大化按鈕,恢復按鈕,關閉按鈕,大小邊框,客戶區域,水平滾動條,和垂直滾動條。一個應用程序的主窗口通常包括所有這些組件。下面的插圖顯示了在一個典型的主窗口的這些組件。

 

  標題欄顯示一個應用程序定義的圖標和文本行;通常,文本指定應用程序的名稱或表示窗口的目的。在創建窗口時,應用程序指定圖標和文本。標題欄也讓用戶使用鼠標或者其它指針設備來移動窗口。

  大部分應用程序包含一個菜單欄列出應用程序所支持的命令,菜單欄中的項目表示命令的主要類別。點擊菜單欄上的一個條目,通常會打開一個彈出菜單,它的條目對應一個給定類別中的任務,通過點擊一個命令,用戶指導應用程序執行任務。

  窗口菜單由系統創建和管理。它包含一組標准的菜單項,當用戶選擇它時,設置窗口的大小或位置,關閉應用程序,或執行任務,了解更多信息,參閱菜單。

  當你點擊最大化或最小化按鈕,這影響窗口的大小和位置。當你點擊最大化按鈕,系統放大窗口到屏幕大小,定位窗口的位置,因此它會覆蓋整個桌面,減去任務欄。與此同時,系統用恢復按鈕替換最大化按鈕。恢復按鈕是一個位圖,當點擊它時,恢復窗口到它原來的大小和位置。

  當用戶點擊最小化按鈕,系統縮小窗口到它任務欄的大小,將窗口放在任務欄按鈕位置上,並以正常狀態顯示任務欄按鈕。要恢復應用程序到以前的位置和大小,點擊任務欄按鈕。

  大小邊界是窗口周邊的一個區域,允許用戶能使用鼠標或指向設備調整窗口大小。

  客戶端區域時應用程序顯示輸出的窗口的一部分,像文本或圖形。例如,桌面發布應用程序在客戶端區域顯示文檔的當前頁面。應用程序需提供一個函數,稱窗口過程,以處理到窗口的輸入和在客戶區域的顯示輸出。更多信息,看窗口過程。

  水平滾動條和垂直滾動條轉換鼠標或鍵盤的輸入成值,應用程序用以水平或垂直移動客戶區域的內容。例如,一個顯示冗長文檔的文字處理應用程序通常提供一個垂直滾動條,使用戶能在文檔中上下翻頁。

  標題欄,菜單欄,窗口菜單,最小化和最大化按鈕,大小邊框和滾動條,被提及的所有作為窗口的非客戶區域。系統管理非客戶區域的大部分方面;應用程序管理窗口的所有其它。尤其是,每一個應用程序管理其客戶端區域的外觀和行為。

2)  控件、對話框和消息框

  除了主窗口,應用程序還使用幾種類型的窗口,包括控件、對話框、消息框。

  一個控件是一個窗口,應用程序用來從用戶獲取指定信息,例如打開文件的名稱或者文本選擇的所需點大小。應用程序還使用控件獲取控制應用程序特定特性所需的信息。例如,一個字處理應用程序常提供一個控件讓用戶打開或關閉自動換行。更多信息,參閱控件。

  控件總是與另一個窗口一起使用-通常是一個對話框。一個對話框是一個包含一個或多個控件的窗口。應用程序使用對話框提示用戶完成一個命令所需的輸入。例如,應用程序包含一個打開文件的命令,將顯示一個對話框,包含一個用戶指定路徑和文件名的控件。

  消息框是一個窗口,顯示提示,注意,或警告給用戶。例如,一個消息框可以通知用戶應用程序執行任務時遇到的一個問題。

  對話框和消息框通常不使用與主窗口相同的一套窗口組件。大多數都有標題欄,一個窗口菜單,一個邊框(不改變大小),和一個客戶端區域,但是它們通常沒有菜單欄,最小和最大按鈕,或者滾動條。更多信息,參閱對話框。

五、    Z順序

  窗口的Z順序表示窗口在一堆重疊窗口中的位置。這個窗口堆棧朝向沿着一個虛擬軸,z軸,從屏幕向外延伸。Z順序頂部的窗口覆蓋所有的其它窗口。Z順序底部的窗口被所有的窗口重疊。

  系統在一個列表中維護Z順序,它添加窗口到Z順序基於是否它們是最頂層窗口,頂層窗口或者子窗口。一個最頂層窗口覆蓋所有的非最頂層窗口,不管它時活動的還是前台的窗口。一個最頂層窗口有WS_EX_TOPMOST樣式,所有的最頂層窗口在Z順序里出現在任何非最頂層窗口之前,一個子窗口在Z順序里和它父窗口分組。

  當應用程序創建一個窗口時,系統將其置於同類型窗口的Z順序的頂部。你可以使用BringWindowToTop函數將一個窗口帶到同類型窗口Z順序的頂部,你能使用SetWindowPos和DeferWindowPos函數重新排列Z順序。

  用戶通過激活一個不同的窗口來更改Z順序,系統放置活動窗口在相同類型窗口的Z順序頂部,當一個窗口出現在Z順序的頂部時,它的子窗口也是如此。你能使用GetTopWindow函數搜索父窗口的所有子窗口,並返回一個在Z順序中最高的子窗口的句柄,GetNextWindow函數檢索在Z順序中的下一個或前一個窗口。

六、    創建窗口

  應用程序創建其窗口(包括主窗口),使用CreateWindow或CreateWindowEx函數,並提供定義窗口屬性所需的信息。CreateWindowEx有一個參數dwExStyle,CreateWindow沒有,否則函數相同,事實上,CreateWindow設置dwExStyle參數為0簡單調用CreateWindowEx。由於這個原因,本文其余部分僅引用CreateWindowEx。

  還有其它函數,包括DialogBox,CreateDialog,和MessageBox,用於創建指定用途的窗口,像對話框和消息框。要了解更多信息,看對話框。

  本節包含以下主題:

3)  窗口的屬性

  應用程序在創建窗口時必須提供以下的信息:

a)  窗口類

  每一個窗口都屬於一個窗口類。應用程序必須在創建該類的任何窗口之前注冊窗口類。窗口類定義一個窗口外觀和行為的大部分方面。窗口類的主要部分是窗口過程,一個函數接收並處理發往到窗口的所有的輸入和請求。系統以消息的形式提供輸入和請求。要了解更多信息,看窗口類,窗口過程,或消息和消息隊列。

b)  窗口名稱

  窗口名稱(也稱窗口文本)是一個為用戶標識窗口的文本字符串。如果存在,一個主窗口對話框或消息框通常在它的標題欄顯示它的窗口名稱。對於控件,窗口名稱的外觀依賴控件的類。按鈕,編輯控件,或靜態控件在控件占據的矩形中顯示它的窗口名稱,列表框,組合框或靜態控件不能顯示它的窗口名稱。

  應用程序創建窗口后使用SetWindowText函數改變窗口名稱。它使用GetWindowTextLength和GetWindowText函數函數從窗口獲取當前窗口名稱。

c)  窗口樣式

  每一個窗口有一個或多個窗口樣式。窗口樣式是一個命名的常量,它定義窗口外觀和行為的一個方面,而不是被窗口類指定。例如,SCROLLBAR類創建一個滾動條控件,但是SBS_HORZ和SBS_VERT樣式決定了是否創建水平或垂直的滾動條控件。一些窗口類型適用所有的窗口,但是大部分適用於指定窗口類的窗口。系統,某種程度上,類的窗口過程,解釋窗口的樣式。

d)  父母或所有者窗口

  一個窗口可以有一個父窗口。有父窗口的窗口叫子窗口。父窗口提供定位子窗口的坐標系統。有父窗口影響窗口的外觀面貌;例如,一個子窗口被修剪,這樣子窗口沒有任何部分能出現在父窗口邊界之外。沒有父窗口或者父窗口是桌面窗口的窗口叫頂層窗口。一個應用程序使用EnumWindows函數獲取它的每一個頂層窗口的句柄。EnumWindows傳遞每個頂層窗口句柄給應用程序定義的回調函數EnumWindowsProc。

  窗口可以擁有或被另一個窗口擁有。一個被擁有窗口一直出現在它的擁有者窗口的前面,當它的擁有者窗口被最小化時隱藏,當它的擁有者窗口被銷毀時銷毀。

e)  大小

f)  位置

g)  Z順序的方位

  每個窗口都有個位置、大小和在Z順序的方位。位置是窗口的左上角相對於屏幕的左上角的坐標,或子窗口的情況下,父窗口客戶區域的左上角。一個窗口的大小是以像素測量的它的寬度和高度。在Z順序中窗口的位置是在一堆層疊窗口的堆棧中的窗口的位置。更多信息,參閱Z順序。

h)  子窗口標識或菜單句柄

  一個子窗口能有一個唯一的應用程序定義值的關聯到子窗口的子窗口標識。在應用程序創建多個子窗口時,子窗口標識特別有用。當創建一個子窗口,應用程序指定子窗口的標識符。創建窗口之后,應用程序能改變窗口的標識符,使用SetWindowsLong函數。也能檢索標識符通過GetWindowLong函數。

  除了子窗口,每個窗口都可以有一個菜單。應用程序可以通過注冊窗口類時或創建窗口時提供菜單句柄來包含一個菜單。

i)  實例句柄

  每個基於win32應用程序有一個實例句柄關聯到它。當應用程序啟動時,系統提供一個到應用的實例句柄。因為它能運行同一個應用程序的多個副本。系統在內部使用應用程序的實例句柄區分另一個。應用程序必須在多個不同的窗口指定實例句柄,包括那些創建窗口。

j)  創建數據

  每個窗口可以有應用程序定義的關聯到它的創建數據。當窗口被第一次創建時,系統傳遞一個指向數據的指針給正創建窗口的窗口過程。窗口過程使用數據初始化應用程序定義的值。

4)  窗口句柄

  創建窗口之后,創建函數返回一個窗口句柄唯一的標識窗口。應用程序使用這個句柄在另一個函數指示操作到該窗口。一個窗口句柄有HWND數據類型;在聲明一個變量存儲窗口值時,應用程序必須使用這個值。

  有一些專門的常量在某些函數能替換窗口句柄。例如,應用程序在SendMessage和SendMessageTimeout函數能使用HWND_BROADCAST,或者在MapWindowPoints函數使用HWND_DESKTIP。

 

  盡管NULL常量不是窗口句柄,在一些函數你能使用它指定沒有窗口被影響。例如,為CreateWindowEx函數的hwndParent參數使用NULL創建沒有父窗口或擁有者的窗口,為MessageBox函數的hWnd參數指定NULL創建一個沒有擁有者的消息框。一些函數可能返回的實例句柄為NULL,表明給定的操作不使用與任何窗口。

  應用程序可以使用FindWindow函數發現是否在系統中存在指定類名或窗口名的窗口存在。如果存在這樣一個窗口,FindWindow返回窗口句柄。限制搜索指定應用程序的子窗口,使用FindWindowEx函數。IsWindow函數判斷是否一個窗口句柄標識一個有效的存在的窗口。

5)  創建主窗口

  每個基於win32的應用程序必須有WinMain作為它的入口點函數。WinMain執行許多任務,包括為主窗口注冊窗口類和創建主窗口。WinMain調用RegisterClass函數注冊主窗口類,調用CreateWindowEx函數創建主窗口。

  可移植性問題入口點不需要命名為WinMain。

  你的WinMain函數也能限制你的應用程序為單一實例。創建一個命名互斥鎖使用CreateMutex函數,如果GetLastError返回ERROR_ALREADY_EXISTS,你的應用程序的另一個實例存在(它創建了互斥鎖),你應該退出WinMain。

  系統不能創建主窗口之后自動的顯示它,相反,應用程序必須使用ShowWindow函數顯示主窗口。創建主窗口之后,應用程序的WinMain函數調用ShowWindow,傳遞它兩個參數:一個主窗口句柄和一個標識指定是否主窗口應該被最小或最大化,當它第一次被顯示時。通常,標識能被設置為任何以SW_前綴開頭的常量。然而,當ShowWindow被調用以顯示應用程序的主窗口,標識必須被設置為SW_SHOWDEFAULT,這個標識告訴系統根據啟動應用程序的應用定向的顯示窗口。

  如果窗口類被RegisterClass的Unicode版本注冊,那窗口只接收Unicode消息。要確定窗口是否使用了Unicode字符集,調用IsWindowUnicode。

6)  窗口創建消息

  在創建任何窗口時,系統發送消息給窗口的窗口過程。系統發送WM_NCCREATE消息在正創建窗口非客戶區域之后和發送WM_CREATE在正創建客戶區域之后。窗口過程接收到兩個消息在顯示窗口之前。兩個消息都包含指針到CREATESTRUCT結構,包括CreateWindowEx函數指定的所有信息。通常,窗口過程執行初始化任務在接收到這些消息。

  當在創建一個子窗口時,系統發送WM_PARENTNOTIFY消息給父窗口在發送WM_NCCREATE和WM_CREATE消息,在創建窗口時還發送其它消息。這些消息的數量和順序取決於窗口類和樣式以及用於創建窗口的函數。這些消息在這個幫助文件的其它主題中描述。

7)  多線程應用程序

  一個基於win32的應用程序能有多個執行線程,每個線程能創建窗口。創建窗口的線程必須包含它的窗口過程代碼。

  一個應用能使用EnumThreadWindows函數來枚舉被一個特定線程創建的窗口。這個函數傳遞到每個線程窗口的句柄依次給應用程序定義的回調函數EnumThreadWndProc。

  GetWindowThreadProcessId函數返回創建指定窗口的線程的標識。

  要設置由另一個線程創建的窗口的狀態使用ShowWindowAsync函數。

七、    一般窗口樣式

  有一般的窗口樣式和類指定的窗口樣式。一般窗口樣式以WS_前綴開頭的常量表示,它們能用OR操作符組合構成不同的類型的窗口,包括主窗口,對話框,和子窗口。類指定的窗口樣式定義了屬於預定義控件類的窗口的外觀和行為,例如編輯控件和列表框。

  應用程序通常設置窗口的樣式在創建窗口時,它也可以設置窗口的樣式在創建窗口之后用SetWindowLong函數。

  本節包含下面主題:

1)  重疊窗口

  重疊窗口是一個頂層窗口,有標題欄,邊框,和客戶區域;它的目的作為應用程序的主窗口。它也能有菜單窗口,最小化和最大化窗口,和滾動條。作為主窗口的重疊窗口通常包括所有這些組件。

  通過在CreateWindowEx函數指定WS_OVERLAPPED或WS_OVERLAPPEDWINDOW樣式,應用程序能創建一個層疊窗口。如果你使用WS_OVERLAPPED樣式,窗口有標題欄和邊框。如果你使用WS_OVERLAPPEDWINDOW樣式,窗口標題欄,大小便看,窗口菜單,和最小和最大按鈕。

2)  彈出窗口

  彈出窗口是一個專門的重疊窗口用於對話框,消息框和其它臨時窗口,出現在主窗口之外。標題欄時可選的;否則,彈出窗口和使用WS_OVERLAPPED樣式的層疊窗口一樣。

  你可以在CreateWindowEx中指定WS_POPUP樣式創建一個彈出窗口。要包含標題欄指定WS_CAPTION樣式。使用WS_POPWINDOW樣式創建一個彈出窗口,有邊框和窗口菜單。WS_CAPTION樣式必須和WS_POPUPWINDOW樣式組合才使窗口菜單可見。

3)  子窗口

  子窗口有WS_CHILID樣式,並且被限制到父窗口的客戶端區域。應用程序使用子窗口划分父窗口的客戶端區域為功能區域。你指定WS_CHILD樣式在CreateWindowEx函數中創建子窗口。

  子窗口必須有父窗口。父窗口可以時重疊窗口,團出窗口,甚至時另一個子窗口。當你調用CreateWindowEx時指定父窗口。如果你指定了WS_CHILD樣式在CreateWindowEx,但是沒有指定父窗口,系統不創建窗口。

  子窗口有客戶端區域,但沒有其它特性,除非它們被顯示的請求。一個應用程序可以為子窗口請求一個標題欄,一個窗口菜單,最小化和最大化按鈕,一個邊框,和滾動條。但是子窗口不能有菜單。如果應用程序指定了菜單句柄,在它注冊子窗口類或創建子窗口時,菜單句柄被忽略。

  定位

  系統總是定位一個子窗口相對於父窗口客戶端區域的左上角。子窗口任何部分永遠不會出現在它父窗口的邊界之外。如果一個應用程序創建了一個子窗口,大於父窗口或者定位子窗口的一些或所有延伸超過父窗口的邊界。系統剪輯子窗口;也就是說,在父窗口客戶端區域之外的部分不被顯示。影響父窗口的操作也會影響子窗口,如下。

  父窗口 子窗口

  銷毀 父窗口被銷毀之前銷毀

  隱藏 父窗口被隱藏之前被隱藏,子窗口僅在父窗口可見時可見

  移動 和父窗口客戶端區域移動移動,子窗口負責繪制它的客戶端區域在移動之后

  顯示 在父窗口顯示之后顯示

  剪裁

  系統不會自動的從父窗口的客戶端區域剪輯一個子窗口。這意味着如果它任何和子窗口在相同位置繪制父窗口繪制在子窗口之上。然而,如果父窗口有WS_CLIPCHILDREN,系統從父窗口客戶區域剪輯子窗口。如果子窗口被剪輯,父窗口不能繪制在它上面。

  子窗口可以在相同的客戶端區域重疊其它子窗口,和一個或多個其它子窗口共享父窗口的子窗口叫兄弟窗口,兄弟窗口在每一個其它的窗口客戶端區域繪制,除非一個子窗口有WS_CLIPSIBLINGS樣式,如果一個子窗口有這個樣式,它兄弟窗口的任何部分在子窗口內部的被裁剪。

  如果窗口有WS_CLIPCHILIDREN或WS_CLIPSIBLINGS樣式,輕微的性能損失,每一個窗口都占用系統資源,因此應用程序不應該不加選擇的使用子窗口,為了更好的性能,應用程序需要邏輯上划分它的主窗口,這樣做應該在主窗口過程中而不是使用子窗口。

  父窗口的關系

  應用程序可以調用SetParent函數改變現有的子窗口的父窗口。在這種情況下,系統從舊父窗口的客戶端區域移除子窗口,移動到新父窗口的客戶端區域。如果父窗口指定為NULL句柄。桌面窗口時新父窗口。在在這種情況,子窗口被繪制在桌面上,在任何其它窗口的邊框之外。GetParent函數檢索子窗口的父窗口句柄。

  父窗口放手客戶端區域的一部分給子窗口,子窗口從這個區域接收所有的輸入。父窗口的每個子窗口的窗口類不需要一樣。意思時,應用程序能看起來不同和執行不同任務的子窗口填充父窗口。例如,對話框能包含許多不同類型的控件,每個子窗口接收不同類型的用戶數據。

  子窗口只有一個父窗口,但是父窗口可以有許多子窗口。每個子窗口,同樣能有子窗口。在這個窗口鏈中,每個子窗口被叫作原始父窗口的子孫窗口,應用程序使用IsChild函數發現給定的窗口時給定的父窗口的子窗口還是子孫窗口。

  EnumChildWindows函數枚舉父窗口的子窗口。然后,EnumChildWindows傳遞每個子窗口的句柄給應用程序定義的回調函數。還枚舉給定父窗口的子孫窗口。

  消息

  系統傳遞一個子窗口的輸入消息直接給子窗口;消息沒有通過父窗口傳遞。唯一的例外時,如果子窗口已經被EnableWindow函數禁用了。在這種情況,系統傳遞原給子窗口的任何輸入消息給父窗口。這允許父窗口檢查輸入消息,如果需要並啟用子窗口。

  子窗口可以有一個唯一的標識符。在使用控制窗口時,子窗口標識符時終於的。應用程序發送消息指導控件的活動。應用程序使用控件子窗口標識符指導發往控件的消息。此外,一個控件發送通知消息到它的父窗口。通知消息包含控件的子窗口標識符,父窗口通過標識符識別哪個控件發送的消息。應用程序給其它類型的子窗口指定子窗口標識符,借助設置CreateWindowEx函數的hMenu參數一個值而不是一個菜單句柄。

4)  只有消息窗口

  只有消息的窗口能讓你發送和接收消息,它不可見,沒有Z順序不能被枚舉,也不能接收廣播消息,窗口只是簡單的派發消息。

  要創建一個只有消息的窗口,指定HWND_MESSAGE常量或一個存在的只有消息窗口的句柄在CreateWindowEx函數的hWndParent參數里。你也能改變一個存在的窗口為只有消息窗口指定HWND_MESSAGE為SetParent函數的hWndNewParent參數。

  要查詢只有消息窗口,指定FindWindowEx函數的hwndParent參數為HWND_MESSAGE。此外,如果hwndParent和hwndChildAfter參數為NULLL,FindWindowEx搜索只有消息窗口和頂層窗口。

5)  窗口邊框

  一個窗口能有下面的邊框樣式的一個

  邊框樣式 描述

  WS_BORDER 創建一個細線邊框窗口

  WS_DLGFRAME 創建一個雙邊框窗口,這一樣式常用語對話框,窗口有這一樣式不能有標題欄。

  WS_EX_DLGMODALFRAM 創建一個雙邊框窗口,不行WS_DLGFRAME,應用程序可以指定WS_CAPTION樣式創建標題欄。

  WS_EX_STATICEDGE 創建一個三維邊框樣式,用於不能接收用戶輸入的項目。

  WS_THICKFRAME 創建一個帶大小的邊框窗口。

  帶WS_OVERLAPPED或WS_POPUPWINDOW樣式的窗口有WS_BORDER樣式。默認情況下,其它邊框模式必須組合和WS_OVERLAPPED或WS_POPUPWINDOW樣式以給一個重疊窗口不同的邊框樣式。

  如果WS_POPUP或WS_CHILD樣式窗口沒有指定邊框樣式。系統創建無邊框窗口。應用程序使用無邊框子窗口來分割父窗口客戶端區域,同時保持了對用戶不可見的划分。

6)  非客戶端區域組件

  窗口的非客戶端區域能包括標題欄,窗口菜單,最小和最大化按鈕,大小邊框,和水平和垂直滾動條。應用程序創建窗口是喲哦那個這些組件的一個或多個通過指定下面的樣式在CreateWidnowEx函數。

  樣式 描述

  WS_CAPTION 創建一個有標題欄(包括WS_BORDER樣式)的窗口。

  WS_HSCROLL 創建一個有水平滾動條的窗口

  WS_MAXIMIZEBOX 創建一個有最大化按鈕的窗口,不能和WS_EX_CONTEXTHELP組合

  WS_MINIMIZEBOX 創建一個有最小化按鈕的窗口,不能和WS_EX_CONTEXTHELP樣式組合

  WS_SYSMENU 創建一個在標題欄有窗口菜單的窗口,WS_CAPTION樣式必須被指定

  WS_VSCROLL 創建一個垂直滾動條

7)  初始狀態

  下面的樣式決定一個窗口是啟用還是禁用,可見還是不可見,最小化還是最大化

  樣式 描述

  WS_DISBALED 創建一個最初禁用的窗口,禁用窗口不能接收用戶輸入消息

  WS_MAXIMIZE 創建一個最初最大化的窗口

  WS_MINIMIZE 創建一個最初最小化的窗口

  WS_VISIBLE 創建一個最初可見的窗口

8)  父和子風格

  下面的樣式影響剪切關系在父窗口和它的子窗口,以及子窗口和它的兄弟窗口。

  樣式 描述

  WS_CLIPCHILDREN 當在父窗口繪制時,排除被子窗口占據的區域,在創建父窗口時使用這個樣式。

  WS_CLIPSIBLINGS 剪切和子窗口有關系的窗口。也就是說,當一個特定子窗口接收到WM_PAINT消息時,WS_CLIPSIBLINGS樣式剪切所有其它重疊子窗口,子窗口的該區域更新被排除之外。如果WS_CLIPSIBLINGS沒有被指定,並且子窗口重疊,當在一個子窗口的客戶端區域繪制,會繪制在其它鄰居子窗口的客戶端區域時可能的。

  擴展風格

  可以在CreateWindowEx函數dwExStyle參數指定下面的樣式

9)  樣式 描述

  WS_EX_ACCEPTFILES 用這個樣式創建的窗口接收拖放文件。

  WS_EX_CONTEXTHELP 包含一個問號在窗口的標題欄。當用戶點擊問號,光標成帶指針的疑問號。如果用戶點擊一個子窗口,子窗口接收到WM_HELP消息。子窗口應該將笑嘻嘻傳遞給父窗口過程,該過程應該調用WinHelp函數使用HELP_WM_HELP命令。應用程序顯示一個彈出窗口,通常包含子窗口的幫助。

  WS_EX_CONTEXTHELP 不能和WS_MAXMIZEBOX或WS_MINIMIZEBOX樣式使用。

  WS_EX_CONTROLPARENT 允許用戶使用tab鍵在窗口的子窗口之間導航。

  WS_EX_DLGMODALFRAME 創建一個雙邊框對話框,不像WS_DLGFRAME樣式,應用也能指定WS_CAPTION樣式創建窗口的標題欄。

  WS_EX_NOPAENTNOTIFY 指定使用這個樣式創建的子窗口在窗口創建或銷毀時不會像父窗口發送WM_PARENTNOTIFY消息。

  WS_EX_TOPMOST 指定使用這個樣式創建的窗口應該被妨礙在所有非頂層窗口之上,即使在窗口去激活化時也在它們之上。

  WS_EX_TOLLWINDOW 創建一個工具窗口;那是一個用在浮動的工具欄。一個工具欄有標題欄比普通的短。工具欄不會出現在任務欄或者在在意按下ALT+TAB出現的窗口中。如果工具欄窗口有系統菜單,它的圖標不會顯示在標題欄。然而你能顯示系統菜單通過右擊或輸入alt+space。

八、    窗口的關系

  窗口可以時被擁有窗口,禁用窗口,前景窗口和背景窗口。以不同的方式,窗口和用戶或其它窗口關聯。

  被擁有的窗口

  一個重疊窗口或彈出窗口能被另一個重疊窗口或彈出窗口擁有,擁有幾個約束條件。

  一個被擁有窗口一直在它的擁有者之上在Z順序上。

  系統自動的銷毀一個擁有的窗口,在它的所有者窗口被銷毀時。

  擁有者隱藏被擁有者也隱藏。

  只有重疊窗口或彈出窗口可以是擁有者窗口;子窗口不能時擁有者窗口。應用程序創建一個被擁有窗口指定擁有者窗口句柄在CreateWindowEx的hwndParent參數當它創建一個窗口用WS_OVERLAPPED或WS_WS_POPUP樣式。hwndParent參數必須被指定為重疊窗口或彈出差un公開,如果hwndParent標識一個子窗口,系統分配所有權到子窗口的頂層窗口。創建一個被擁有窗口之后,應用不能轉移窗口所有權給另一個窗口。

  對話框和消息框默認都是被擁有窗口。應用程序指定擁有者窗口在調用函數創建對話框或消息框時。

  應用能使用GetWindow函數GW_OWNER標識接收擁有者句柄。

  禁用窗口

  窗口可以別經用,禁用窗口不接收用戶的鍵盤和鼠標輸入,但是它能接收來自其它窗口和來自系統的消息。應用程序通常禁用一個窗口阻止用戶使用窗口。例如,一個應用禁用一個對話框的按鈕阻止用戶選擇它。應用能在任何時侯啟用它;啟用一個窗口恢復正常的輸入。

  默認,創建的窗口時啟用的。應用指定WS_DISABLED樣式,從而禁用一個新窗口。用戶使用EnableWindow函數啟用或禁用一個存在的窗口。系統發送WM_ENABLE消息給窗口當系統的啟用狀態即將被改變時。應用能判斷窗口是否被啟用了使用IsWindowEnable函數。

  當一個子窗口被禁用時,系統傳遞子窗口的鼠標輸入消息給父窗口。父窗口使用消息決定是否啟用子窗口。更多消息看鼠標輸入。

  每次僅有一個窗口能接收鍵盤輸入,那個窗口被稱為有鍵盤焦點。如果應用程序使用EnableWindow函數禁用一個鍵盤焦點的窗口,窗口除了被經用還失去鍵盤焦點,EnableWindow設置鍵盤焦點為NULL,意味着沒有窗口有焦點。如果子窗口或其它后代窗口有鍵盤交代呢,后代窗口丟失焦點當父窗口被禁用時,更多信息,看鍵盤輸入。

  前景和背景窗口

  每個進程能有多個線程執行,每個線程能創建窗口。線程創建窗口,用戶正在使用該窗口,該線程叫前景線程,該窗口被叫為前景窗口。其它所有線程被較為后台線程,被后台線程創建的窗口被較為后台窗口。

  每個線程有一個優先級,決定了線程的接收CPU時間的總數。盡管應用程序能設置它線程的優先級,但是通常前台線程有稍高的優先級比后台線程。因為它有高優先級,前台線程接收的CPU時間更多比后台線程,前景線程有9的基礎優先級,后台有7的基礎優先級。

  用戶通過點擊窗口設置前台窗口,或使用alt+tab或alt+esc組合。應用程序設置前台窗口使用SetForegroundWindow函數。如果新前景窗口時頂層窗口,系統激活它;否則,它激活關聯的頂層窗口。應用程序使用GetForegroundWindow函數接收一個前景窗口的句柄。測試比較你應用窗口的句柄和GetForegroundWindow返回的句柄是否你的應用窗口被激活。

九、    顯示狀態

  在任何一個給定的時間,一個窗口必須時活動的或非活動的;隱藏的或可見的;和最小,最大還是恢復的。這些特性被稱為窗口的顯示狀態,下面的主題討論窗口的顯示狀態。

1)  活動窗口

  在系統中,同一時間只有一個頂層窗口時活動的。用戶激活一個頂層窗口通過點擊它(或它子窗口的一個)或使用alt+esc或alt+tab組合。一個應用程序激活一個頂層窗口是喲哦那個SetActiveWindow函數,其它函數能影響系統激活一個不同的頂層窗口,包括SetWindowPos、DeferWindowPos,SetWindowPlacement,和DestroyWindow。盡管應用程序能激活一個不同的頂層窗口在任何時候。為避免用戶感覺迷惑,它只應該這樣做在相應用戶的動作。應用程序使用GetActiveWindow函數接收一個活動窗口的句柄。

  當活動性改變從一個應用程序的頂層窗口到另一個應用程序的頂層窗口,系統發送WM_ACTIVATEAPP消息給連個應用程序,通知它們改變,當活動性改變到一個不同的頂層窗口在一個應用程序。系統發送兩個WM_ACTIVATE消息。

2)  窗口的可見性

  窗口時可見的或隱藏的,系統顯示可見窗口在屏幕,它不繪制它隱藏一個隱藏窗口。如果窗口是可見的,用戶能提供輸入到窗口和顯示窗口的輸出。如果窗口是隱藏的,實際上它被禁用的。一個隱藏窗口能處理來自系統和其它窗口的消息,但是它不能處理用戶的輸入和顯示輸出。在創建窗口時應用程序設置窗口的可見性,稍后,應用能改變可見性狀態。

  當窗口被設置WS_VISIBLE樣式,窗口時可見的,默認,CreateWidowEx函數創建一個隱藏的窗口,除非應用指定了WS_VISIBLE樣式,通常,應用程序設置WS_VISiBLE樣式在它被創建窗口之后,以保持創建過程的細節對用戶隱藏。例如,應用程序在定制窗口外觀時保持新窗口隱藏。如果WS_VISiBLE樣式被指定在CreateWidnowEx,系統發送WM_SHOWWINDOW消息給窗口在創建窗口之后,並在顯示之前。

  應用程序能使用IsWindowVisible函數判斷窗口是否可見。應用程序能顯示(使可見)或隱藏窗口使用ShowWindow,SetWinDowPos,DeferWindowPos,或SetWindowPlacement函數,這些函數顯示或隱藏窗口用設置或移除WS_VISiBLE樣式為窗口。它們也發送WM_SHOWWINDOW消息給窗口在顯示或隱藏之前。

  當一個所有者窗口被最小化時,系統子的那個隱藏相關的所有被擁有者窗口。類似的,當所有者窗口被恢復時,系統自動的顯示被關聯的被擁有者窗口。兩種情況。系統發送WM_SHOWWINDOW消息給被擁有者窗口在顯示或隱藏之前。有事,應用程序可能需要隱藏被擁有窗口而不最小化或隱藏所有者窗口,在這種情況,應用使用ShowOwnedPopups函數。這個函數設置或移除WS_VISIBLE樣式為被所有者窗口,並發送WM_SHOWWINDOW消息給被所有窗口在隱藏或顯示它們之前。隱藏一個所有者窗口不影響被擁有者窗口的可見性狀態。

  當一個父窗口時可見的,它關聯的子窗口也是可見的,類似,父窗口時隱藏的,子窗口也是隱藏的。最小化父窗口不影響子窗口的可見性狀態,也就是說,子窗口隨父窗口一起最小化,但是W_VISiBLE樣式沒有被改變。

  即使一個窗口有WS_VISIBLE樣式,用戶可能也布恩那個看到窗口在屏幕上,其它窗口可能完全覆蓋它或它被移動到屏幕邊界之外了。此外,一個可見子窗口服從父窗口指定的剪裁規則。如果窗口的夫唱凱不可見,它也不可見,如果父窗口一道屏幕的邊界,子窗口也移動,因為子窗口依據父窗口客戶端區域左上角繪制。例如,一個用戶移動父窗口包括子窗口遠離屏幕的邊界至用戶不能看到子窗口,即使子窗口和父窗口都有WS_VISIBLE樣式。

3)  最小化,最大化和恢復窗口

  最大化窗口時有WS_MAXIMIZE樣式的窗口。默認,系統放大最大化窗口使其填充屏幕,或在子窗口的情況下,填充父窗口客戶端區域,盡管窗口大小能被設置和最大化一樣的大小,有略微不同,系統自動移動窗口標題到屏幕頂部或父窗口客戶端區域的頂部。同時,系統禁用窗口的大小邊框和標題欄的窗口定位功能(這樣用戶不能通過拖動標題欄移動窗口)

  一個最小化窗口時有WS_MINIMIZE樣式,默認系統縮小最小化窗口到它任務欄按鈕的大小,並移動最小化窗口到任務欄。一個恢復窗口是能返回到它先前大小和位置的窗口,也就是說,他在最小化和最大化之前的大小。

  如果一個應用指定了WS_MAXMIZE或WS_MINIMIZE樣式在CreateWindowEx函數,窗口最初時最小或最大化的。在創建窗口之后,應用可以可以使用CloseWindow函數最小化窗口,ArrangeIconicWindows函數排列在桌面的圖標,或它排列在父窗口中一個父窗口最小化的子窗口。OptionIcon函數恢復最小化窗口到它先前的大小和位置。

  ShowWindow函數能最小,最大,恢復一個窗口,它能設置窗口的可見性和活動狀態。SetWindowPlacement函數包括一樣的功能同ShowWindow,但是它能覆蓋窗口默認的最小和最大和恢復位置。

  IsZoomed和IsIconic函數能分別判斷是否一個給定的窗口時最大或最小。GetWindowPlacement函數接收窗口的最小,最大和恢復的位置,也能判斷窗口的顯示狀態。

  當系統接收一個命令最大化和恢復最下化窗口,它發送給窗口一個WM_QUERYOPEN消息。如果窗口過程返回FALSE,系統忽略最大或恢復命令。

  系統自動的設置最大化窗口的大小和位置為系統定義的為最大化窗口。覆蓋這些缺省值,應用程序能調用SetWindowPlacement函數或處理在系統將最大化差窗口時從窗口接收的WM_GetMINMAXINFO消息,WM_GETMINMAXINFO包含一個指向MINMAXINFO結構的指針,包含系統使用的最大化大小和位置的值,替換這些值覆蓋缺省值。

十、    窗口大小和位置

  窗口的大小和位置被表示為一個矩形邊框,在相對於屏幕或父窗口的坐標給出。頂層窗口的坐標相對於屏幕的左上角,子窗口的坐標相對於父窗口的左上角。當應用程序創建窗口時給定大小和位置,但是在任何時候它能改變大小和位置。更多信息看填充圖形。

1)  窗口大小

  窗口大小(寬度和高度)以像素為單位,窗口能有0寬度和高度,如果應用程序設置窗口的寬度和高度為0,系統設置大小為默認最小窗口大小。查看默認最小窗口大小,應用程序使用GetSystemMetrics函數用SM_CXMIN和SM_CYMIN標識。

  應用程序可能需要創建特定客戶區域的窗口。AdjusWindowRect和AdjusWindowRectEx函數根據要求的大小和客戶區域計算窗口所需的大小。應用程序傳遞結果大小值給CreateWindowEx函數。

  應用程序可以調整窗口大小更大,然而,它不應該大小窗口比屏幕大。設置窗口大小之前,應該檢查屏幕的寬度和高度使用GetSystemMetrics用SM_CXSCREEN和SM_CYSCREEN標志。

2)         窗口位置

  窗口位置被定義為左上角的坐標。這個坐標有時被叫窗口坐標,總是相對於屏幕左上角或對應子窗口,父窗口客戶區域左上角。例如,頂層窗口有坐標(10,10)被放置屏幕左上角右10像素,下10像素。一個子窗口有坐標(10,10)被放在父窗口客戶端區域左上角右10像素,下10像素。

  WindowFromPoint函數接收一個窗口句柄,該窗口在屏幕占據指定點。類似的,ChildWindowFromPoint和ChildWindowFromPointEx函數接收一個子窗口的句柄,該子窗口占據在父窗口客戶區域指定點。盡管ChildFromEx能忽略不可見,禁用,和透明的子窗口,但ChildWindowFromPoint不能。

3)  默認的大小和位置

  應用程序在CreateWidnowEx中指定CW_USEDEFAULT允許系統計算初始大小和位置為頂層窗口。如果應用程序設置窗口坐標為CW_USEDEFAULT並且還沒有創建其它頂層窗口,系統設置新窗口的位置相對屏幕左上角;否則,它設置位置相對應用程序最近創建的頂層窗口的位置。如果設置寬度和高度參數為CW_USEDEFAULT,系統計算新窗口的大小。如果應用程序已經創建其它頂層窗口,系統根據應用程序最近創建的頂層窗口的大小計算新窗口的大小。當創建子窗口或彈出窗口時指定CW_USEDEFAULT,系統設置窗口大小為默認最小窗口大小。

4)  跟蹤大小

  系統為WS_THICKFRAME樣式的窗口維護最小和最大的跟蹤大小;帶有這樣式的窗口有大小邊框。最小的跟蹤大小時你能拖拽窗口大小邊框引起最小的窗口大小。類似最大同理。

  當系統創建窗口時,窗口的最小和最大跟蹤大小能被設置為系統缺省定義值。系統能通過WM_GETMINMAXINFO消息查詢並覆蓋它。更多信息看大小和位置消息。

5)  系統命令

  有窗口菜單的應用程序能通過發送系統命令改變窗口大小和位置。當用戶從窗口菜單選擇命令時,系統命令被產生。應用程序能模仿用戶的動作發送WM_SYSCOMMAND消息給窗口。下面的系統命令影響窗口的大小和位置。

  命令 描述

  SC_CLOSE 關閉窗口。這個命令發送WM_CLOSE消息給窗口,窗口會執行任何需要清理和銷毀自身的步驟。

  SC_MAXIMIZE 最大化窗口

  SC_MINIMIZE 最小化窗口

  SC_MOVE 移動窗口

  SC_RESTORE 恢復最小化或最大化窗口到它之前的大小和位置。

  SC_SIZE 啟動一個大小命令,使用鼠標或鍵盤改變窗口的大小。

6)  大小和位置函數

  創建窗口之后,應用程序能設置窗口的大小和位置通過調用幾個不同的函數,包括SetWindowPlacement,MoveWindow,SetWindowPos,和DeferWindowPos。SetWindowPlacement設置窗口的最小位置,最大位置,恢復大小和位置,和顯示狀態。MoveWindow和SetWindowPos函數是相似的,都設置當應用程序窗口的大小和位置。SetWindowPos函數包括一個標志的結合,影響窗口的顯示狀態;MoveWidnow不包括這些標志。使用BeginDeferWindowPos,DeferWindowPos和EndDeferWindowPos函數設置多個窗口,包括大小,位置,Z順序位置,和顯示狀態。

  應用程序可接收窗口邊框矩形的坐標使用GetWindowRect函數,填充aRect結構使用窗口左上角和右下角的坐標。坐標根據屏幕的左上角。對於子窗口,ScreenToClient或MapWindowPoint函數映射子窗口邊界矩形的屏幕坐標為依據父窗口客戶端區域的坐標。

  GetClientRect函數接收窗口客戶端區域坐標,填充RECT結構用客戶端區域左上和右下坐標,但是坐標時相對於客戶區域自身的。意味着可以區域左上坐標一直為(0,0),右下坐標時客戶區域的寬度和高度。

  CascadeWindow函數在桌面層疊窗口,或在指定的父窗口層疊子窗口。TileWindow函數

  放置窗口到桌面,或放置指定的父窗口的子窗口。

7)  大小和位置消息

  系統發送WM_GETMINMAXINFO消息給一個大小和位置即將要改變的窗口。例如,消息被發送當用戶點擊移動或大小從窗口菜單或點擊大小邊框或標題欄。在應用程序調用SetWindowPos移動,改變窗口大小消息也被發送。WM_GETMINMAXINFO包含指針到MINMAXINFO結構,內容為窗口的默認的最大化大小和位置,同樣默認最小和最大跟蹤大小,應用程序能覆蓋默認值處理WM_GETMINMAXINFO並設置恰當的MINMAXINFO的成員。一個窗口接收WM_GETMINMAXINFO必須有WS_THICKFRAME或WS_CAPTION樣式。有WS_THICKFRAME樣式的窗口在窗口創建過程期間接收到這個消息,以及它被移動,大小改變。

  系統發送WM_WINDOWPOSCHANGING消息給一個大小,位置,Z順序的位置窗口。例如,這個消息包含一個指針到WINDOWPOS,指示窗口的新大小,位置,Z順序位置,和顯示狀態。設置WINDOWPOS結構的成員對窗口沒有影響,窗口必須處理WM_SIZE和WM_MOVE消息,必須傳遞WM_WINDOWPOSCHANGED給DefWindowProc函數,否則,系統不發送WM_SIZE和WM_MOVE消息給窗口。

  當窗口被創建或大小改變,系統發送WM_NCCALCSIZE消息給窗口。系統使用這個消息計算窗口客戶區域的大小和客戶區域相對於窗口左上角的位置。窗口通常傳遞這個消息給默認窗口過程;然而,這個消息能來在應用程序中定制創客的非客戶端區域或客戶區域的保留部分當窗口大小改變時。更多消息看,繪制和繪圖

十一、    窗口動畫

  使用AnimateWindow函數在顯示和隱藏窗口時你能產生指定的特效。當窗口以這種方式進行動畫時,系統經會滾動或滑動窗口,取決於你調用AnimateWindow函數指定的標志。

  默認,系統使用滾動動畫。有了這個效果,窗口以滾動打開出現(窗口顯示)或者滾動關閉(隱藏窗口)你能使用dwFlags參數指定是否窗口水平、垂直、或斜着滾動。

  當你指定AW_SLIDE標志,系統使用滑動動畫,有了這個效果,窗口出現以滑動顯示或滑動滑出(隱藏窗口),你能使用dwFlags參數指定窗口是否水平,垂直,或斜着滑動。

  你也能使用AW_CENTER標志,使窗口出現為向內折疊或向外擴展。

十二、    窗口的破壞

  通常應用程序必須銷毀它創建的所有窗口。它使用DestroyWindow函數做這個。當窗口被銷毀,系統隱藏窗口,如果它是可見的,任何移除與窗口相關的任何內部數據。這失效窗口句柄,不再被應用程序使用。

  應用程序銷毀了它創建了它們之后的許多窗口。例如,應用通常銷毀對話框窗口一旦它有足夠的用戶輸入然后繼續其任務。應用最終銷毀主窗口(在終止之前)。

  在銷毀窗口之前,應用應該保持或移除和窗口相關的數據,並且釋放和窗口相關的系統資源。如果應用不釋放資源,系統釋放應用沒有釋放的任何資源。

  銷毀窗口不影響創建窗口的窗口類,新窗口仍能被創建使用該類。任何該類存在的窗口繼續操作。銷毀一個窗口也銷毀窗口的后代窗口。DestroyWindow函數發送WM_DESTROY消息首先給窗口,任何時子窗口和后代窗口。這樣,所有被銷毀的窗口的后代窗口被銷毀。

  當用戶點擊Closehi,帶窗口菜單的窗口接收到WM_CLOSE消息。通過處理這個消息,應用可以在銷毀窗口之前提示用戶確認。如何用戶確認,窗口應該被銷毀。應用可以調用DestroyWidnow函數銷毀窗口。

  如果被銷毀的窗口時活動窗口,焦點狀態和活動被轉移到其它窗口。成為活動的窗口是下一個窗口,由alt+esc組合確認。新的活動窗口決定哪個窗口接收鍵盤焦點。

十三、    使用窗口

  本節的實例描述如何執行以下任務。

  創建一個主窗口

  應用程序創建的第一個窗口通常時主窗口,你能創建主窗口使用CreateWindowEx函數,指定窗口類,窗口名,窗口樣式,大小,位置,菜單句柄,實例句柄,和創建數據。主窗口屬於應用程序定義的窗口類,因此你必須注冊窗口類並提過一個窗口過程為類在創建窗口之前。

  大部分應用程序使用WS_OVERLAPPEDWINDOW樣式創建主窗口,這個樣式給窗口一個標題欄,窗口菜單,大小辦卡,和最小和最大按鈕,CreateWidnowEx返回一個唯一標識窗口的句柄。

  下面的例子創建一個屬於應用程序定義窗口類的主窗口。窗口名稱,主窗口,將出現在標題欄,通過組合WS_VSCROLL和WS_HSCROLL樣式和WS_OVERLAPPEDWINDOW樣式,應用程序創建主窗口帶水平和垂直滾動條,四個CW_USEDEFAULT常量設置窗口的初始大小和位置稱系統定義的默認值,指定NULL代替菜單句柄,窗口將使用窗口類默認菜單。

  HINSTANCE hinst;

  HWND hwndMain;

 

  // Create the main window.

 

  hwndMain = CreateWindowEx(

  0, // no extended styles

  "MainWClass", // class name

  "Main Window", // window name

  WS_OVERLAPPEDWINDOW | // overlapped window

  WS_HSCROLL | // horizontal scroll bar

  WS_VSCROLL, // vertical scroll bar

  CW_USEDEFAULT, // default horizontal position

  CW_USEDEFAULT, // default vertical position

  CW_USEDEFAULT, // default width

  CW_USEDEFAULT, // default height

  (HWND) NULL, // no parent or owner window

  (HMENU) NULL, // class menu used

  hinstance, // instance handle

  NULL); // no window creation data

 

  if (!hwndMain)

  return FALSE;

 

  // Show the window using the flag specified by the program

  // that started the application, and send the application

  // a WM_PAINT message.

 

  ShowWindow(hwndMain, SW_SHOWDEFAULT);

  UpdateWindow(hwndMain);

  注意,在創建主窗口之后,前面的示例調用ShowWindow函數,這樣做因為系統不自動的顯示主窗口在創建之后。傳遞SW_SHOWDEFAULLT標志給ShowWindow,應用程序允許啟動應用程序的程序設置主窗口的初始狀態。UpdateWindow函數向窗口發送它的第一個WM_PAINT消息。

  創建枚舉,和大小子窗口

  你能通過使用子窗口將窗口的客戶區域划分為不同的功能區域。創建子窗口像創建主窗口,你使用CreateWindowEx函數。要創建一個應用程序定義的窗口類窗口,你必須注冊窗口類並提供窗口過程在創建子窗口之前,你必須給子窗口WS_CHILD樣式和指定父窗口為子窗口當你創建時。

  下面的示例將應用程序的主窗口的客戶區域划分為三個功能區域,通過創建三個相同大小的子窗口。每個子窗口和主窗口客戶區域一樣的高度。但是每個是它三分之一的寬。主窗口創建子窗口相應WM_CREATE消息,主窗口在其窗口創建過程時接收該消息。因為每個窗口后WS_BORDER樣式,每一個有細線邊框。另外,因為WS_VISIBLE樣式沒有指定,每個子窗口最初隱藏的。還要注意每個子窗口被分配了一個子窗口標識符。

  主窗口調整大小和定位子窗口在相應WM_SIZE消息時,主窗口接收它在其大小改變時。在相應WM_SIZE主窗口通過GetWindowRect函數檢索其客戶端區域大小,然后傳遞其給EnumChildWindowss函數。其傳遞每個子窗口的句柄,依次給應用程序定義的EnumChildProc回調函數。這個函數調用MoveWindow對每個子窗口調整大小和位置。大小和位置基於主窗口的客戶區域和子窗口的標識符。隨后,調用ShowWindow函數使窗口可見。

  #define ID_FIRSTCHILD 100

  #define ID_SECONDCHILD 101

  #define ID_THIRDCHILD 102

 

  LONG APIENTRY MainWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)

  {

  RECT rcClient;

  int i;

 

  switch(uMsg)

  {

  case WM_CREATE: // creating main window

 

  // Create three invisible child windows.

 

  for (i = 0; i < 3; i++)

  {

  CreateWindowEx(

  0,

  "ChildWClass",

  (LPCTSTR) NULL,

  WS_CHILD | WS_BORDER,

  0,0,0,0,

  hwnd,

  (HMENU) (int) (ID_FIRSTCHILD + i),

  hinst,

  NULL);

  }

 

  return 0;

 

  case WM_SIZE: // main window changed size

 

  // Get the dimensions of the main window's client

  // area, and enumerate the child windows. Pass the

  // dimensions to the child windows during enumeration.

 

  GetClientRect(hwnd, &rcClient);

  EnumChildWindows(hwnd, EnumChildProc,

  (LPARAM) &rcClient);

  return 0;

  // Process other messages.

 

  }

  return DefWindowProc(hwnd, uMsg, wParam, lParam);

  }

 

  BOOL CALLBACK EnumChildProc(HWND hwndChild, LPARAM lParam)

  {

  LPRECT rcParent;

  int i, idChild;

 

  // Retrieve the child-window identifier. Use it to set the

  // position of the child window.

 

  idChild = GetWindowLong(hwndChild, GWL_ID);

 

  if (idChild == ID_FIRSTCHILD)

  i = 0;

  else if (idChild == ID_SECONDCHILD)

  i = 1;

  else

  i = 2;

 

  // Size and position the child window.

 

  rcParent = (LPRECT) lParam;

  MoveWindow(hwndChild,

  (rcParent->right / 3) * i,

  0,

  rcParent->right / 3,

  rcParent->bottom,

  TRUE);

 

  // Make sure the child window is visible.

 

  ShowWindow(hwndChild, SW_SHOW);

 

  return TRUE;

  }

  銷毀一個窗口

  你能使用DestroyWindow函數銷毀窗口,通常,應用在銷毀窗口之前發送WM_CLOSE消息,給窗口機會提示用戶確認在銷毀窗口之前。包含窗口菜單的窗口自動接收到WM_CLOSE消息,在用戶從窗口菜單點擊關閉時。如果用戶確認窗口應該被銷毀。應用調用DestroyWindow。系統發送WM_DESTROY消息給窗口在從屏幕移除它時。相應WM_DESTROY窗口保存它的數據和釋放任何資源和它關聯的。主窗口通過調用PostQuitMessage函數退出應用程序來結束對WM_DESTROY處理。

  下面的示例顯示了如何在銷毀窗口之前提示用戶確認。在對WM_CLOSE的相應中,例子顯示包含Yes,Cancel按鈕的對話框。用戶點擊YesDestroyWindow被調用,否則,窗口不被銷毀,因為被銷毀的是主窗口,在這個示例中調用PostQuitMessage響應WM_DESTROY。

  case WM_CLOSE:

 

  // Create the message box. If the user clicks

  // the Yes button, destroy the main window.

 

  if (MessageBox(hwnd, szConfirm, szAppName,

  MB_YESNOCANCEL) == IDYES)

  DestroyWindow(hwndMain);

  else

  return 0;

 

  case WM_DESTROY:

 

  // Post the WM_QUIT message to

  // quit the application terminate.

 

  PostQuitMessage(0);

  return 0;

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM