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


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