一、 WIN32程序

首先:我们看一些简单的名词简写

API: Application Programming Interface 应用程序接口
SDK: Software Development Kit 名义为软件的开发工具,实际上也包括一些程序代码
MFC:Microsoft Foundation Classes 微软基础类库
DLL:Dynamic Link Library 动态链接库(长见识的一点,并不是只有.dll文件才是动态链接库文件,实际上.exe, .fon, .mod, .drv, .ocx都是)
GUI:Graphics User Interface图形用户界面
SDI:Simple Document Interface 简单的文件接口
UI:User Interface 用户界面

接下来讨论一下一个标准的Windows程序的基本框架:
我们都知道,windows系统是基于消息驱动的系统,即通过消息队列传递到每一个窗口去处理消息相应事件的。所以,一个标准的windows程序:
Step 1 : Windows.h文件包含

Step 2: 窗口过程WndProc,关于窗口过程函数,有一点值得关注的是,他是一个callback函数,也就是它自身提供的是一个回调函数,Windows Programming Model这样设计的原因是Windows系统方便自身可能也会调用你的函数,比如(窗口刷新)。

Step 3:WinMain中要实现的主要工作就是窗口注册和创建
这里写图片描述
,显示刷新,消息循环处理
窗口主函数WinMain其中主要的就是消息循环部分

一个简单的消息循环如下:

    MSG msg = { 0 };
    While (msg.message != WM_QUIT)
{
            if (PeekMessage(&Msg, 0, 0, 0, PM_REMOVE))//应用程序以此获取对消息队列操作权利,并获取属于自己的消息
            {
                TranslateMessage(&Msg); //消息解析()
                DispatchMessage(&Msg); //消息派发(通过USER模块发送到窗口函数)
    }
    Else
{
    //TODO:
}
}

其中有两个消息抓取函数:GetMessage和PeekMassage,两个函数都是从消息队列抓取消息,如果抓不到,程序的主线程将会被操作系统挂起,当操作系统再次处理该线程的时候,发现消息队列中仍然是空的,那么这两个函数的操作就有些不同了;
GetMessage:如同大禹治水,过家门而不入。
PeekMessage:继续取回资源控制权,使得程序继续执行一段时间,也就是else里面做的事情了。
这里写图片描述
一个完成的例子:
Step Function:
#

include <Windows.h>

#define MAIN_CLASS_NAME TEXT("mainclass") 

LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE iPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
    int cx = GetSystemMetrics(SM_CXSCREEN);
    int cy = GetSystemMetrics(SM_CYSCREEN);

    cx = (cx - 800) / 2;
    cy = (cy - 600) / 2;

    WNDCLASSEX wndClass = { 0 };

    wndClass.cbClsExtra = 0;
    wndClass.cbSize = sizeof(WNDCLASSEX);
    wndClass.cbWndExtra = 0;
    wndClass.hbrBackground = NULL;
    wndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
    wndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    wndClass.hInstance = hInstance;
    wndClass.lpfnWndProc = WndProc;
    wndClass.lpszClassName = MAIN_CLASS_NAME;
    wndClass.lpszMenuName = NULL;
    wndClass.style = CS_HREDRAW | CS_VREDRAW;

    if (!RegisterClassEx(&wndClass))
    {
        MessageBoxA(NULL, "Class registration faild!", "Error", 0);

        return -1;
    }

    HWND Hwnd = CreateWindowEx(NULL, MAIN_CLASS_NAME, TEXT("test window"),
        WS_OVERLAPPEDWINDOW , (cx), cy,
        800, 600, NULL,
        NULL, hInstance, NULL);

    if (!Hwnd)
    {
        MessageBoxA(NULL, "HWND created faild!", "Erorr", NULL);
        return -1;
    }

    MoveWindow(Hwnd, cx, cy, 800, 600, true);
    ShowWindow(Hwnd, nCmdShow);
    UpdateWindow(Hwnd);

    MSG Msg = { 0 };
    while (Msg.message != WM_QUIT)
    {
        if (PeekMessage(&Msg, 0, 0, 0, PM_REMOVE))
        {
            TranslateMessage(&Msg);
            DispatchMessage(&Msg);
        }
    }
    return 0;
}

LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
    case WM_CREATE:
        break;
    case WM_PAINT:
        break;
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    default:
        return DefWindowProc(hwnd, message, wParam, lParam);
    }

    return DefWindowProc(hwnd, message, wParam, lParam);
}

下面是一个关于Windows和窗口程序消息活动图:从图中可以看出,消息从用户获取到后,通过消息队列发送到该相应窗口,然后做消息处理工作的
这里写图片描述
一个基于界面的窗口程序是由UI和代码两部分完成的,如下,就是一个Windows SDK程序开发的全过程:
这里写图片描述
说完上面,我们关注一下其他的:
消息映射(message map),从《深入浅出MFC》中,有一个关于类似MFC的消息映射机制:

这里写图片描述
这里写图片描述
这里写图片描述
所以这样的话,窗口函数就可以设计成这样的:
这里写图片描述
以及对子窗口命令处理和其他函数处理就可以这样:
这里写图片描述
从而实现了WndProc以及OnCommand函数永远不用管他中间的操作,只需要处理其消息对应的消息函数就可以,比如想处理关于WM_PAINT消息,只需要重载其OnPaint函数即可。
对话框:
Windows对话框分为两种,一种是model对话框,其意在于“另其父窗口无效,直到对话框结束”,另一种是modeless对话框,其意在于父窗口于对话框同时运行。
窗口的生命周期:
这里写图片描述
从上,我们可以看出窗口运行的整个过程,如下:
这里写图片描述
.RC文件:
RC文件是一个以文字描述资源的文件,常用的有ICON、CUSOR、BITMAP等。这类文字描述资源需要RC编译器编译成二进制代码才能使用。

猜你喜欢

转载自blog.csdn.net/huichangxindong/article/details/79960546