在编写窗口程序时主要是5个步骤,创建窗口类、注册窗口类、创建窗口、显示窗口、消息环的编写。对于这5个步骤为何要这样写,当初我不是太理解,学习到现在有些问题我基本上已经找到了答案,同时对于Windows对于窗口的管理机制有了更深的认识,下面我通过问答的方式,一一写出自己之前的疑惑。

问题一、窗口类与窗口之间有何关系?

答:窗口类与窗口就好像C++中类与对象的关系,窗口是窗口类的具体表现,在注册窗口类成功后,系统并没有创建窗口,只是分配的相应的存储空间存储了我们为窗口类填写的一些信息。只有调用CreateWindow后系统才会创建窗口。窗口类中的成员变量定义的是这一类窗口的共性,比如定义窗口类风格为子窗口,那么用这个窗口类创建的窗口就都是子窗口。而创建窗口时传入的参数是具体窗口显示形式,比如大小、长宽等;既然窗口类是窗口的共性,那么窗口过程自然是所有用该类创建的窗口都公用这个窗口过程,窗口过程根据窗口句柄来判断处理那个窗口,而Windows中提供了获取并修改窗口过程的方法(超类化),所以只要掌握了窗口句柄那么就可以控制该类的所有窗口。

问题二、为何需要注册窗口类,而不是根据我们填写的窗口类结构体来直接创建?

答:在程序中为窗口类定义了一个变量,填写好各个成员变量后,这个只是我们自己知道我们定义了一个新的窗口过程但是系统并不知道我们,系统中有一个专门的表用来存储系统中各个窗口类的信息,注册窗口类实际上是将我们填写的窗口类的信息添加到系统的这个表中,以后创建时系统会在这个表中查找相应的窗口类。

问题三、创建窗口时使用的是窗口类名而不是我们定义的窗口类的变量?

答:上面说过,系统中有一个专门用于管理各个窗口类的表,在调用CreateWindow函数时会首先在表中查找是否有这个类,没有的话就返回出错,并不会在我们所定义的窗口类结构体变量的内存中查找,通过这一点我们可以知道其实对于所有的窗口类只需要使用一个结构体变量来创建所有的窗口类,只要注册后系统将相关信息存储到窗口类表中,改变这个变量并不会对前面创建的窗口类产生影响。窗口类表中采用类名作为主码(不知道是不是真的采用数据库的相关方法存储,但是系统是根据类名来唯一确定一条窗口类的信息),并不是保存类结构体变量的地址,所以注册后这个窗口类就与这个变量没有关系。

问题四、为何需要一个窗口句柄、为何系统不直接利用窗口类生成一个窗口,用窗口类名表示窗口窗口?

答:在实际使用中,可能很多窗口具有相同或者相似的性质,因此为了代码的重用,系统抽象出一个窗口类用来管理具有共性的窗口,这样就表示一个窗口类可以产生多个窗口,这样用窗口类的信息管理窗口自然就不现实,而系统采用句柄的方式,而窗口句柄又是什么呢?系统对每个窗口也有一张表,而这个句柄就是相应的表项的一个索引。

问题五、在消息环中GetMessage和Dispatchmessage各有什么作用,为什么一个应用程序只需要一个消息环而不是每个窗口一个消息环?

答:这就涉及到系统的消息机制,Windows采用的是消息机制,每一个应用程序都有一个消息队列,系统有一个总的消息队列用来存储所有的产生的消息,在我们产生相应的操作时,首先由硬件捕捉到再由驱动程序做简单的翻译,再由系统根据传来的信息,组织生成一个MSG结构体,然后由系统根据MSG 中的第一参数发送到相应应用程序的消息队列中,这个是由PostMessage或者是SendMessage来完成,应用程序会不断的从自己的消息队列中取出消息,这是由GetMessage完成,取出后根据MSG中的HWND参数确定是哪个窗口的消息,从而发送到相依的窗口过程中。每个应用程序只有一个消息环,而取出消息和将消息分配到对应的窗口过程都争对的这一个消息队列自然没有必要写多个消息环

问题六、系统是如何根据窗口句柄找到相应的窗口过程的?

答:系统中有两个表分别管理窗口类和窗口,窗口类中最重要的信息是窗口类名和窗口过程地址,有了类名就可以在定义窗口时找到类的相关信息,有了窗口过程地址就可以处理消息,毕竟对于程序而言最重要的还是对于信息的处理,窗口什么的都只是用于与用户更好的交互。而系统在处理消息时是如何知道该调用哪个窗口过程的呢,有一种思路是根据消息中的HWND找到窗口表项,根据表项找到相应的窗口类,最后根据窗口类找到对应的窗口过程,但是实际上系统并不是这样做的,当要处理大量的消息时这样查找效率太低,所以系统的做法是在窗口表项中增加一些空间,用来存储从窗口类中拷贝的信息,在创建窗口时系统将窗口过程等重要信息拷贝一份放到相应的窗口信息表项中,在查找时只要找到窗口就可以找到窗口过程,所有在子类化时我们只是修改窗口表中的窗口过程,这样只改变对应窗口的窗口过程,而用该类创建的其他窗口的窗口过程并不受影响,而改变窗口类的窗口过程,则所有用该类创建的窗口的窗口过程都被修改。

