zoukankan      html  css  js  c++  java
  • Windows编程基础之:基本窗口模型

    /* -------------------------------------------------------------------
                        MyWindows.c -- 基本窗口模型
    --------------------------------------------------------------------*/
    
    #include <windows.h>
    
    LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
    
    // WINAPI:代表 __stdcall 参数的传递顺序:从右到左,依次入栈,并在函数返回前清空堆栈
    // WINAPI:调用约定,主要是参数入栈顺序,这个栈空间的清理者
    int WINAPI WinMain(
        HINSTANCE hInstance,  // 应用程序实例句柄
        HINSTANCE hPrevInstance,  // 上一个应用程序实例句柄,在win32环境下,参数一般为NULL,不起作用了
        PSTR szCmdLine,  // char * argv[]
        int iCmdShow // 显示命令:最大化、最小化、正常
    )
    {
        static TCHAR szAppName[] = TEXT("MyWindows");
        HWND hwnd;
        MSG msg;
        WNDCLASS wndclass;
    
        // 设计一个窗口
        wndclass.style = CS_HREDRAW | CS_VREDRAW; // 显示的风格
        wndclass.lpfnWndProc = WndProc; // 回调函数
        wndclass.cbClsExtra = 0; // 类的额外的内存
        wndclass.cbWndExtra = 0; // 窗口的额外的内存
        wndclass.hInstance = hInstance; // 应用程序实例句柄
        wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION); // 窗口图标,第一个参数为NULL,表示使用系统提供的图标
        wndclass.hCursor = LoadCursor(NULL, IDC_ARROW); // 光标样式,第一个参数为NULL,表示使用系统提供的光标
        wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); // 背景
        wndclass.lpszMenuName = NULL; // 菜单名称,为NULL表示不使用菜单
        wndclass.lpszClassName = szAppName; // 窗口名称
    
        // 注册窗口,注册失败则返回NULL,提示操作系统是否支持窗口
        if (!RegisterClass(&wndclass))
        {
            MessageBox(NULL, TEXT("这个程序需要在 Windows NT 才能执行!"), szAppName, MB_ICONERROR);
            return 0;
        }
    
        // 创建窗口,hwnd接收窗口句柄
        hwnd = CreateWindow(szAppName,              // 类名
                            TEXT("title"),          // 标题名
                            WS_OVERLAPPEDWINDOW,    // 风格
                            CW_USEDEFAULT,          // 显示坐标x,CW_USEDEFAULT默认值
                            CW_USEDEFAULT,          // 显示坐标y
                            CW_USEDEFAULT,          // 宽
                            CW_USEDEFAULT,          // 高
                            NULL,                   // 父窗口
                            NULL,                   // 菜单
                            hInstance,              // 父实例句柄
                            NULL                    // 附加值
                            );
    
        // 显示窗口
        ShowWindow(hwnd, iCmdShow);
        // 更新窗口
        UpdateWindow(hwnd);
    
        // 消息循环
       /*
            MSG:消息结构体
                HWND    hwnd     :      主窗口句柄
                UINT    message  :      具体消息名称
                WPARAM  wParam   :      附加消息 之 键盘消息
                LPARAM  lParam   :      附加消息 之 鼠标消息
                DWORD   time     :      消息产生的时间
                POINT   pt       :      附加消息 之 鼠标位置
       */
        /*
            GetMessage:捕获消息
                LPMSG    lpMsg           : lpMsg 消息
                HWND     hWnd            : 窗口句柄
                UINT     wMsgFilterMin   : 最小过滤消息(一般填0,表示捕获所有消息)
                UINT     wMsgFilterMax   : 最大过滤消息(一般填0,表示捕获所有消息)
        */
        while (GetMessage(&msg, NULL, 0, 0) == TRUE) 
        {
            // 解释消息
            TranslateMessage(&msg);
            // 分发消息
            DispatchMessage(&msg);
        }
    
        return msg.wParam;
    }
    
    // 窗口处理过程
    /*
        CALLBACK  表示参数的传递顺序,入栈,函数返回前清空堆栈
        参数:
            HWND        hwnd        窗口句柄
            UINT        message     具体的消息名称
            WPARAM      wParam      键盘附加消息
            LPARAM      lParam      鼠标附加消息
    */
    LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
        HDC hdc;
        PAINTSTRUCT ps;
        RECT rect;
    
        // 选择感兴趣的消息进行处理
        switch (message)
        {
        case WM_PAINT: // 窗口绘制
            hdc = BeginPaint(hwnd, &ps); // 绘画初始化
            GetClientRect(hwnd, &rect);
            DrawText(hdc, TEXT("大家好,这是我的第一个窗口程序!"), -1, &rect,
                DT_SINGLELINE | DT_CENTER | DT_VCENTER);
            EndPaint(hwnd, &ps);
            return 0;
    
        case WM_LBUTTONDOWN: // 鼠标左键按下
            { // C语言中,在case中定义变量的话,case 体 要用大括号括起来
                // 获取鼠标的位置信息
                int xPos = LOWORD(lParam);
                int yPos = HIWORD(lParam);
                WCHAR buf[1024]; // LPWSTR 或者 WCHAR buf[1024]
                wsprintf(buf, TEXT("x = %d, y = %d"), xPos, yPos);
                MessageBox(hwnd, buf, TEXT("鼠标左键点击"), MB_OK);
                return 0;
            }
        case WM_DESTROY: // 窗口销毁
            PostQuitMessage(0);
            return 0;
        }
    
        // 使用系统默认处理方式处理剩余消息
        return DefWindowProc(hwnd, message, wParam, lParam);
    }
    
  • 相关阅读:
    高手详解:sscanf函数的高级用法
    堆排序——BuildHeap和Heapify函数的实现
    递归与动态规划求解最长公共子序列
    分享:crpcut 1.8.4 发布,C++ 的单元测试框架
    团队展示 京拍档 电商运营服务、电子商务服务外包 首家京东代运营电子商务服务平台
    Linux中link,unlink,close,fclose详解
    常用排序算法的c++实现(冒泡,选择,插入,堆,shell,快速,归并 )与sort()对比 coder_xia的专栏 博客频道 CSDN.NET
    CAJ文件转PDF文件方法
    递归与动态规划求解最长公共子序列
    NLP Job 专注自然语言处理&机器学习等领域的求职招聘 | 关注自然语言处理|机器学习|数据挖掘|搜索引擎|计算广告|推荐算法等相关领域的工作机会
  • 原文地址:https://www.cnblogs.com/wbyixx/p/13975547.html
Copyright © 2011-2022 走看看