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並終止程序。
windows程序設計.窗口.