Windows程序设计笔记(二) 关于编写简单窗口程序中的几点疑惑的更多相关文章

  1. Windows程序设计1(工具、编码、窗口)

    一.几个常用小工具: 1. 编译器:CL.EXE   将源文件转变为目标文件(汇编语言). CL.EXE  /c  xxx.c  或   xx.cpp cl.exe  -? 显示cl帮助 cl.exe ...

  2. Windows 程序设计 笔记

    知识点 双字节字符集和Unicode字符集有何区别?采用双字节字符集有何问题 双字节字符集(DBCS)编码是0-255,DBCS含有1字节代码与2字节代码,而Unicode是统一的16位系统,这样就允 ...

  3. windows程序设计笔记

    2014.05.06 新建一个visual C++ -- 常规 -- 空白 的项目,用.c后缀名指定这是一个用C语言来写的windows项目.和C语言的hellworld程序做了一个比较,按照wind ...

  4. ROS学习(十二)—— 编写简单的消息发布器和订阅器(C++)

    一.创建发布器节点 1 节点功能: 不断的在ROS网络中广播消息 2 创建节点 (1)打开工作空间目录 cd ~/catkin_ws/src/beginner_tutorials 创建一个发布器节点( ...

  5. 学习笔记之javascript编写简单计算器

      感觉自己的的实力真的是有待提高,在编写计算器的过程中,出现了各种各样的问题,暴露了自己的基础不扎实,逻辑思维能力不够,学得知识不能运用到自己的demo中区.先介绍一些这个这个计算器的整体思路.大致 ...

  6. Windows程序设计--(二)Unicode 简介

    2.2 宽字符和C语言 2.2.2 更宽的字符 在C语言中的宽字符正是基于short型数据的, 这一数据类型在头文件WCHAR.H中的定义为: typedef unsigned short wchar ...

  7. Windows服务的安装及配合定时器编写简单的程序

    最近要实时统计一些数据,所以就用到了Windows服务及定时任务,在这里记录下. Windows Service简介: 一个Windows服务程序是在Windows操作系统下能完成特定功能的可执行的应 ...

  8. Qt 编写多窗口程序

    该文章原创于Qter开源社区(www.qter.org),作者yafeilinux,转载请注明出处! 导语      程序要实现的功能是:程序开始出现一个对话框,按下按钮后便能进入主窗口,如果直接关闭 ...

  9. Android学习笔记(第一篇)编写第一个程序Hello World+Activity

    PS:终于开始正式的搞Android了...无人带的一介菜鸟,我还是自己默默的努力吧... 学习内容: 1.编写第一个Hello World程序..   学习Android,那么就需要有一个编译器来集 ...

随机推荐

  1. 前端MVC Vue2学习总结(一)——MVC与vue2概要、模板、数据绑定与综合示例

    一.前端MVC概要 1.1.库与框架的区别 框架是一个软件的半成品,在全局范围内给了大的约束.库是工具,在单点上给我们提供功能.框架是依赖库的.Vue是框架而jQuery则是库. 1.2.AMD与CM ...

  2. MyBatis_通过resultMap解决不一致的问题

  3. 工作随笔——自动重发的凶手--feign

    公司使用的feign(https://github.com/OpenFeign/feign)作为http客户端. 开发时debug后端程序,发现同一个请求会多次收到. 为了判断是谁在搞鬼,在客户端和服 ...

  4. 开源免费接口管理平台eoLinker AMS开源版 V3.2.0更新,增加批量导出导入接口功能!

    eoLinker是一个免费开源的针对开发人员需求而设计的接口管理工具,通过简单的操作来帮助开发者进行接口文档管理.接口自动化测试.团队协作.数据获取.安全防御监控等功能,降低企业的接口管理成本,提高项 ...

  5. 对Java中堆栈的解析

    Java把内存分为两种:一种是栈内存,一种是堆内存 栈内存:在函数中定义的一些基本类型的变量和对象的引用变量,当超过变量的作用域之后,Java自动释放该变量内存 堆内存:存放new创建的对象和数组,由 ...

  6. SQL_Server 常用语句以及语法整理

    下列语句部分是Mssql语句,不可以在access中使用. SQL分类: DDL—数据定义语言(CREATE,ALTER,DROP,DECLARE) DML—数据操纵语言(SELECT,DELETE, ...

  7. sourceTree每次拉取代码和提交代码都需要输入密码

    今天新安装的sourceTree导入项目,拉取代码的时候一直提示让我输入git密码,每次拉取和提交的时候都需要重新输入密码,甚是麻烦,在网上,搜索,解决办法五花八门,这里提供一种简单有效的方法供大家参 ...

  8. 如何在阿里云linux上部署java项目

      前2天把git练了下,敲了很多命令,也借助图形界面增强自己的理解,乘着余热把linux在熟悉下.然后想起以前婷主有让我帮忙搭建的阿里云服务器,所以就想自己试着在阿里云的linux上搭建自己的jav ...

  9. Linux 学习记录 二 (文件的打包压缩).

     前言:本文参考<鸟哥的Linux 私房菜>,如有说的不对的地方,还请指正!谢谢!  环境:Centos 6.4    和window不同,在Linux压缩文件需要注意的是,压缩后的文件会 ...

  10. Jrebel简单的热部署一个web工程

    前言:博主最近在做Hybris开发,漫长的启动时间大大的拖累了项目的进度,而Jrebel的出现就是为了减少项目重启的时间或者说修改了代码后直接不用重启就可以看到修改的结果,但是Hybris的部署一直没 ...