moc 发表于 2018-8-18 20:12:16

MFC-002Windows应用程序编程模型

本帖最后由 moc 于 2018-11-12 23:01 编辑

Windows应用程序编程模型
        一个完整的Win32程序(#include<windows.h>),是创建窗口并在其中响应和实现消息,其实现步骤:
        ① WinMain 函数的定义;
        ②创建一个窗口;
        ③进行消息循环;
        ④编写窗口过程函数。

程序具体步骤:
                1、设计窗口
                2、注册窗口
                3、创建窗口
                4、显示和更新
                5、通过循环取消息
                6、处理消息(窗口过程)
实现代码(windows.c):
#include <Windows.h>   // 底层实现窗口的头文件

// CALLBACK代表__stdcall 表示参数的传递顺序:从右到左,以此入栈,并在函数返回前清空栈
//6、处理消息(窗口过程)
LRESULT CALLBACK WindowProc(
        HWND   hwnd,   // 消息所属的窗口句柄
        UINT   uMsg,   // 具体消息名称WM_XXXX消息名
        WPARAM wParam,   // 键盘附加消息
        LPARAM lParam)   // 鼠标附加消息
{
        int xPos, yPos;
        char buf;

        switch (uMsg)
        {
        case WM_CLOSE:   //关闭消息(点击X的消息)
                //所有以xxxWindow结尾的消息,直接进入窗口过程,不进入消息队列
                DestroyWindow(hwnd);   // DestroyWindow 发送另一个消息WM_DESTROY
                break;

        case WM_DESTROY:
                PostQuitMessage(0);   //发送正常的退出,会使GetMessage(&msg, NULL, 0, 0)的值为FALSE,然后退出消息循环
                break;

        case WM_LBUTTONDOWN://鼠标左键按下
                xPos = LOWORD(lParam);
                yPos = HIWORD(lParam);
               
                wsprintf(buf, TEXT("x = %d, y = %d"), xPos, yPos);    //连接字符串
                MessageBox(hwnd, buf, TEXT("鼠标左键按下"), MB_OK);   //弹出消息框
                break;

        case WM_KEYDOWN:   //键盘按下
                MessageBox(hwnd, TEXT("键盘按下"), TEXT("键盘按下"), MB_OK);
                break;
       
        case WM_PAINT:   //绘图事件
                PAINTSTRUCT ps;//绘图结构体)

                HDC hdc = BeginPaint(hwnd, &ps);// 开始绘图,画家
                TextOut(hdc, 100, 100, TEXT("HELLO, 你好"), strlen("HELLO, 你好"));
                EndPaint(hwnd, &ps);
        }

        //返回值用默认处理方式
        return DefWindowProc(hwnd, uMsg, wParam, lParam);
}


//程序入口

// WINAPI 代表__stdcall 表示参数的传递顺序:从右到左,以此入栈,并在函数返回前清空栈
int WINAPI WinMain(
        HINSTANCE hInstance,       // 应用程序实例句柄
        HINSTANCE hPrevInstance,   // 上一个应用程序句柄,在Win32环境下,参数一般为NULL
        LPWSTR lpCmdLine,         // char* argv[]命令行参数
        int nShowCmd)             // 显示窗口最大化、最小化、正常
{
        //1、设计窗口
        WNDCLASS wc;
        wc.cbClsExtra = 0;    // 类的额外内存
        wc.cbWndExtra = 0;    // 窗口的额外内存
        wc.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);   // 设置背景
        wc.hCursor = LoadCursor(NULL, IDC_HAND);   //设置光标 如果第一个参数为NULL, 代表使用系统提供的光标
        wc.hIcon = LoadIcon(NULL, IDI_ERROR);// 设置图标如果第一个参数为NULL, 代表使用系统提供的图标
        wc.hInstance = hInstance; // 应用程序实例句柄, 由操作系统提供,传入WinMain中形参即可
        wc.lpfnWndProc = WindowProc;   // 回调函数, 窗口过程
        wc.lpszClassName = TEXT("WIN");   // 指定窗口类名称
        wc.lpszMenuName = NULL;   // 菜单名称 (不使用)
        wc.style = 0;      // 显示风格 0代表默认窗口

        //2、注册窗口
        RegisterClass(&wc);

        //3、创建窗口
        /*
                LPCTSTR   lpClassName   类名
                LPCTSTR   lpWindowName    标题名
                DWORD   dwStyle         风格 WS_OVERLAPPEDWINDOW(混合风格)
                int       x               显示起点坐标x      CW_USEDEFAULT默认值
                int       y               显示起点坐标y
                int       nWidth          窗口宽度
                int       nHeight         窗口高度
                HWND      hWndParent      父窗口NULL
                HMENU   hMenu         菜单NULL
                HINSTANCE hInstance       实例句柄hInstance
                LPVOID    lpParam         附加值NULL
        */

        HWND hwnd = CreateWindow(wc.lpszClassName, TEXT("WINDOWS"), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL);

        //4、显示和更新
        ShowWindow(hwnd, SW_SHOWNORMAL);
        UpdateWindow(hwnd);

        //5、通过循环取消息
        /* MSG 结构体
        HWND      hwnd;   主窗口句柄
        UINT      message;具体消息名称
        WPARAM    wParam;   附加消息键盘消息
        LPARAM    lParam;   附加消息鼠标消息
        DWORD   time;   消息产生时间
        POINT   pt;       附件消息 鼠标点击位置消息
        */
        MSG msg;

        while (1)
        {
                /*
                LPMSG lpMsg,          消息
                HWNDhWnd,          捕获窗口   填NULL表示捕获所有的窗口
                UINTwMsgFilterMin, 最大最小的过滤消息一般填0,表示不过滤消息
                UINTwMsgFilterMax填0代表捕获所有消息
                */

                if (GetMessage(&msg, NULL, 0, 0) == FALSE)   //==FALSE 表示点击X关闭窗口
                {
                        break;
                }

                //不为FALSE则分发消息(可能需要翻译(比如组合键CTRL+C))
                TranslateMessage(&msg);
                DispatchMessage(&msg);
        }
        return 0;
}
消息处理机制

① 操作系统接收到应用程序的窗口消息,将消息投递到该应用程序的消息队列中。
② 应用程序在消息循环中调用GetMessage函数从消息队列中取出一条一条的消息。取出消息后,应用程序可以对消息进行一些预处理,例如,放弃对某些消息的响应,或者调用TranslateMessage产生新的消息。
③ 应用程序调用DispatchMessage,将消息回传给操作系统。消息是由 MSG结构体对象来表示的,其中就包含了接收消息的窗口的句柄。因此,DispatchMessage函数总能进行正确的传递。
④ 系统利用WNDCLASS结构体的lpfnWndProc成员保存的窗口过程函数的指针调用窗口过程,对消息进行处理。

页: [1]
查看完整版本: MFC-002Windows应用程序编程模型