Windows窗口过程

news2025/1/23 9:20:19

一、窗口类(WNDCLASS)

定义:窗口类是一个属性集,是Windows编程中用于创建窗口的模板。窗口类包含了窗口的各种信息的数据结构,每个窗口都具有窗口类,每个窗口都是基于自己的窗口类来进行创建窗口的。每一个窗口类都有一个名称,使用窗口类时必须注册到操作系统中去。
分类:窗口类可以分为系统窗口类、应用程序全局窗口类、应用程序局部窗口类。
系统窗口类——系统中已经定义好的窗口类,所有的的应用程序都可以使用 如:BUTTON EDIT。
应用程序全局窗口类——由用户自己定义的,当前应用程序所有模块都可以使用。
程序局部窗口类——由用户自己定义,当前应用程序中本模块中可以使用
结构:

typedef struct_WNDCLASS{
  UINT style;                 //窗口类的缓冲大小
  WNDPROC lpfnWndProc;        //窗口的消息处理函数的指针
  int cbClsExtra;             //窗口类的buff的缓冲大小
  int cbWndExtra;             //窗口的buff的缓冲大小
  HANDLE hInstance;           //当前窗口的实例
  HICON hIcon;                //窗口图标句柄
  HCURSOR hCursor;            //窗口鼠标句柄
  HBRUSH hbrBackground;       //绘制窗口背景的画刷句柄
  LPCTSTR lpszMenuName;       //窗口菜单资源ID的字符串
  LPCTSTR lpszClassName;      //窗口类的名称
  }WNDCLASS;

注意:1. 不建议使用全局窗口类,容易发生冲突,全局窗口实现的功能,局部窗口类都可以实现;

     2. 用户在创建窗口时,首先需要对窗口进行注册,即通过ATOM RegisterClassEx(CONST WNDCLASSEX *Ipwcx):将窗口类的结构写入操作系统中。

 

                

当调用完 CreateWindow 函数的时候:应用程序实例 以及 相应的消息队列已经生成了!

二、生成窗口步骤

1. 设计窗口类(WNDCLASS)
2. 注册窗口:将窗口类的信息写入操作系统的内核中。RegisterClass(窗口类结构体的指针),如RegisterClass(&wndclass)
3. 创建窗口:在内存中开辟一片空间,将窗口的数据(包括CreateWindows传入的数据和窗口类的数据)写入内存,并返回该内存的地址(窗口句柄)。hwnd = CreateWindow()
4. 显示及更新窗口:按照内存中的窗口数据绘制窗口。ShowWindow(HWND hWnd,int mCmdStyle) 、UpdateWindow( hwnd )
5. 消息循环:获取、翻译、分发窗口中的消息
6. 窗口的消息处理函数进行消息处理:处理窗口中的消息
以上对窗口的创建流程进行了概括,接下来对窗口创建过程进行详细的分析。

三、举例

在创建窗口 和 构造WNDCLASS的过程中,有两个相同参数lpszClassName(窗口名称)和hInstance(窗口实例),创建窗口CreateWindow 和 注册窗口RegisterClass,通过这2个参数联系起来的。

/**
一个简单的Win32应用程序,通过这个简单的实例讲解Windows消息是如何传递的
*/
#include <windows.h>
 
//声明窗口过程函数
LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);
 
//定义一个全局变量,作为窗口类名
TCHAR szClassName[] = TEXT("SimpleWin32");
 
//应用程序主函数
int WINAPI WinMain (HINSTANCE hInstance,
                                  HINSTANCE hPrevInstance,
                                  LPSTR szCmdLine,
                                  int iCmdShow){
    /***********注意以下几步是windows窗口创建的流程*********************/
    //1.设计一个窗口类
    //(说明:在这里需要自己查一下 _WNDCLASS结构体,不过里边的成员就是以下被初始化的那些变量)
    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);//图标
    wndclass.hCursor = LoadCursor(NULL,IDC_ARROW);//光标
    wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);//画刷
    wndclass.lpszMenuName  = NULL;//菜单
    wndclass.lpszClassName = szClassName;//类名称
