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

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

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

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

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

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

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

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

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

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

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

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

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

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

上一篇:Windows 程序设计 笔记


下一篇:【BZOJ】【1986】【USACO 2004 Dec】/【POJ】【2373】划区灌溉