Windows Programming/窗口創建

維基教科書,自由的教學讀本

窗口創建與窗口分類[編輯]

使用Windows API函數CreateWindowEx,可以指定創建的窗口的類型:

  • Non Child Window:
    • Overlapped Window:頂層窗口,作為應用程式的主窗口。有標題條、邊界與客戶區,可以有菜單、最大最小化按鈕、滾動條。
    • Pop-up Window:用於對話框、MessageBox,以及其他出現在應用程式主窗口之外的臨時窗口。標題條可選。
  • Child Window:出現在父窗口的客戶區中,超出的部分不可見。典型用於把父窗口的客戶區分割成一些子區域。父窗口可以是Overlapped、Pop-up、其他Child窗口。子窗口的唯一必要特性是有客戶區;不能有菜單;其他特性可選。定位子窗口時總是用父窗口客戶區左上角坐標系。Destroyed、Hidden、Moved、Shown等窗口操作與父窗口一致。父窗口如果指定了WS_CLIPCHILDREN風格,則父窗口不能在子窗口上繪製。兄弟子窗口可以在彼此重疊的客戶區上繪製,除非指定了WS_CLIPSIBLINGS風格。
  • Layered Window:
  • Message-Only Window:該窗口visible屬性為false
  • Owner/Owned Window
    • Owner Window
    • Owned Window
GetParent函數,對於子窗口返回其父窗口;對於有WS_POPUP風格的非Child窗口,返回其owner;對於沒有WS_POPUP風格的非Child窗口來說,GetParent恆定返回0。
GetWindow(hwnd, GW_OWNER)能夠正常取得其owner
FindWindowEx可以指定父窗口、Z order上的前一個兄弟窗口,查找符合類名、窗口名的窗體。父窗口參數為NULL,則查找desktop的「子窗口」,即沒有WS_CHILD風格的窗口。
GetTopWindow返回父窗口下的最頂層子窗口。
GetNextWindow返回Z order的前一個或下一個窗口。

Layered Window[編輯]

如果窗口使用語句

 ModifyStyleEx(0, WS_EX_LAYERED);

成為了Layered Window,就可以指定它的阿爾法值(半透明程度):

SetLayeredWindowAttributes(0, (255 * 50) / 100, LWA_ALPHA);

或者指定色鍵,系統將把具有該顏色的所有像素當作透明:

SetLayeredWindowAttributes(0x00bbggrr, 0, LWA_COLORKEY);

如果希望把所有鼠標事件傳給桌面或者在當前窗口之下的其它線程的窗口,可以把當前窗口設置為:

 ModifyStyleEx(0, WS_EX_TRANSPARENT);

UpdateLayeredWindow函數:

  • 如果是WS_EX_APPWINDOW,此時在updatelayerwindow,並不會由系統攔截WM_PAINT消息,就像平時處理窗口一樣,系統像平時使用invalidateRect()函數,可以局部重繪無效區域。
  • 如果是WS_EX_LAYERED,就必須手動在各處添加SendMessage(hwnd,wm_paint),這樣才會進入WM_PAINT的處理

窗口的子類化[編輯]

窗口的subclass是指修改窗口過程的操作,而不是面向對象中的派生子類。

移動窗口[編輯]

正常情況下當使用者在窗口的標題欄按下鼠標左鍵時,系統發出WM_NCHITTESt來判斷鼠標是否在HTCAPTION區域,然後向該窗口過程函數發送WM_NCLBUTTONDOWN消息。DefWindowProc函數指示窗口隨同鼠標光標一起移動。鬆開鼠標按鈕後,發出WM_NCLBUTTONUP消息。最後發出WM_MOVE消息。

在沒有窗口的標題欄的情況下,移動窗口的幾種辦法:

  • SendMessage(hWnd,WM_NCLBUTTONDOWN,HTCAPTION,0);
  • SendMessage(hWnd,WM_SYSCOMMAND,SC_DRAGMOVE,0); // #define SC_DRAGMOVE 0xF012

作業系統有兩種移動窗口的方式,一種是有虛線框(即影子窗口,ghost window),另一種沒有虛線框,即實體窗口本身。作業系統全局範圍內可通過如下函數來改變移動窗口的方式:

SystemParametersInfo(SPI_SETDRAGFULLWINDOWS,true,NULL,0);

下一章[編輯]