MFC/QT 学习笔记(一)——认识windows基础库

MFC (微软基础类库),Windows系统平台做GUI尚且OK,但不支持跨平台。

//Windows消息机制:

//1.SDK与API

Software Development Kit,为特定软件框架,硬件平台,操作系统等建立应用软件的开发工具的集合;

Application Programming Interface,操作系统提供给应用程序编程的接口;

//2.窗口和句柄

窗口,一个Windows程序至少有一个主窗口;

句柄,在Windows应用程序中,窗口是通过窗口句柄(HWND)来标识的。我们要对某个窗口进行操作,首先要得到这个窗口的句柄;

//ps:系统在创建各种资源(窗口,图标...)会为他们分配内存,并返回标识这些资源的标识号,即句柄。eg:图标句柄(HICON),光标句柄(HCURSOR),画刷句柄(HBRUSH)

//3.消息与消息队列

Windows是一种事件驱动方式的程序设计模式,主要是基于消息。

//4.WinMain 函数——Windows程序的入口函数,相当于DOS程序的main 

一个完整的Win32程序实现步骤:

  ·WinMain函数的定义

  ·创建一个窗口

  ·进行消息循环

  ·编写窗口过程

//环境:VS2013,实测:VS2017,TranslateMessage函数未找到。

#include <windows.h>//底层实现窗口的头文件

//回调函数
//CALLBACK 代表参数_stdcall参数的传递顺序:从右到左入栈,函数返回前清空栈
LRESULT CALLBACK WindowProc(
    HWND hwnd,//消息所属窗口句柄
    UINT uNsg,//具体消息名称 WM_XXX格式
    WPARAM wParam,//键盘附加消息
    LPARAM lParam) {//鼠标附加消息

    switch (uNsg) {

        //所有以xxxWindow结尾的方法,不进入消息队列,直接执行
    case WM_CLOSE:
        DestroyWindow(hwnd);//DestroyWindow 发送另一个消息WM_DESTROY
        break;
    case WM_DESTROY:
        PostQuitMessage(0);//调用while循环中的break
        break;

    case WM_LBUTTONDOWN://鼠标左键按下
    {
        int xPos = LOWORD(lParam);
        int yPos = HIWORD(lParam);

        char buf[1024];//显示在窗口内
        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);//结束
        break;
    }
    }

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


//程序入口函数
//WINAPI 代表参数_stdcall参数的传递顺序:从右到左入栈,函数返回前清空栈
int WINAPI WinMain(
    _In_ HINSTANCE hInstance,        //应用程序实例句柄
    _In_opt_ HINSTANCE hPrevInstance,//上一个应用程序句柄,一般为NULL
    _In_ LPSTR lpCmdLine,            //char* argv[]
    _In_ 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;//默认风格

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

    //3.创建窗口
    HWND hwnd = CreateWindow(
        wc.lpszClassName,//lpClassName 类名
        TEXT("Windows"),//lpWindowName 标题名
        WS_OVERLAPPEDWINDOW,//dwStyle 默认风格 混合模式
        CW_USEDEFAULT,// x坐标
        CW_USEDEFAULT,// y
        CW_USEDEFAULT,//nWidth宽高
        CW_USEDEFAULT,//nHeight
        NULL,// hWndParent 父窗口
        NULL,//hMenu 菜单
        hInstance,// hInstance 实例句柄
        NULL);//lpParam 附加值 鼠标左右键

    //4.显示和更新
    ShowWindow(hwnd, SW_SHOWNORMAL);//正常大小

    UpdateWindow(hwnd);

    //5.通过循环取消息
    /*
     *typedef struct tagMSG {
     *    HWND        hwnd;        //主窗口句柄
     *    UINT        message;    //具体消息名称
     *    WPARAM      wParam;        //键盘消息 附加消息
     *    LPARAM      lParam;        //鼠标消息 附加消息
     *    DWORD       time;        //消息产生时间,系统自算
     *    POINT       pt;            //鼠标位置
     *}
    **/
    MSG msg;

    while (1) {
        /*
        GetMessageW(
            _Out_ LPMSG lpMsg, 消息
            _In_opt_ HWND hWnd, 捕获窗口,NULL代表捕获所有窗口
            _In_ UINT wMsgFilterMin,
            _In_ UINT wMsgFilterMax);(0,0)代表捕获所有消息
        */
        if (GetMessage(&msg, NULL, 0, 0) == FALSE) {
            break;
        }

        //翻译消息 eg:键入Ctrl+C不可直接打印,需译后再次进入消息队列
        TranslateMessage(&msg);

        DispatchMessage(&msg);//分发消息

    }

    //6.处理窗口过程  up

    return 0;

}

我参考的视频链接:

https://www.bilibili.com/video/av20005978/?p=8&t=328

猜你喜欢

转载自www.cnblogs.com/CowryGao/p/12335788.html