zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    为什么我要用 Node.js? 案例逐一介绍
    不用 Twitter Bootstrap 的5个理由
    20个最强的基于浏览器的在线代码编辑器
    你需要了解 Windows Phone 8.1 的11件事
    你知道吗?什么是 Responsive JavaScript ?
    2014年最佳的10款 PHP 开发框架
    你知道吗?10个精妙的 Java 编码最佳实践
    知识笔记:jQuery 事件对象属性小结
    你知道吗?undefined 与 null 的区别
    Java开发者应该列入年度计划的5件事
  • 原文地址:https://www.cnblogs.com/CowryGao/p/12335788.html
Copyright © 2011-2022 走看看