CWinApp中的InitInstance()

initInstance是WinMain调用的第一个函数,用于创立程序。InitInstance基本上只创建程序窗口。这个函数的代码本可直接插入到WinMain中,但将它们放到单独的函数中会更方便(这与多实例的处理有关,因为一个程序可能会多次运行)。注意,InitInstance不是一个像WinMain那样的基本Windows函数,而只是一个“助手”函数。实例句柄是一个程序中使用的全局变量,用于保存主实例。下面展示典型的InitInstance函数调用的形式及它做的工作。不过无须将其当成律条来遵守,因为这只是个标准做法而已,并不是要求。

1. InitInstance函数调用

InitInstance的函数调用如下所示:

 

我们来了解一下参数:

HINSTANCE hInstance。WinMain传递的第一个参数,是它从Windows接收来的程序实例。InitInstance将使用全局实例来检查这个参数,看看新实例是否需要终止(Windows中的常见过程)。如果是,那么程序的主实例会被设置为前台窗口。对于用户而言,就好像再次运行程序的结果就是将原来的实例提到前面来。

int nCmdShow。WinMain传递给InitInstance的第二个参数,也是从Windows接收的参数。这个参数最常见的值有:SW_HIDE和SW_SHOW,Windows通常依据操作系统中的事件(例如电源关闭)来发送这个值。

InitInstance函数返回一个布尔值,它要么是1(true),要么是0(false),告诉WinMain启动是成功了还是失败了。注意,WinMain没有将任何命令行参数传递给InitInstance。如果想处理lpCmdLine字符串,则可创建一个新函数来处理它,也可按照通常的做法来做,即在WinMain中处理参数。

2. InitInstance的结构

在应用程序编程中,经常推荐使用资源表来处理字符串。资源字符串的使用实际上是个人偏好问题(而笔者不使用它们)。有时需要将游戏中的文本移植到另一种语言,而这正是将字符串储存为资源所能带来的便利。但总的来说,这种用法并不普遍。显示资源中的简单消息的代码需要查找每个用到的字符串,这会降低程序运行速度并让代码更为凌乱,尤其是对初学者而言。

从代码看,InitInstance函数颇为简单。下面先列出代码,然后讲解函数的每一部分:

CWinApp中的InitInstance()_第1张图片 
CWinApp中的InitInstance()_第2张图片 
注意,在这段代码之前,程序实际上根本没有用户界面!使用CreateWindow函数创建的主窗口成为程序所用的窗口。InitInstance的全部工作就是创建应用程序所需的新窗口并显示。CreateWindow的参数列表中包括了描述每个参数用途的注释。在创建(并校验)了窗口之后,最后几行代码实际显示新创建的窗口:
 
hWnd值由CreateWindow函数传递给这些函数。在创建窗口时,窗口就已经存在于Windows中了,只是看不见。UpdateWindow通过将WM_PAINT消息发送给窗口处理器告诉新窗口把自己绘制出来。不仅如此,程序也经常以这种方式和自己对话,这在Windows编程中很常见。InitInstance中的最后一行将值1(true)返回给WinMain:
 
如果读者还记得的话,则知道WinMain对待这个返回值很严肃!如果InitInstance目前的情势不对,WinMain将终止程序:
 

从WinWain中返回一个值,无论它是1(true)还是0(false)都将立即终止程序。如果InitInstance的返回值是1,那么前面讲过,WinMain将继续执行,它在while循环中进行消息处理,然后程序将开始运行。

MFC对WindowsAPI进行了封装。在用向导编译成的二进时代码,MFC 编译器 链接器把 源文件编译成PE文件格式存储在 磁盘上。程序执行的时候,从PE 文件头开始执行,在进入Winmain函数之前,进行一系列的必备的初始化。 MFC对这一系列的过程进行了封装。提供给编程人员的第一个裸露程序入口就是CWinApp的InitInstance(),其实程序的入口依然是WinMain()函数。大家都知道,每个程序都有拥有一个进程,每个进程至少有一个线程就是 主线程。CWinThread类是MFC用来封装线程的,这个 主线程就是在WinMain函数中创建的,包括UI线程和工作者线程。因此每个MFC程序至少使用一个CWinThread派生类。被MFC程序员熟知的CWinApp应用类就从这里派生。
InitInstance是CWinThread的一个 虚函数,InitInstance就是“初始化实例”的意思,可见,它是在实例创建时首先被调用的。应用程序总要 重载这个 虚函数,进行系统设置,创建运行环境。例如,主窗口一定要在InitInstance()中创建,因为该函数退出后就进入该线程的 消息循环。
MFC执行流程: _tWinMain(WinMain的别名,用define替换的)-》AfxWinMain->初始化线程,调用InitInstance初始化窗口,调用Run函数进入 消息循环。


你可能感兴趣的:(MFC)