Windows程序的生命周期

来源:互联网 发布:招工软件 编辑:程序博客网 时间:2024/06/06 01:11

    几年前曾经看过侯俊杰老师的《MFC深入浅出》,觉得这本书对MFC的讲解比较深入,由浅入深,对C++的基础、Windows程序的基础、MFC的原理等讲的都比较好。通过几年的工作学习,我对MFC的理解也有了进一步的提高,想再去看一遍这本书,最近看了第一章,就想写点东西来增加自己的理解,也顺便开始我的博客之旅。我的第一篇文章,想谈谈Windows程序的开始和结束。

    每当我们双击桌面上的应用程序图标时,Windows的Shell程序(我的理解可能类似于Windows的任务管理器之类,检测用户的动作)就会创建一个进程,就像我们在程序中显式调用CreateProcess一样,但是这时程序并没有真正运行起来。首先,系统会为创建的进程分配内存空间,一般32位的机器上都是4GB,用于加载程序的数据、代码以及相关的依赖库文件。在这4G的地址空间中,有2G的空间是进程独有的,即每个进程的2G空间不相干扰、互不能访问,另外2G空间用于加载Windows内核程序,这些是每个进程共享的。在这之后,系统会调用C Runtime库中的Startup代码,并在其中调用应用程序的main或者WinMain函数,我的理解应该是进程运行环境准备好后,C Runtime的Startup代码会创建一个主线程,这样main或WinMain函数就会运行在主线程中了。

    每一个Win32程序都有一个WinMain函数,这相当于控制台程序的main函数,是我们自己写的代码的入口点,虽然它并不是程序被调用的第一个函数。进入WinMain函数后程序需要调用RegisterClass注册一个窗口类,这应该是告诉系统窗口的名称、类型、大小等属性,是描述Win32程序的类,而显示出来的窗口只是这个类的一个实例。注册窗口时必须要提供一个“窗口函数”的指针给系统,由于Windows程序是靠消息和事件驱动的,所以必须要告诉系统,该类窗口的消息由谁处理的。窗口类注册成功后,就需要调用CreateWindow和ShowWindow函数去创建和显示窗口了。创建窗口时,系统会发送WM_CREATE消息给窗口,这样程序在窗口创建成功后有机会做一些初始化的操作。显示窗口时,系统也会发送WM_PAINT消息,这样程序就能够控制如何显示窗口。

    接下来的事情就等待用户输入并处理用户输入了。“输入”有可能来自键盘、鼠标等硬件动作,也有可能来自系统或其他程序发送过来的消息,它们都由系统的USER模块进行捕获,我们在调用GetMessage或PeekMessage时会得到这些消息。当获得一个消息后,需要调用TranslateMessage将硬件动作或其他动作转换为通用的MSG消息,然后调用DispatchMessage分发消息。DispatchMessage会通过USER模块将消息发送给窗口函数,由于程序注册窗口类(RegisterClass)时已经提供了窗口函数的指针,所以系统能够根据窗口的类型很方便的调用窗口函数。一开始我会想,为什么这里不是直接调用消息处理函数(窗口函数)去处理消息呢?我想这应该MFC的“框架”特性了,它封装了一些通用的操作,而无需每个窗口都要进行重复的操作。将窗口函数通过指针提交给系统,系统有机会在消息被处理之前做一些其他操作,另外,不一定只有程序本身会调用窗口函数,系统可能会在其他一些情况下调用它。

    当用户关闭窗口时,系统会发送WM_CLOSE消息,如果程序需要在窗口关闭之前做一些事,如提示用户即将退出等,就需要在窗口函数中拦截这个消息,否则调用DestroyWindow函数或直接交由系统的默认窗口函数即可。系统在销毁窗口之前会发送WM_DESTROY消息,程序必须在收到这个消息时调用PostQuitMessage发送WM_QUIT消息,通知系统程序可以退出,否则窗口虽然销毁了,但是进程却没有退出。当然我们也可以在WM_DESTROY消息中处理一些其他事情,如释放资源等操作。

    进程退出后,控制权会回到C Runtime的Startup代码中,我想它应该会调用ExitThread退出主线程。之后系统会调用ExitProcess退出进出,至此,一个程序的运行就算结束了。

本文出自 “Jsl_mes” 博客,请务必保留此出处http://jslmes.blog.51cto.com/5008224/1157947

0 0
原创粉丝点击