windows第一个窗口程序转自windows程序设计王艳平老师编著
轉
目錄:??
1.窗口程序?
2.分析?
??????注冊窗口類別?
??????建立窗口?
??????顯示窗口?
??????消息循環?
??????窗口消息處理程序???
3.注意事項???
窗口程序:
運行程序,將會出現一個窗口并發出響聲,窗口中央有一行文字。如下圖:?
分析:
1.注冊窗口類別
窗口依照某一窗口類別建立,窗口類別用以標識處理窗口消息的窗口消息處理程序。
在為程序建立窗口之前,必須首先呼叫RegisterClass注冊一個窗口類別。該函數只需要一個參數,即一個指向型態為WNDCLASS的結構指針。
WNDCLASS是一個窗口類結構:?
{?
???? UINT??????? style ;?????????????????????????????????? //窗口類別樣式?
???? WNDPROC???? lpfnWndProc ;??????????????? //設定消息處理程序?
???? int???????? cbClsExtra ;??????????????????????????? //用于在窗口類別結構和Windows內部保存的窗口結構中預留一些額外空間?
???? int???????? cbWndExtra ;???????????????????????? //同上?
???? HINSTANCE?? hInstance ;??????????????????? //程序的執行實體句柄?
???? HICON?????? hIcon ;????????????????????????????? //為所有依據這個窗口類別建立的窗口設置一個圖標?
???? HCURSOR???? hCursor ;?????????????????????? //設置鼠標光標?
???? HBRUSH????? hbrBackground ;???????????? //指定依據這個類別建立的窗口背景顏色?
???? LPCTSTR???? lpszMenuName ;???????????? //指定窗口類別菜單?
???? LPCTSTR???? lpszClassName ;???????????? //必須給出一個類別名稱?
} WNDCLASS, * PWNDCLASS ;
在WinMain中為WNDCLASS定義一個結構,通常像這樣:?
然后,你就可以初始化該結構的10個字段,并呼叫RegisterClass。
在初始化該結構的10個字段后,HELLOWIN呼叫RegisterClass來注冊這個窗口類別。該函數只有一個參數,即指向WNDCLASS結構的指針。
2.建立窗口
窗口類別定義了窗口的一般特征,因此可以使用同一窗口類別建立許多不同的窗口。呼叫CreateWindow建立窗口時,可以指定有關窗口的更詳細的信息。
下面是HELLOWIN.C中的CreateWindows呼叫,每一個字段都做了完整的說明:?
???????????????????? TEXT ("The Hello Program"), // window caption?
???????????????????? WS_OVERLAPPEDWINDOW,??????? // window style?
???????????????????? CW_USEDEFAULT,????????????? // initial x position?
???????????????????? CW_USEDEFAULT,????????????? // initial y position?
???????????????????? CW_USEDEFAULT,????????????? // initial x size?
???????????????????? CW_USEDEFAULT,????????????? // initial y size?
???????????????????? NULL,?????????????????????? // parent window handle?
???????????????????? NULL,?????????????????????? // window menu handle?
???????????????????? hInstance,????????????????? // program instance handle?
???????????????????? NULL) ;???????????????????? // creation parameters
此程序建立的窗口是一個普通的重迭式窗口。它含有一個標題列,標題列左邊有一個系統菜單按鈕,標題列右邊有縮小、放大和關閉圖示,四周還有一個表示窗口大小的邊框。這是標準樣式的窗口,名為WS_OVERLAPPEDWINDOW,出現在CreateWindow的「窗口樣式」參數中。此樣式是幾種位旗標的組合:?
???????????????????????????? WS_CAPTION??????? | /?
???????????????????????????? WS_SYSMENU??????? | /?
???????????????????????????? WS_THICKFRAME???? | /?
???????????????????????????? WS_MINIMIZEBOX??? | /?
???????????????????????????? WS_MAXIMIZEBOX)
「窗口標題」是顯示在標題列中的文字。
注釋著「initial x position」和「initial y position」的參數指定了窗口左上角相對于屏幕左上角的初始位置。由于這些參數使用CW_USEDEFAULT標識符,指示Windows使用重迭窗口的內定位置。(CW_USEDEFAULT定義為0x80000000。)內定情況下,Windows依次對新建立的窗口定位,使各窗口左上角的垂直和水平距離在屏幕上按一定的大小遞增。與此類似,注釋著「initial x size」和「initial y size」的參數分別指定窗口的寬度和高度。同樣使用了CW_USEDEFAULT標識符,表明希望Windows使用內定尺寸。
在建立一個「最上層」窗口,如應用程序窗口時,注釋為「父窗口句柄」的參數設定為NULL。通常,如果窗口之間存在有父子關系,則子窗口總是出現在父窗口的上面。應用程序窗口出現在桌面窗口的上面,但不必為呼叫CreateWindow而找出桌面窗口的句柄。
因為窗口沒有菜單,所以「窗口菜單句柄」也設定為NULL。「程序執行實體句柄」設定為執行實體句柄,它是作為WinMain的參數傳遞給這個程序的。最后,「建立參數」指標設定為NULL,可以用這個參數存取稍后程序中可能引用到的數據。
CreateWindow傳回被建立的窗口的句柄,該句柄存放在變量hwnd中,后者被定義為HWND型態(「窗口句柄型態」)。Windows中的每個窗口都有一個句柄,程序用句柄來使用窗口。許多Windows函數需要使用hwnd作為參數,這樣,Windows才能知道函數是針對哪個窗口的。如果一個程序建立了許多窗口,則每個窗口均有一個句柄。窗口句柄是Windows程序所處理最重要的句柄之一。
3.顯示窗口
在CreateWindow呼叫傳回之后,Windows內部已經建立了這個窗口。這就是說,Windows已經配置了一塊內存,用來保存在CreateWindow呼叫中指定窗口的全部信息跟一些其它信息,而Windows稍后就是依據窗口句柄找到這些信息的。
然而,光是這樣子,窗口并不會出現在視訊顯示器上。您還需要兩個函數呼叫,一個是:?
第一個參數是剛剛用CreateWindow建立的窗口句柄。第二個參數是作為參數傳給WinMain的iCmdShow。它確定最初如何在屏幕上顯示窗口,是一般大小、最小化還是最大化。在開始菜單中安裝程序時,使用者可能做出最佳選擇。如果窗口按一般大小顯示,那么WinMain接收到后傳遞給ShowWindow的就是SW_SHOWNORMAL﹔如果窗口是最大化顯示的,則為SW_SHOWMAXIMIZED。而如果窗口只顯示在工作列上,則是SW_SHOWMINNOACTIVE。
ShowWindow函數在顯示器上顯示窗口。如果ShowWindow的第二個參數是SW_SHOWNORMAL,則窗口的顯示區域就會被窗口類別中定義的背景畫刷所覆蓋。函數呼叫:?
這個函數會重畫顯示區域。它經由發送給窗口消息處理程序(即HELLOWIN.C中的WndProc函數)一個WM_PAINT消息做到這一點。
4.消息循環
呼叫UpdateWindow之后,窗口就出現在視訊顯示器上。程序現在必須準備讀入使用者用鍵盤和鼠標輸入的數據。Windows為當前執行的每個Windows程序維護一個「消息隊列」。在發生輸入事件之后,Windows將事件轉換為一個「消息」并將消息放入程序的消息隊列中。
程序通過執行一塊稱之為「消息循環」的程序代碼從消息隊列中取出消息:?while (GetMessage (&msg, NULL, 0, 0))??
{?
???? TranslateMessage (&msg) ;???????
???? DispatchMessage (&msg) ;?
} msg變量是型態為MSG的結構,型態MSG在WINUSER.H中定義如下:?
typedef struct tagMSG?
{?
???? HWND?? hwnd ;??????????????? //接收消息的窗口句柄?
???? UINT?? message ;???????????? //消息標識符。這是一個數值,用以標識消息。?
???? WPARAM wParam ;????????? //一個32位的「message parameter(消息參數)」?
???? LPARAM lParam ;???????????? //一個32位的消息參數,其值與消息有關?
???? DWORD? time ;??????????????? //消息放入消息隊列中的時間?
???? POINT? pt ;????????????????????? //消息放入消息隊列時的鼠標坐標?
}?
MSG, * PMSG ; POINT數據型態也是一個結構,它在WINDEF.H中定義如下:?
typedef struct tagPOINT?
{?
???? LONG? x ;?
???? LONG? y ;?
}?
POINT, * PPOINT;
消息循環以GetMessage呼叫開始,它從消息隊列中取出一個消息。第二、第三和第四個參數設定為NULL或者0,表示程序接收它自己建立的所有窗口的所有消息。?
只要從消息隊列中取出消息的message字段不為WM_QUIT(其值為0x0012),GetMessage就傳回一個非零值。WM_QUIT消息將導致GetMessage傳回0。
TranslateMessage將msg結構傳給Windows,進行一些鍵盤轉換。?
DispatchMessage又將msg結構回傳給Windows。然后,Windows將該消息發送給適當的窗口消息處理程序,讓它進行處理。這也就是說,Windows將呼叫窗口消息處理程序。
5.窗口消息處理程序
以上我們所討論的都是必要的負擔:注冊窗口類別,建立窗口,然后在屏幕上顯示窗口,程序進入消息循環,然后不斷從消息隊列中取出消息來處理。實際的動作發生在窗口消息處理程序中。窗口消息處理程序確定了在窗口的顯示區域中顯示些什么以及窗口怎樣響應使用者輸入。
在此程序中,窗口消息處理程序是命名為WndProc的函數。窗口消息處理程序可任意命名(只要求不和其它名字發生沖突)。一個Windows程序可以包含多個窗口消息處理程序。一個窗口消息處理程序總是與呼叫RegisterClass注冊的特定窗口類別相關聯。CreateWindow函數根據特定窗口類別建立一個窗口。但依據一個窗口類別,可以建立多個窗口。
//窗口消息處理程序總是定義為如下形式 LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { HDC hdc ; PAINTSTRUCT ps ; RECT rect ; ? //在此程序中,WndProc只選擇處理三種消息:WM_CREATE、WM_PAINT和WM_DESTROY。窗口消息處理程序的結構如下: switch (message) { case WM_CREATE: //播放聲音文件 PlaySound (TEXT ("hellowin.wav"), NULL, SND_FILENAME | SND_ASYNC) ; return 0 ; ? case WM_PAINT: //對WM_PAINT的處理幾乎總是從一個BeginPaint呼叫開始,而以一個EndPaint呼叫結束,BeginPaint使顯示區域變為有效。如果不呼叫BeginPaint和EndPaint(或者ValidateRect),則Windows不會使該區域變為有效。相反,Windows將發送另一個WM_PAINT消息,且一直發送下去。 hdc = BeginPaint (hwnd, &ps) ; //GetClientRect函數檢索一個窗口的客戶區坐標rect GetClientRect (hwnd, &rect) ; //DrawText可以輸出文字。第一個參數是從BeginPaint傳回的設備內容句柄;第二個參數是要輸出的文字;第三個參數是-1,指示字符串是以字節終結的;DrawText最后一個參數是一系列位旗標,旗標指示了文字必須顯示在一行上,水平方向和垂直方向都位于第四個參數指定的矩形中央。 DrawText (hdc, TEXT ("Hello, Windows Vista!"), -1, &rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER) ; EndPaint (hwnd, &ps) ; return 0 ; ? case WM_DESTROY: //通過呼叫PostQuitMessage以標準方式響應WM_DESTROY消息 PostQuitMessage (0) ; return 0 ; } //呼叫DefWindowProc來為窗口消息處理程序不予處理的所有消息提供內定處理,這是很重要的。不然一般動作,如終止程序,將不會正常執行。 return DefWindowProc(hwnd, message, wParam, lParam); }程序通常不直接呼叫窗口消息處理程序,窗口消息處理程序通常由Windows本身呼叫。通過呼叫SendMessage函數,程序能夠直接呼叫它自己的窗口消息處理程序。
3.注意事項
該程序使用了多媒體功能呼叫需要添加Windows多媒體鏈接庫文件WINMM.LIB??梢栽陧椖俊?gt;屬性—>配置屬性—>鏈接器—>輸入—>附加依賴項里輸入WINMM.LIB即可。總結
以上是生活随笔為你收集整理的windows第一个窗口程序转自windows程序设计王艳平老师编著的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 用 leangoo进行自我账目管理
- 下一篇: 在线cad版本转换_商业住宅小区弱电系统