1. 程式人生 > >windows程序設計.窗口.

windows程序設計.窗口.

obj char 情況 背景 說明 重新 關閉窗口 新的 fde

第一個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並終止程序。

windows程序設計.窗口.