Win32應用程序創建步驟:
編寫WinMain函數
設計窗口類(WNDCLASS)
註冊窗口類
創建窗口
顯示並更新窗口
編寫消息循環
編寫窗口過程函數
1,編寫WinMain函數
WinMain函數式Windows應用程序的入口點。函數原型如下:
int WINAPI WinMain( HINSTANCE hInstance, //handle to current instance HINSTANCE hPrevInstance, //handle to previous instance LPSTR lpCmdLine, //command line int nCmdShow, //show state );
第二個參數總爲NULL。
第四個參數是窗口的顯示方式,由一些宏定義。
如果函數運行成功,則它在接收到WM_QUIT消息時退出,並返回值,該值包含在消息的wParam變量中。如果還沒有進入消息循環,函數就終止,則返回0。
我們的WinMain函數應該初始化我們的應用程序,顯示主窗口,然後進入retrieval-and-dispatch循環。當收到WM_QUIT消息時,退出循環。如果是這樣,函數返回值爲包含在消息的wParam變量中的值。如果WM_QUIT消息時由PostQuitMessage發出的,則返回值爲PostQuitMessage函數的退出值。
2,設計窗口類(WNDCLASS)
WNDCLASS結構包含窗口的一些屬性。其結構如下:
typedef struct _WNDCLASS{ UINT style; WNDPROC lpfnWndProc; int cbClsExtra; int cbWndExtra; HINSTANCE hInstance; HICON hIcon; HCURSOR hCursor; HBRUSH hbrBackground; LPCTSTR lpszMenuName; LPCTSTR lpszClassName; } WNDCLADD, *PWNDCLASS;
style指定類風格。
lpfnWndProc指向窗口函數。
cbClsExtra指定一些額外的空間來容納後續的一些窗口結構。
cbWndExtra指定一些額外的空間來容納後續的一些窗口實例。
hInstance該窗口的窗口函數的實例句柄。
hIcon圖標句柄。
hCursor光標句柄。
hbrBackground背景畫刷句柄。
lpszMenuName以NULL結尾的字符串指定結構菜單的名字。
3,註冊窗口
函數原型如下:
ATOM RegisterClass( CONST WNDCLASS *lpWndClass //class data )
lpWndClass之中呢指向一個WNDCLASS結構。在將該WNDCLASS結構傳給註冊函數之前,你必須已經對lpWndClass指向的結構進行了初始化。
4,創建窗口
函數原型如下:or child
HWND CreateWindow( LPCTSTR lpClassName, //registered class name LPCTSTR lpWindowName, //window name DWORD dwStyle, //window style int x, //horizontal postion of window int y, //vertical postion of window int nWidth, //window width int nHeight, //window height HWND hWndParent, //handle to parent or owner window HMENU hMenu, //menu handle or child identifier HINSTANCE hInstance, //handle to application instance LPVOID lpParam //window-creation data )
每個變量的含義可參考MSDN。
5,顯示並更新窗口
顯示窗口函數原型如下:
BOOL ShowWindow( HWND hWnd, //handle to window int nCmdShow //show state );
如果窗口可見,返回非0,不可見,返回0。
更新窗口函數原型如下:
BOOL UpdateWindow( HWND hWnd //handle to window );
成功返回非0值,失敗返回0。
6,編寫消息循環
在創建窗口、顯示窗口、更新窗口後,我們需要編寫一個消息循環,不斷的從消息隊列中取出消息,並進行響應。從隊列中獲取消息,我們調用GetMessage()函數,函數原型如下
BOOL GetMessage( LPMSG lpMsg, //message information HWND hWnd, //handle to window UINT wMsgFilterMin, //first message UINT wMsgFilterMax //last message );
函數取回非WM_QUIT消息,返回非0。
函數取回WM_QUIT消息,返回0。
如果發生錯誤,返回-1。
通常我們編寫的消息循環如下:&msg
MSG msg; while(GetMessage(&msg, NULL, 0, 0) { TranslateMessage(&msg); DispatchMessage(&msg); }
7,編寫窗口過程函數
窗口過程函數和程序要實現的功能相關,但是函數原型必須是如下格式:
LRESULT CALLBACK WindowProc( HWND hWnd, //handle to window UINT uMsg, //message identifier WPARAM wParam, //first message parameter LPARAM lParam //second message parameter );
最後附上《VC++深入詳解》書上的例子WinMain.cpp:
#include <windows.h> #include <stdio.h> //窗口函數聲明 LRESULT CALLBACK WinSunProc( HWND hwnd, //handle to window UINT uMsg, //message identifier WPARAM wParam, //first message parameter LPARAM lParam //second message parameter ); int WINAPI WinMain( HINSTANCE hInstance, //handle to current instance HINSTANCE hPrevInstance, //handle to previous instance LPSTR lpCmdLine, //command line int nCmdShow //show state ) { //設計一個窗口類 WNDCLASS wndcls; wndcls.cbClsExtra = 0; wndcls.cbWndExtra = 0; wndcls.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH); wndcls.hCursor = LoadCursor(NULL, IDC_CROSS); wndcls.hIcon = LoadIcon(NULL, IDI_ERROR); wndcls.hInstance = hInstance; //應用程序實力句柄由WinMain函數傳進來 wndcls.lpfnWndProc = WinSunProc; wndcls.lpszClassName = "sunxin2006"; wndcls.lpszMenuName = NULL; wndcls.style = CS_HREDRAW | CS_VREDRAW; RegisterClass(&wndcls); //創建窗口,定義一個變量用來保存成功創建窗口後返回的句柄 HWND hwnd; hwnd = CreateWindow("sunxin2006", "http://www.sunxin.org",WS_OVERLAPPEDWINDOW, 0, 0, 600, 400, NULL, NULL, hInstance, NULL); //顯示及刷新窗口 ShowWindow(hwnd, SW_SHOWNORMAL); UpdateWindow(hwnd); //定義消息結構體,開始消息循環 MSG msg; while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return msg.wParam; } //編寫窗口過程函數 LRESULT CALLBACK WinSunProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) { switch (uMsg) { case WM_CHAR: char szChar[20]; sprintf(szChar, "char code is %d", wParam); MessageBox(hwnd, szChar, "char", 0); break; case WM_LBUTTONDOWN: MessageBox(hwnd, "mouse clicked", "message", 0); HDC hdc; hdc = GetDC(hwnd); TextOut(hdc, 0, 50, "程序員之家", strlen("程序員之家")); ReleaseDC(hwnd, hdc); break; case WM_PAINT: HDC hDC; PAINTSTRUCT ps; hDC = BeginPaint(hwnd, &ps); TextOut(hDC, 0, 0, "http://www.sunxin.org", strlen("http://www.sunxin.org")); EndPaint(hwnd, &ps); break; case WM_CLOSE: if (IDYES == MessageBox(hwnd, "是否真的結束?", "message", MB_YESNO)) { DestroyWindow(hwnd); } break; case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hwnd, uMsg, wParam, lParam); } return 0; }