創建Win32應用程序步驟——《VC++深入詳解》讀書筆記

Win32應用程序創建步驟:

  1. 編寫WinMain函數

  2. 設計窗口類(WNDCLASS)

  3. 註冊窗口類

  4. 創建窗口

  5. 顯示並更新窗口

  6. 編寫消息循環

  7. 編寫窗口過程函數



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;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章