按键盘上方向键 ← 或 → 可快速上下翻页,按键盘上的 Enter 键可回到本书目录页,按键盘上方向键 ↑ 可回到本页顶部!
————未阅读完?加入书签已便下次继续阅读!
本书关于进程和线程的有关章节。
同其它的任何Windows应用一样,框架应用程序仍然具有一个WinMain
函数。但是,在由AppWizard生成的应用程序框架中,我们却找不到
对WinMain函数的声明或定义。在MFC应用程序中,WinMain函数是由
类库提供的,它在应用程序启动时被调用。WinMain函数执行如注册
窗口类之类的标准服务。接着,它调用应用程序对象的成员函数来初
始化并且运行应用程序。通过重载WinMain函数所调用的类CWinApp的
成员函数可以自定义WinMain函数。
WinMain函数通过调用应用程序对象的InitApplication和
InitInstance成员函数来初始化应用程序,通过调用Run成员函数运
行应用程序的消息循环,最后在程序结束时调用程序程序的
ExitInstance成员函数。其中Run函数一般由MFC提供,而
InitApplication、InitInstance和ExitInstance一般需要程序员创
建或进行重载。
l 注意:
l 由于在Win32环境下,每一个应用程序的实例都是独立的,它们有
着 自己的虚拟地址空间,因此,在目前版本的MFC中,成员函数
CWinApp::InitApplication已被废弃,原来在InitApplication中
进行的初始化操作应该移到InitInstance中进行。
由AppWizard生成的基于对话框的框架应用程序提供了对
InitInstance的默认重载,也正是在该成员函数中提供了基于对话框
…………………………………………………………Page 174……………………………………………………………
的应用程序的特点。在MFC中,无论是基于对话框的应用程序,还是
基于文档/视结构的应用程序,它们的应用程序对象都是从CWinApp派
生而来的,它们之间的功能的巨大差异,往往就是通过对类CWinApp
的成员函数进行不同的重载来体现的。
在每一个同一应用程序的实例被启动时,WinMain函数调用一次
InitInstance成员函数。原有的InitApplication不再有意义,每一
个应用程序的实例都被认为是独立的,对应用程序的初始化同对实例
的初始化没有本质区别。对于InitInstance成员函数,我们这时只需
知道它在当应用程序进行初始化的时候由WinMain函数调用。关于基
于对话框的应用程序的InitInstance成员函数的典型实现,我们将在
本章后面的内容中专门讲述。
类CDialogDemoApp的实现包含在文件DialogDemo。cpp中,其清单如
下:
// DialogDemo。cpp : 为应用程序定义类的行为
//
#include 〃stdafx。h〃
#include 〃DialogDemo。h〃
#include 〃DialogDemoDlg。h〃
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE'' = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CDialogDemoApp
BEGIN_MESSAGE_MAP(CDialogDemoApp; CWinApp)
//{{AFX_MSG_MAP(CDialogDemoApp)
// 注意 ClassWizard 将在此添加或删除映射宏。
// 不要删除你在这里看到的这些生成代码块 !
…………………………………………………………Page 175……………………………………………………………
//}}AFX_MSG
ON_MAND(ID_HELP; CWinApp::OnHelp)
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CDialogDemoApp 构造
CDialogDemoApp::CDialogDemoApp()
{
// TODO: 在这里添加构造代码,
// 将所有重要的初始化放入 InitInstance
}
/////////////////////////////////////////////////////////////////////////////
// 唯一的 CDialogDemoApp 对象
CDialogDemoApp theApp;
/////////////////////////////////////////////////////////////////////////////
// CDialogDemoApp 初始化
BOOL CDialogDemoApp::InitInstance()
{
AfxEnableControlContainer();
// 标准初始化
// 如果你不需要使用这些特性,并且希望减小最终可执行文件的大小,你可以删除
// 下面的特定的初始化过程中不需要的部分。
#ifdef _AFXDLL
Enable3dControls(); // 当通过共享 DLL 使用 MFC 时调用
#else
Enable3dControlsStatic(); // 当通过静态链接到 MFC 时调用
#endif
…………………………………………………………Page 176……………………………………………………………
CDialogDemoDlg dlg;
m_pMainWnd = &dlg;
int nResponse = dlg。DoModal();
if (nResponse == IDOK)
{
// TODO: 在这里添加当使用 OK 关闭对话框时的处理代码
}
else if (nResponse == IDCANCEL)
{
// TODO: 在这里添加当使用 Cancel 关闭对话框时的处理代码
}
// 由于对话框已被关闭,返回 FALSE 并退出应用程序,而不需要启动应用程序
// 消息泵。
return FALSE;
}
上面的源代码为类CDialogDemoApp提供了一个空的构造函数和一个对
InitInstance的默认重载。我们把讨论的重点放在InitInstance成员
函数上。在InitInstance成员函数的一开始,先调用MFC全局函数
AfxEnableControlContainer,该函数为应用程序提供了对OLE控件
(新的术语称作ActiveX控件)的支持。
接着,InitInstance成员函数调用类CWinApp的成员函数
Enable3dControls或Enable3dControlsStatic以允许对话框和窗口可
以使用具有三维外观的控件。这两个成员函数加载CTL3D32。DLL并且
注册应用程序。Enable3dControls和Enable3dControlsStatic的区别
在于一个在链接到MFC动态链接库时使用,而另一个在使用MFC的静态
链接时使用。
MFC 自动为以下窗口类提供3D控件效果:
l CDialog
l CDialogBar
…………………………………………………………Page 177……………………………………………………………
l CFormView
l CPropertyPage
l CPropertySheet
l CControlBar
l CToolBar
如果你所希望得到3D效果的控件属于以上类型之一的话,你只需调用
Enable3dControls或Enable3dControlsStatic即可。反之则必须直接
调用相应的CTL3D32 API函数。
然后在InitInstance中定义了类型为CDialogDemoDlg的对象dlg,然
后将其指针赋予类型为CWnd的成员变量m_pMainWnd。成员变量
m_pMainWnd用来保存指向线程主窗口对象的指针,当由m_pMainWnd引
用的窗口被关闭时,该线程由MFC 自动终止。当应用程序的主线程被
终止时,该应用程序相应的也被终止。如果该成员的值为NULL,则应
用程序的CWinApp对象的主窗口被用来判断线程何时终止。成员
m_pMainWnd具有共有访问权限。对于工作者线程而言,该数据成员的
值从其父线程继承。
接着InitInstance调用了对象dlg的成员函数DoModal,该成员函数以
模态方式调用对话框并在结束时返回对话框的结果。在对话框激活
时,该成员函数处理所有与用户的交互,也就是说,对于模态对话
框,用户不可以在对话框关闭之前与其它窗口进行交互。
如果用户单击了对话框中的OK或Cancel按钮,相应的消息处理函数,
如OnOK或OnCancel被调用以试图关闭对话框。OnOK成员函数的默认行
为为验证和更新对话框数据并以结果IDOK关闭对话框,OnCancel的默
认行为