windows程序設計.窗口.


第一個windows窗口

 1 #include <windows.h>
 2 /*  Displays "Hello, World!" in client area   */
 3 
 4 LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);//窗口過程函數
 5 
 6 int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
 7     PSTR szCmdLine, int iCmdShow)
 8 {
 9     static TCHAR szAppName[] = TEXT("HelloWin");//窗口類名稱
10     char string[] = "Hello World!";
11     HWND   hwnd;//窗口句柄
12     MSG    msg;//消息結構
13     WNDCLASS wndclass;//定義窗口類結構體變量
14     /*下面代碼填充窗口類信息*/
15     wndclass.style = CS_HREDRAW | CS_VREDRAW;//窗口樣式
16     wndclass.lpfnWndProc = WndProc;//過程函數
17     wndclass.cbClsExtra = 0;//擴展字段
18     wndclass.cbWndExtra = 0;//擴展字段
19     wndclass.hInstance = hInstance;//當前實例句柄
20     wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);//設置程序圖標
21     wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);//設置鼠標
22     wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);//用白色填充背景
23     wndclass.lpszMenuName = NULL;//菜單
24     wndclass.lpszClassName = szAppName;//類名
25                                        /*注冊窗口類*/
26     if (!RegisterClass(&wndclass))
27     {
28         MessageBox(NULL, TEXT("This program requires Windows NT!"),
29             szAppName, MB_ICONERROR);
30         return 0;
31     }
32     //創建窗口create window
33     hwnd = CreateWindow(szAppName,      // window class name類名
34         TEXT("The Hello Program"),   // window caption標題
35         WS_OVERLAPPEDWINDOW,  // window style樣式
36         CW_USEDEFAULT,// initial x position 橫坐標原點
37         CW_USEDEFAULT,// initial y position 縱坐標原點
38         CW_USEDEFAULT,// initial x size 
39         CW_USEDEFAULT,// initial y size
40         NULL,                 // parent window handle父窗口句柄
41         NULL,            // window menu handle菜單句柄
42         hInstance,   // program instance handle當前實例句柄
43         NULL);      // creation parameters 傳遞給窗口 WM_CREATE消息的值的指針 一般為NULL
44     ShowWindow(hwnd, iCmdShow);
45     UpdateWindow(hwnd);
46     //消息循環,一直停在這里,退出消息循環就表示程序結束了
47     while (GetMessage(&msg, NULL, 0, 0))
48     {
49         TranslateMessage(&msg);//翻譯
50         DispatchMessage(&msg);//分發
51     }
52     return msg.wParam;
53 }
54 /*  消息處理函數  */
55 LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
56 {
57     HDC         hdc;
58     PAINTSTRUCT ps;
59     RECT        rect;
60     switch (message)
61     {
62     case   WM_PAINT:
63         hdc = BeginPaint(hwnd, &ps);
64         GetClientRect(hwnd, &rect);
65         DrawText(hdc, TEXT("Hello World!"), -1, &rect,
66             DT_SINGLELINE | DT_CENTER | DT_VCENTER);
67         EndPaint(hwnd, &ps);
68         return 0;
69     //發送結束請求,里面的參數為退出碼
70     case   WM_DESTROY:
71         PostQuitMessage(0);
72         return 0;
73     }
74     //調用默認的過程函數
75     return DefWindowProc(hwnd, message, wParam, lParam);
76 }

 首先是通過WNDCLASS這個結構體來告訴系統我們要創建一個窗口。

 1 ypedef struct tagWNDCLASSA {
 2     UINT        style;
 3     WNDPROC     lpfnWndProc;
 4     int         cbClsExtra;
 5     int         cbWndExtra;
 6     HINSTANCE   hInstance;
 7     HICON       hIcon;
 8     HCURSOR     hCursor;
 9     HBRUSH      hbrBackground;
10     LPCSTR      lpszMenuName;
11     LPCSTR      lpszClassName;
12 } WNDCLASSA, *PWNDCLASSA, NEAR *NPWNDCLASSA, FAR *LPWNDCLASSA;

設置結構內的不同的字段,調用RegisterClass函數來告訴系統,要注冊一個這樣的窗口類型。

