首页 > 代码库 > 深入浅出MFC--第一章

深入浅出MFC--第一章

Windows程序的生与死

当使用者按下系统菜单中的Close命令项,系统送出WM_CLOSE。通常程序的窗口函数不拦截次消息,于是DefWindowProc函数处理它。DefWindowProc收到WM_CLOSE后,调用DestoryWindow把窗口清除。DestroyWindow本身又会送出WM_DESTROY。程序对WM_DESTROY的标准反应是调用PostQuitMessage。PostQuitMessage没什么其它动作,就只送出WM_QUIT消息,准备让消息循环退出。

空闲时间的处理:OnIdle

所谓空闲时间(Idle time),是指【系统中没有任何消息等待处理】的时间。举个例子,没有任何程序使用定时器(timer,它会定时送来WM_TIMER),使用者也没有碰触键盘和鼠标或任何外围设备,那么,系统就处在所谓的空闲时间。

空闲时间常常发生。不要认为你移动鼠标时产生了一大堆的WM_MOUSEMOVE,事实上夹杂在每一个WM_MOUSEMOVE之间就可能存在许多空闲时间。毕竟,计算机速度超乎想象。

后台工作最适宜在空闲时间完成。传统的SDK程序如果要处理空闲时间,可以以下列循环取代WinMain中传统的消息循环:

 1 while(TRUE)
 2 {
 3     if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
 4     {
 5         if(msg.message == WM_QUIT)
 6         {
 7             break;
 8         }
 9         TranslateMessage(&msg);
10         DispatchMessage(&msg);
11     }
12     else
13     {
14         OnIdle();
15     }
16 }

原因是PeekMessage和GetMessage的不同,GetMessage是阻塞的,而PeekMessage是非阻塞的。

Console程序和DOS程序的区别

console程序是指在Windows下开发的不实用UI的控制台程序

dos程序是指在dos系统下开发的程序

一个进程的诞生与死亡

执行一个程序就必然产生一个进程。最直接的程序执行方式是在shell中即资源管理器找那个以鼠标双击某个可执行文件的图标,执行起来的App进程其实是shell调用CreateProcess激活的。

让我们看看整个流程:

1、shell调用CreateProcess激活App.exe。

2、系统产生一个【进程核心对象】,计数值为1。

3、系统为此进程建立一个4GB的地址空间。

4、加载器将必要的码加载到上述地址空间中,包括App.exe的程序、资料,以及所需的动态链接库。加载器如何知道要加载哪些dll呢?它们被记录在可执行文件的.idata section中。

5、系统为此进程建立一个执行线程,称为主执行线程(primary thread)。执行线程才是CPU时间的分配对象。

6、系统调用C runtime函数库的startup code。

7、startup code调用App程序的WinMain函数。

8、App程序开始运行。

9、使用者关闭App主窗口,使WinMain中的消息循环结束掉,于是WinMain结束。

10、回到startup code。

11、回到系统,系统调用ExitProcess结束进程。

可以说,透过这种方式执行起来的所有程序都是shell的子进程。本来,父进程与子进程之间可以有某些关系存在,但shell在调用CreateProcess时已经把这种关系剪断,因此它们是独立的实例。