(Windows程式設計)視窗的誕生
阿新 • • 發佈:2018-12-25
相對於DOS程式的main函式,Windows應用程式也有一個入口點函式--WinMain。當作業系統啟動一個程式時,它將呼叫程式的WinMain函式開始執行程式碼;當WinMain函式返回時,應用程式就結束了。
視窗的誕生
- 設計視窗類:Windows是基於視窗的作業系統,下圖顯示了一個普通的Windows視窗:
作業系統通過視窗資料結構來管理視窗,該資料結構包含了一個視窗的所有資訊,視窗資料結構定義如下:
引數說明: style:指定類風格,這些風格可以通過按位或操作組合起來。(CS_HREDRAW、CS_VREDRAW、CS_BYTEALIGNCLIENT......) lpfnWndProc:指向一個視窗函式。函式原型為: LRESULT CALLBACK WindowProc( HWNDhwnd, UINTuMsg, WPARAM, LPARAM);//視窗函式由系統呼叫,響應不同的訊息,通常為一個 switch語句塊。 hbrBackground:背景畫刷,是HBRUSH型別。hbrBackground欄位必須是用於繪製背景的物理刷子的控制代碼,或者是一個顏色的值。typedef struct _WNDCLASS { UINT style; // 視窗型別 WNDPROC lpfnWndProc; <span style="white-space:pre"> </span>//視窗處理函式 int cbClsExtra; //視窗擴充套件 int cbWndExtra; //視窗例項擴充套件 HINSTANCE hInstance; <span style="white-space:pre"> </span>//例項控制代碼 HICON hIcon; <span style="white-space:pre"> </span>//視窗的最小化圖示 HCURSOR hCursor; <span style="white-space:pre"> </span>//視窗滑鼠游標 HBRUSH hbrBackground; <span style="white-space:pre"> </span>//視窗背景色 LPCTSTR lpszMenuName; <span style="white-space:pre"> </span>//視窗選單 LPCTSTR lpszClassName;<span style="white-space:pre"> </span>// 視窗類名 } WNDCLASS
- 註冊視窗類:定義了一個視窗類之後,並不能直接使用它通過CreateWindow函式來建立窗體,因為作業系統並不知道該視窗類的存在。需要通過RegisterClass函式註冊一個視窗類。該函式原型如下:
ATOM RegisterClass(CONST WNDCLASS*lpWndClass); //引數lpWndClass即為步驟一設計的視窗類的指標
- 建立視窗:呼叫CreateWindow函式建立視窗。CreateWindow函式語法如下:
<span style="white-space:pre"> </span>HWND CreateWindow( LPCTSTR lpClassName, LPCTSTR lpWindowName, DWORD dwStyle, int x, int y, int nWidth, int nHeight, HWND hWndParent, HMENU hMenu, HINSTANCE hInstance, LPVOID lpParam <span style="white-space:pre"> </span>);
引數說明: lpClassName:跟設計視窗類步驟的引數lpszClassName相同,指定了視窗的類名。 dwStyle:指定建立視窗的風格。該引數可以是下列視窗風格的組合再加上說明部分的控制風格(WS_DISABLED、WS_ICONIC、WS_MAXIMIZE......)。這裡的 dwStyle表示每個具體視窗的風格,而視窗類風格指定的是該類視窗所具有的風格。
- 顯示視窗:視窗在成功建立之後,還需要呼叫ShowWindow函式才能顯示出來
//顯示視窗 ShowWindow(hWnd, SW_SHOW); UpdateWindow(hWnd);
- 進入訊息迴圈:不斷從訊息佇列取出訊息,存在引數lpMsg引數中。如果獲得訊息為WM_QUIT,返回值為0.如果函式執行過程中出現錯誤,返回值為-1,其他情況返回值為非零。
<span style="white-space:pre"> </span>//進入訊息迴圈
MSG msg;
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
最後附上一個建立簡單視窗的Win32程式#include "windows.h"
//視窗函式
LRESULT CALLBACK WNDFUN(HWND hWnd, UINT msg,
WPARAM wparam, LPARAM lparam)
{
switch (msg)
{
case WM_PAINT:
{
HDC hdc = GetDC(hWnd);
SetBkMode(hdc, TRANSPARENT);
TextOut(hdc, 20, 20, (LPCTSTR)"Hello,world!" , sizeof("Hello,world!")-1);
DeleteDC(hdc);
break;
}
case WM_CLOSE:
{
DestroyWindow(hWnd);
break;
}
case WM_DESTROY:
{
PostQuitMessage(0);
break;
}
default:
return DefWindowProc(hWnd, msg, wparam, lparam);
}
return 0;
}
//程式的入口點
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
//設計視窗類
WNDCLASS wndcls;
wndcls.style = CS_DBLCLKS | CS_VREDRAW | CS_HREDRAW;
wndcls.lpszMenuName = NULL;
wndcls.lpszClassName = (LPCTSTR)"CustomWnd";
wndcls.lpfnWndProc = WNDFUN;
wndcls.hInstance = GetModuleHandle(NULL);
wndcls.hIcon = NULL;
wndcls.hCursor = LoadCursor(hInstance,IDC_ARROW);
wndcls.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wndcls.cbClsExtra = 0;
wndcls.cbWndExtra = 0;
//註冊視窗類
RegisterClass(&wndcls);
//建立視窗
HWND hWnd;
hWnd = CreateWindow((LPCTSTR)"CustomWnd", (LPCTSTR)"Win32App", WS_CAPTION | WS_OVERLAPPEDWINDOW | WS_SYSMENU,
50, 50, 500, 500, NULL, NULL, wndcls.hInstance, NULL);
//顯示視窗
ShowWindow(hWnd, SW_SHOW);
UpdateWindow(hWnd);
//進入訊息迴圈
MSG msg;
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}