接下來就是通過調用函數CreateWindow創建一個剛才注冊的窗口類型。

 1 #define CreateWindowA(lpClassName, lpWindowName, dwStyle, x, y,\
 2 nWidth, nHeight, hWndParent, hMenu, hInstance, lpParam)\
 3 CreateWindowExA(0L, lpClassName, lpWindowName, dwStyle, x, y,\
 4 nWidth, nHeight, hWndParent, hMenu, hInstance, lpParam)
 5 #define CreateWindowW(lpClassName, lpWindowName, dwStyle, x, y,\
 6 nWidth, nHeight, hWndParent, hMenu, hInstance, lpParam)\
 7 CreateWindowExW(0L, lpClassName, lpWindowName, dwStyle, x, y,\
 8 nWidth, nHeight, hWndParent, hMenu, hInstance, lpParam)
 9 #ifdef UNICODE
10 #define CreateWindow  CreateWindowW
11 #else
12 #define CreateWindow  CreateWindowA
13 #endif // !UNICODE

創建好的窗口還沒有顯示,這就要調用函數ShowWindow來顯示,以及UpdateWindow來更新。

ShowWindow(
    _In_ HWND hWnd,
    _In_ int nCmdShow);

UpdateWindow(
    _In_ HWND hWnd);

消息循環。GetMessage函數從消息隊列中取得消息。TranslateMessage函數 轉移某些鍵盤消息。DispatchMessage函數將消息發送給窗口消息處理程序。

再來看WndProc這個函數內部。BeginPaint 開始繪制窗口。GetClientRect 取得窗口顯示區域的大小。DrawText 顯示字符串。EndPaint 結束繪制窗口。PostQuitMessage 在消息隊列中插入一個「退出程序」消息。DefWindowProc 執行內定的消息處理。

程序通常不直接呼叫窗口消息處理程序,窗口消息處理程序通常由Windows本身呼叫。通過呼叫SendMessage函數,程序能夠直接呼叫它自己的窗口消息處理程序。

處理消息。

WndProc處理的第一個消息為WM_PAINT。當窗口顯示區域的一部分顯示內容或者全部變為「無效」,以致於必須「更新畫面」時,將由這個消息通知程序。wndclass結構的style字段設定為標志CS_HREDRAW和CS_VREDRAW,這樣的格式設定指示Windows,改變窗口的大小、窗口最小化以及移動窗口后,顯示區域的顯示內容重新變得無效。

GetClientRect (hwnd, &rect) ;

第一個參數是程序窗口的句柄。第二個參數是一個指標,指向一個RECT型態的rectangle結構。該結構有四個LONG字段,分別為left、top、right和bottom。GetClientRect將這四個字段設定為窗口顯示區域的尺寸。left和top字段通常設定為0,right和bottom字段設定為顯示區域的寬度和高度(像素點數)。

DrawText(hdc, TEXT("Hello World!"), -1, &rect,
            DT_SINGLELINE | DT_CENTER | DT_VCENTER);

DrawText可以輸出文字(正如其名字所表明的一樣)。由於該函數要輸出文字,第一個參數是從BeginPaint傳回的設備內容句柄,第二個參數是要輸出的文字,第三個參數是 -1,指示字符串是以字節0終結的。

DrawText最后一個參數是一系列位旗標,它們均在WINUSER.H中定義(雖然由於其顯示輸出的效果,使得DrawText像一個GDI函數呼叫,但它確實因為相當高級的畫圖功能而成為User模塊的一部分。此函數在/Platform SDK/Graphics and Multimedia Services/GDI/Fonts and Text中說明)。旗標指示了文字必須顯示在一行上,水平方向和垂直方向都位於第四個參數指定的矩形中央。因此,這個函數呼叫將讓字符串「Hello World!」顯示在顯示區域的中央。

一旦顯示區域變得無效(正如在改變大小時所發生的情況一樣),WndProc就接收到一個新的WM_PAINT消息。WndProc通過呼叫GetClientRect取得變化后的窗口大小,並在新窗口的中央顯示文字。

case   WM_DESTROY:
        PostQuitMessage(0);

WM_DESTROY消息指示,Windows正在根據使用者的指示關閉窗口。單擊Close按鈕或者在程序的系統菜單上選擇 Close時發生的。

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

結構的wParam字段是傳遞給PostQuitMessage函數的值(通常是0)。然后return敘述將退出WinMain並終止程序。


免責聲明!

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



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