//};
 
    //2.注册窗口类
    if(!RegisterClass (&wndclass)){
        MessageBox (NULL, TEXT ("RegisterClass Fail!"), szClassName, MB_ICONERROR);
        return 0;
    }
 
    //3.创建一个窗口
    HWND hwnd;
    hwnd = CreateWindow(szClassName,//窗口类名称
           TEXT ("The Simple Win32 Application"),//窗口标题 
           WS_OVERLAPPEDWINDOW,//窗口风格,即通常我们使用的windows窗口样式
           CW_USEDEFAULT,//指定窗口的初始水平位置,即屏幕坐标系的窗口的左上角的X坐标
           CW_USEDEFAULT,//指定窗口的初始垂直位置,即屏幕坐标系的窗口的左上角的Y坐标
           CW_USEDEFAULT,//窗口的宽度
           CW_USEDEFAULT,//窗口的高度
           NULL,//父窗口句柄
           NULL,//窗口菜单句柄
           hInstance,//实例句柄
           NULL);
    
    //4.显示窗口
    ShowWindow(hwnd,iCmdShow);
    
    //5.更新窗口
    UpdateWindow(hwnd);
 
 
    //消息循环
    MSG msg;
    while(GetMessage(&msg,NULL,0,0))//从消息队列中取消息 
    {
           TranslateMessage (&msg);              //转换消息
           DispatchMessage (&msg);               //派发消息
    }
    return msg.wParam;
}
 
/**
*消息处理函数
*参数:窗口句柄,消息,消息参数,消息参数
*/
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    //处理感兴趣的消息
    switch (message)
    {
        case WM_DESTROY:
            //当用户关闭窗口,窗口销毁,程序需结束,发退出消息,以退出消息循环
            PostQuitMessage(0);
            return 0;
    }
    //其他消息交给由系统提供的缺省处理函数
    return ::DefWindowProc (hwnd, message, wParam, lParam);
}

四、

4.1 在窗口的创建之前,为什么要进行注册?

想创建什么样的窗口呢?那么,创建什么样的窗口呢?创建前,Window系统可不知道你要的是什么类型的窗口啊(比如标题栏上显示什么图标,鼠标形状是什么,窗口背景颜色等等)。这些类型信息应在你创建前事先告诉Window系统。可以采用这种方法:就是我们事先写一份要创建窗口的类型申请表,提交(注册)给Window系统。然后在创建时,可以让Windows按这个申请表来创建你所要的窗口了。也就是说我们还应该先提交一个申请表,申请成功后再根据这个表创建一个窗口。

4.2 窗口创建和注册之间有什么关系?

通过分析,我们惊奇的发现在创建窗口和构造WNDCLASS的过程中有两个相同参数lpszClassName(窗口名称)和hInstance(窗口实例),创建窗口和注册窗口通过这两个参数联系起来的。
CreateWindow函数的执行过程:

1.CreateWindow首先会根据窗口类的名称在应用程序局部窗口类中查找窗口类,如果找到执行2,若未找到执行3。
2.比较局部窗口类与创建窗口类传入的hinstance是否相同,如果相同在同一模块下创建该窗口。否则执行3。
3.在应用程序全局窗口类中查找,若查找到执行4,否则执行5。
4.使用窗口信息创建窗口并返回。因为要创建的是全局窗口所以不需要比对hInstance。
5.在系统窗口类中查找,若找到创建窗口,否则创建窗口失败,返回NULL。

CreateWindow找到相应的窗口类后会在内存中开辟一个空间来存储窗口类的信息并返回该内存地址的指针(句柄)。

参考:https://blog.csdn.net/qq_43725310/article/details/126103608

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1102022.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【前端】Js

