关于Windows程序模型的最重要之处在于,程序是在Windows面向对象的体系结构中运行的。
在WinMain()函数中,程序所进行的最重要工作是注册窗口类,从而把自定义的窗口过程提供给Windows。然后程序调用Windows创建和显示窗口,由此启动同用户的交互过程。在消息循环中,程序不断取得消息,但并不进行处理,而是将其发回Windows,由Windows将消息发给相应的窗口过程。消息循环的作用在于控制生命期,如果没有消息循环,进程将立即结束。
在较高层次上来看,一个可扩展的系统会给模块提供资源和自由,而模块应当配合系统的整体结构。程序执行时,Windows会为其创建进程,分配资源,并调用WinMain()。WinMain()是进程入口,也是进程出口,在此期间进程可以做任何事情,但是为了使用Windows提供的各种便利,它必须符合Windows程序模型,将自己的运行结合到Windows环境中。作为进程出口,WinMain()决定着程序生命期。一个提供窗口过程而等待Windows调用的程序如何维持和结束自己的生命期呢,应该由消息来决定。当进程没有要处理的消息时,它应该等待,所以WinMain()必须知道有没有消息,Windows发给窗口过程的消息不能绕过WinMain();当进程收到特定的消息时,它结束生命期,所以WinMain()还应该了解消息的内容。这正是GetMessage()所做的,如果取不到消息就阻塞,如果取到WM_QUIT消息就返回0,结束消息循环。那么如果取到普通的消息呢,由WinMain()直接调用窗口过程不可以吗?这种做法有悖于程序由Windows调用的基本思想,而实际上也会出现问题。一个窗口程序可能有很多窗口类,一些窗口类及其窗口过程是程序自定义的,另一些则是在Windows内部定义的,程序看不到其窗口过程,比如各种控件窗口。窗口程序运行起来以后,这些窗口类互相配合,它们通信的方式就是消息。由于消息指向的窗口过程可能是自定义的,也可能是Windows内部的,只有Windows才能把它们都送到目的地,并保持发送方式的一致性。所以WinMain()取到消息后,通过DispatchMessage()将其发回Windows,由Windows为其调用适当的窗口过程,直到窗口过程调用后返回Windows,DispatchMessage()才返回。(Windows调用窗口过程之后控制首先返回Windows,由WinMain()调用窗口过程之后控制保持在程序中,这种区别是否也有作用?不过经我试验,在一个Win32 SDK的Hello程序中改由WinMain()调用窗口过程,没有发现什么问题)
参考资料:
1.《Windows程序设计》/Charles Petzold 著 北京博彦科技发展有限公司 译 北大出版社