Windows程序设计笔记(二) 关于编写简单窗口程序中的几点疑惑
在编写窗口程序时主要是5个步骤,创建窗口类、注册窗口类、创建窗口、显示窗口、消息环的编写。对于这5个步骤为何要这样写,当初我不是太理解,学习到现在有些问题我基本上已经找到了答案,同时对于Windows对于窗口的管理机制有了更深的认识,下面我通过问答的方式,一一写出自己之前的疑惑。
问题一、窗口类与窗口之间有何关系?
答:窗口类与窗口就好像C++中类与对象的关系,窗口是窗口类的具体表现,在注册窗口类成功后,系统并没有创建窗口,只是分配的相应的存储空间存储了我们为窗口类填写的一些信息。只有调用CreateWindow后系统才会创建窗口。窗口类中的成员变量定义的是这一类窗口的共性,比如定义窗口类风格为子窗口,那么用这个窗口类创建的窗口就都是子窗口。而创建窗口时传入的参数是具体窗口显示形式,比如大小、长宽等;既然窗口类是窗口的共性,那么窗口过程自然是所有用该类创建的窗口都公用这个窗口过程,窗口过程根据窗口句柄来判断处理那个窗口,而Windows中提供了获取并修改窗口过程的方法(超类化),所以只要掌握了窗口句柄那么就可以控制该类的所有窗口。
问题二、为何需要注册窗口类,而不是根据我们填写的窗口类结构体来直接创建?
答:在程序中为窗口类定义了一个变量,填写好各个成员变量后,这个只是我们自己知道我们定义了一个新的窗口过程但是系统并不知道我们,系统中有一个专门的表用来存储系统中各个窗口类的信息,注册窗口类实际上是将我们填写的窗口类的信息添加到系统的这个表中,以后创建时系统会在这个表中查找相应的窗口类。
问题三、创建窗口时使用的是窗口类名而不是我们定义的窗口类的变量?
答:上面说过,系统中有一个专门用于管理各个窗口类的表,在调用CreateWindow函数时会首先在表中查找是否有这个类,没有的话就返回出错,并不会在我们所定义的窗口类结构体变量的内存中查找,通过这一点我们可以知道其实对于所有的窗口类只需要使用一个结构体变量来创建所有的窗口类,只要注册后系统将相关信息存储到窗口类表中,改变这个变量并不会对前面创建的窗口类产生影响。窗口类表中采用类名作为主码(不知道是不是真的采用数据库的相关方法存储,但是系统是根据类名来唯一确定一条窗口类的信息),并不是保存类结构体变量的地址,所以注册后这个窗口类就与这个变量没有关系。
问题四、为何需要一个窗口句柄、为何系统不直接利用窗口类生成一个窗口,用窗口类名表示窗口窗口?
答:在实际使用中,可能很多窗口具有相同或者相似的性质,因此为了代码的重用,系统抽象出一个窗口类用来管理具有共性的窗口,这样就表示一个窗口类可以产生多个窗口,这样用窗口类的信息管理窗口自然就不现实,而系统采用句柄的方式,而窗口句柄又是什么呢?系统对每个窗口也有一张表,而这个句柄就是相应的表项的一个索引。
问题五、在消息环中GetMessage和Dispatchmessage各有什么作用,为什么一个应用程序只需要一个消息环而不是每个窗口一个消息环?
答:这就涉及到系统的消息机制,Windows采用的是消息机制,每一个应用程序都有一个消息队列,系统有一个总的消息队列用来存储所有的产生的消息,在我们产生相应的操作时,首先由硬件捕捉到再由驱动程序做简单的翻译,再由系统根据传来的信息,组织生成一个MSG结构体,然后由系统根据MSG 中的第一参数发送到相应应用程序的消息队列中,这个是由PostMessage或者是SendMessage来完成,应用程序会不断的从自己的消息队列中取出消息,这是由GetMessage完成,取出后根据MSG中的HWND参数确定是哪个窗口的消息,从而发送到相依的窗口过程中。每个应用程序只有一个消息环,而取出消息和将消息分配到对应的窗口过程都争对的这一个消息队列自然没有必要写多个消息环
问题六、系统是如何根据窗口句柄找到相应的窗口过程的?
答:系统中有两个表分别管理窗口类和窗口,窗口类中最重要的信息是窗口类名和窗口过程地址,有了类名就可以在定义窗口时找到类的相关信息,有了窗口过程地址就可以处理消息,毕竟对于程序而言最重要的还是对于信息的处理,窗口什么的都只是用于与用户更好的交互。而系统在处理消息时是如何知道该调用哪个窗口过程的呢,有一种思路是根据消息中的HWND找到窗口表项,根据表项找到相应的窗口类,最后根据窗口类找到对应的窗口过程,但是实际上系统并不是这样做的,当要处理大量的消息时这样查找效率太低,所以系统的做法是在窗口表项中增加一些空间,用来存储从窗口类中拷贝的信息,在创建窗口时系统将窗口过程等重要信息拷贝一份放到相应的窗口信息表项中,在查找时只要找到窗口就可以找到窗口过程,所有在子类化时我们只是修改窗口表中的窗口过程,这样只改变对应窗口的窗口过程,而用该类创建的其他窗口的窗口过程并不受影响,而改变窗口类的窗口过程,则所有用该类创建的窗口的窗口过程都被修改。
Windows程序设计笔记(二) 关于编写简单窗口程序中的几点疑惑的更多相关文章
- Windows程序设计1(工具、编码、窗口)
一.几个常用小工具: 1. 编译器:CL.EXE 将源文件转变为目标文件(汇编语言). CL.EXE /c xxx.c 或 xx.cpp cl.exe -? 显示cl帮助 cl.exe ...
- Windows 程序设计 笔记
知识点 双字节字符集和Unicode字符集有何区别?采用双字节字符集有何问题 双字节字符集(DBCS)编码是0-255,DBCS含有1字节代码与2字节代码,而Unicode是统一的16位系统,这样就允 ...
- windows程序设计笔记
2014.05.06 新建一个visual C++ -- 常规 -- 空白 的项目,用.c后缀名指定这是一个用C语言来写的windows项目.和C语言的hellworld程序做了一个比较,按照wind ...
- ROS学习(十二)—— 编写简单的消息发布器和订阅器(C++)
一.创建发布器节点 1 节点功能: 不断的在ROS网络中广播消息 2 创建节点 (1)打开工作空间目录 cd ~/catkin_ws/src/beginner_tutorials 创建一个发布器节点( ...
- 学习笔记之javascript编写简单计算器
感觉自己的的实力真的是有待提高,在编写计算器的过程中,出现了各种各样的问题,暴露了自己的基础不扎实,逻辑思维能力不够,学得知识不能运用到自己的demo中区.先介绍一些这个这个计算器的整体思路.大致 ...
- Windows程序设计--(二)Unicode 简介
2.2 宽字符和C语言 2.2.2 更宽的字符 在C语言中的宽字符正是基于short型数据的, 这一数据类型在头文件WCHAR.H中的定义为: typedef unsigned short wchar ...
- Windows服务的安装及配合定时器编写简单的程序
最近要实时统计一些数据,所以就用到了Windows服务及定时任务,在这里记录下. Windows Service简介: 一个Windows服务程序是在Windows操作系统下能完成特定功能的可执行的应 ...
- Qt 编写多窗口程序
该文章原创于Qter开源社区(www.qter.org),作者yafeilinux,转载请注明出处! 导语 程序要实现的功能是:程序开始出现一个对话框,按下按钮后便能进入主窗口,如果直接关闭 ...
- Android学习笔记(第一篇)编写第一个程序Hello World+Activity
PS:终于开始正式的搞Android了...无人带的一介菜鸟,我还是自己默默的努力吧... 学习内容: 1.编写第一个Hello World程序.. 学习Android,那么就需要有一个编译器来集 ...
随机推荐
- SSH Secure Shell显示serverTomcat后台内容
作为linux小白,仅仅有学一点记一点了: 部署server的时候.常常须要向本地一样查看控制台输出,在linux上能够通过查看日志输出替代,当然也能够通过命令让日志实时显示在命令窗体,这对用惯了wi ...
- hdu 1233 还是畅通project(kruskal求最小生成树)
还是畅通project Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Tota ...
- 1692: [Usaco2007 Dec]队列变换|后缀数组|贪心
将字符串翻转后接到原串的后面,中间加一个分隔符,每次都贪心选择rankrank小的那个 事实上就是练习一发后缀数组的模板 #include<algorithm> #include<i ...
- 机器学习——深度学习(Deep Learning)
Deep Learning是机器学习中一个非常接近AI的领域,其动机在于建立.模拟人脑进行分析学习的神经网络,近期研究了机器学习中一些深度学习的相关知识,本文给出一些非常实用的资料和心得. Key W ...
- VirtualBox 安装 Ubuntu 14.04 无法调节分辨率问题
基础环境 宿主系统:Windows 10 虚拟机系统:Ubuntu 14.04-32bit.Ubuntu 14.04-64bit VirtualBox:5.2.0 r118431 (Qt5.6.2) ...
- AJAX扩展-POST传递参数并跳转页面
拓展的代码: 这段代码的原理是创建一个表单,所有args都创建一个隐藏的input,用post方法把这些参数传递过去 注意form表单一定要加载到页面中,即下面代码中标红的部分,不然参数是无法被传递的 ...
- JSON--stringify() 和 parse() 方法
序列化:stringify()将JavaScript对象序列号为JSON字符串反序列化:parse()将JSON字符串解析为原生JavaScript值 序列化选项:JSON.stringify()除了 ...
- 【java API基本实现】LinkedList
LinkedList: package com.tn.arraylist; public class LinkedList { Node head=null; Node tail=null; int ...
- bzoj 2119: 股市的预测
Description 墨墨的妈妈热爱炒股,她要求墨墨为她编写一个软件,预测某只股票未来的走势.股票折线图是研究股票的必备工具,它通过一张时间与股票的价位的函数图像清晰地展示了股票的走势情况.经过长时 ...
- Neo4j学习笔记(1)——使用API编写一个Hello World程序
项目的创建及配置 因为Neo4j依赖的jar包比较多,所以推荐使用Maven来管理. 首先创建一个Maven Project,添加依赖: <dependency> <groupId& ...