目 录 一.前置知识第一个程序JavaScript 的书写形式注释输入输出 二.语法概览变量的使用理解 动态类型基本数据类型 三.运算符算术运算符赋值运算符 & 复合赋值运算符自增自减运算符比较运算符逻辑运算符位运算移位运算 四.条件语句if 语句三元表达式switch 五.循环语句whi…

云技术分享 | 快速构建 CodeWhisperer 代码生成服务,让 AI 辅助编程

前言 Amazon CodeWhisperer 是 2023 年 4 月份发布的一款通用的、机器学习驱动的代码生成器服务&#xff0c;CodeWhisperer 经过数十亿行 Amazon 和公开可用代码的训练&#xff0c;可以理解用自然语言&#xff08;英语&#xff09;编写的评论&#xff0c;可在集成式开发环境 (…

Unity笔记--渲染顺序

目录 Unity中的渲染顺序一、Camera层二、透明类型&#xff08;先渲染不透明&#xff09;三、物体的SortingLayer&#xff08;越小越先渲染&#xff09;四、sorting order&#xff08;越小越先渲染&#xff09;五、RenderQueue &#xff08;越小越优先&#xff09;六、距离相机z…

在 rider 里用配置 Perforce(P4)的注意事项

整个配置界面里&#xff0c;关键就配2处位置&#xff0c;但是都有些误导性。 1是连接形参的4个参数都得填&#xff0c;字符集看你项目的要求&#xff0c;这里工作区其实指的是你的工作空间&#xff0c;还不如显示英文的 Workspace 呢&#xff0c;搞得我一开始没填&#xff0c;…

Spring事件ApplicationEvent源码浅读

文章目录 demo应用实现基于注解事件过滤异步事件监听 源码解读总结 ApplicationContext 中的事件处理是通过 ApplicationEvent 类和 ApplicationListener 接口提供的。如果将实现了 ApplicationListener 接口的 bean 部署到容器中&#xff0c;则每次将 ApplicationEvent 发布到…

windows电脑彻底删除文件怎么恢复?可尝试这2种恢复办法!

在使用windows电脑过程中&#xff0c;误删重要文件是时常发生的事情。如果幸运的话&#xff0c;误删的文件可以在回收站中还原。而有时&#xff0c;这些文件是被彻底删除的&#xff0c;并不会经过回收站。windows彻底删除文件怎么恢复&#xff1f; windows彻底删除了文件&…

第四章 Istio出口流量管理

文章目录 访问外部服务Envoy 代理将请求传递给网格外服务配置服务条目以提供对外部服务的受控访问访问外部 HTTP 服务 直接访问外部服务 出口网关清理 HTTP 网关其他 访问外部服务 为了更好的做好网络访问控制&#xff0c;k8s结合Istio出口网络升级示意图 来自 Istio 的 pod…

linux入门到精通-第四章-gcc编译器

目录 参考gcc概述gcc的工作流程 参考 gcc编译器 gcc概述 编辑器vi、记事本)是指我用它来写程序的 (编辑码)&#xff0c;而我们写的代码语句&#xff0c;电脑是不懂的&#xff0c;我们需要把它转成电脑能懂的语句&#xff0c;编译器就是这样的转化工具。就是说&#xff0c;我…

4.MidBook项目经验之MonogoDB和easyExcel导入导出

1.数据字典(固定的数据,省市级有层级关系的) //mp表如果没有这个字段,防报错,eleUI需要这个字段TableField(exist false) //父根据id得到子数据 ,从controller开始自动生成代码-->service//hasChildren怎么判断,只需要判断children的parentid的count数量>0就可以了//优化…

uniapp订单循环列表倒计时

目录 效果图片插件uni-countdown代码最后 效果图片 插件uni-countdown 地址 代码 <template><view class""><!-- 下面循环两个列表 --><view class"item" v-for"(item, index) in listData" :key"index">&…

企业c#语言源代码防泄密解决方案

在当今数字化时代&#xff0c;企业的核心业务往往依赖于软件应用程序。为了保护企业的知识产权和敏感信息&#xff0c;源代码的保密至关重要。对于制造类企业尤其是智能制造业来讲&#xff0c;最近几年是高速发展的时期&#xff0c;很多公司在做工厂流水线设备时&#xff0c;就…

远程VPN登录,IPsec,VPN,win10

windows10 完美解决L2TP无法连接问题 windows10 完美解决L2TP无法连接问题 - 哔哩哔哩

点击切换播放图片

<template><!-- banner组件 --><div class"wrap-box"><div class"image-container"><img :src"currentImage" alt"Image"></div><div class"controls"><div class"btn&q…

Deploy、Service与Ingress

Deployment 自愈 介绍:控制Pod&#xff0c;使Pod拥有多副本&#xff0c;自愈&#xff0c;扩缩容等能力 # 清除所有Pod&#xff0c;比较下面两个命令有何不同效果&#xff1f; kubectl run mynginx --imagenginxkubectl create deployment mytomcat --imagetomcat:8.5.68 # 自…

安防视频监控EasyCVR平台修改默认数据为MySQL,但忘记登录密码该如何解决?

视频云存储/安防监控EasyCVR视频汇聚平台基于云边端智能协同&#xff0c;支持海量视频的轻量化接入与汇聚、转码与处理、全网智能分发、视频集中存储等。音视频流媒体视频监控平台EasyCVR拓展性强&#xff0c;视频能力丰富&#xff0c;具体可实现视频监控直播、视频轮播、视频录…

Windows设置开机自启

Windows设置开机自启 一&#xff1a;添加服务二&#xff1a;添加注册表三&#xff1a;添加本地组策略四&#xff1a;添加启动文件夹五&#xff1a;添加任务计划程序 启动优先级&#xff1a;服务>注册表>启动文件夹>任务计划 一&#xff1a;添加服务 注&#xff1a;命…

代码随想录算法训练营第五十六天| 1143.最长公共子序列 、 1035.不相交的线 、53. 最大子序和 动态规划

代码随想录算法训练营第五十六天| 1143.最长公共子序列 、 1035.不相交的线 、53. 最大子序和 动态规划 文章目录 代码随想录算法训练营第五十六天| 1143.最长公共子序列 、 1035.不相交的线 、53. 最大子序和 动态规划[toc]1143.最长公共子序列1035.不相交的线53. 最大子序和 …

【重磅!】2023亚洲品牌500强在香港隆重发布,后羿品牌与华为、抖音、比亚迪、贵州茅台等入选登榜!

9月25日&#xff0c;由专业品牌评价机构Asiabrand发起主办&#xff0c;中国亚洲经济发展协会、一带一路总商会、《环球时报》社、东盟-中国总商会、亚太第一卫视和香港中小企业发展促进会联合主办的“第18届亚洲品牌盛典”在香港隆重举行。众多国际知名品牌齐聚一堂&#xff0c…

低代码:让软件开发不再遥不可及

近些年来&#xff0c;低代码的发展趋势可谓是蒸蒸日上&#xff01;当然&#xff0c;热门的技术总会伴随着质疑的声音&#xff0c;诞生至今&#xff0c;大家各抒己见&#xff0c;也不乏有针锋相对的意思。这本质上是一件有助于推动低代码发展的事情。 业内的朋友们一定知道&…

Peter算法小课堂—蠕动区间

蠕动区间 蠕动区间&#xff08;尺取法、双游标&#xff09;是一个经典的优化算法。 我们以毛毛虫&#x1f41b;举例说明 具体的&#xff0c;我们看题目 例题 最小区间 这一题&#xff0c;我们用暴力法&#xff0c;复杂度O(N^2) 先给出暴力法代码 int ansn1; for(int tail…