深入浅出MFC第2版(PDF格式)-第72部分
按键盘上方向键 ← 或 → 可快速上下翻页,按键盘上的 Enter 键可回到本书目录页,按键盘上方向键 ↑ 可回到本页顶部!
————未阅读完?加入书签已便下次继续阅读!
明),其内只是包含其它的MFC 头文件。应用程序通常会准备自己的
■ STDAFX。H,例如本章的Hello 程序就在STDAFX。H 中包含AFXWIN。H 。
AFXWIN。H 每一个Windows MFC 程序都必须包含它,因为它以及它所包含
■
的文件声明了所有的MFC 类别。此档内含AFX。H ,后者又包含AFXVER_。H ,
后者又包含AFXV_W32。H ,后者又包含WINDOWS。H (啊呼,终于现身)。
■
AFXEXT。H 凡使用工具栏、状态列之程序必须包含这个文件。
■
AFXDLGS。H 凡使用通用型对话框(mon Dialog)之MFC 程序需包含此
档,其内部包含MDLG。H 。
AFXCMN。H 凡使用Windows 95 新增之通用型控制组件(mon Control )
■
之MFC 程序需包含此文件。
AFXCOLL。H 凡使用Collections Classes (用以处理数据结构如数组、串行)
■
之程序必须包含此文件。
■
AFXDLLX。H 凡MFC extension DLLs 均需包含此档。
AFXRES。H MFC 程序的RC 文件必须包含此档。MFC 对于标准资源(例如
■
File、Edit 等菜单项目)的ID 都有默认值,定义于此文件中,例如:
349
…………………………………………………………Page 412……………………………………………………………
第篇 湷觥 FC 程式設計
// File mands
#define ID_FILE_NEW 0xE100
#define ID_FILE_OPEN 0xE101
#define ID_FILE_CLOSE 0xE102
#define ID_FILE_SAVE 0xE103
#define ID_FILE_SAVE_AS 0xE104
。。。
// Edit mands
#define ID_EDIT_COPY 0xE122
#define ID_EDIT_CUT 0xE123
。。。
这些菜单项目都有预设的说明文字(将出现在状态列中),但说明文字并不会事先定义
于此文件,AppWizard 为我们制作骨干程序时才把说明文字加到应用程序的RC 文件中。第
4章的骨干程序Scribble step0 的RC 档中就有这样的字符串表格:
STRINGTABLE DISCARDABLE
BEGIN
ID_FILE_NEW 〃Create a new document〃
ID_FILE_OPEN 〃Open an existing document〃
ID_FILE_CLOSE 〃Close the active document〃
ID_FILE_SAVE 〃Save the active document〃
ID_FILE_SAVE_AS 〃Save the active document with a new name〃
。。。
ID_EDIT_COPY 〃Copy the selection and puts it on the Clipboard〃
ID_EDIT_CUT 〃Cut the selection and puts it on the Clipboard〃
。。。
END
所有MFC 头文件均置于MSVCMFCINCLUDE 中。这些文件连同Windows SDK 的
包含档WINDOWS。H 、MDLG。H 、TOOLHELP。H 、DDEML。H。。。 每每在编译过程中
耗费大量的时间,因此你绝对有必要设定Prepiled header 。
350
…………………………………………………………Page 413……………………………………………………………
第6章 MFC 程式的生死因果
Prepiled Header
一个应用程序在发展过程中常需要不断地编译。Windows 程序包含的标准。H 文件
非常巨大但内容不变,编译器浪费在这上面的时间非常多。Prepiled header 就是
将。H 档第一次编译后的结果贮存起来,第二次再编译时就可以直接从磁盘中取出
来用。这种观念在Borland C/C++ 早已行之,Microsoft 这边则是一直到Visual C++
1。0 才具备。
简化的MFC 程序架构-以Hello MFC 为例
现在我们正式进入MFC 程序设计。由于Document/View 架构复杂,不适合初学者,所
以我先把它略去。这里所提的程序观念是一般的MFC Application Framework 的子集合。
本章程序名为Hello,执行时会在窗口中从天而降〃Hello; MFC〃 字样。Hello 是一个非
常简单而具代表性的程序,它的代表性在于:
■ 每一个MFC 程序都想从MFC 中衍生出适当的类别来用( 不然又何必以
MFC 写程序呢),其中两个不可或缺的类别CWinApp 和CFrameWnd 在Hello
程序中会表现出来,它们的意义如图6…2 。
■ MFC 类别中某些函数一定得被应用程序改写(例如CWinApp::InitInstance ),
这在Hello 程序中也看得到。
■ 菜单和对话框,Hello 也都具备。
图6…3 是Hello 源文件的组成。第一次接触MFC 程序,我们常常因为不熟悉MFC 的
类别分类、类别命名规则,以至于不能在脑中形成具体印象,于是细部讨论时各种信息
及说明彷如过眼云烟。相信我,你必须多看几次,并且用心熟记MFC 命名规则。
图6…3 之后是Hello 程序的源代码。由于MFC 已经把Windows API 都包装起来了,
源代码再也不能够「说明一切」。你会发现MFC 程序很有点见林不见树的味道:
351
…………………………………………………………Page 414……………………………………………………………
第篇 湷觥 FC 程式設計
■ 看不到WinMain,因此不知程序从哪里开始执行。
■ 看不到RegisterClass 和CreateWindow,那么窗口是如何做出来的呢?
■ 看不到 Message Loop (GetMessage/DispatchMessage ),那么程序如何推动?
■ 看不到Window Procedure,那么窗口如何运作?
我的目的就在铲除这些困惑。
Hello 程序源代码
■ HELLO。MAK makefile
■ RESOURCE。H 所有资源ID 都在这里定义。本例只定义一个IDM_ABOUT 。
■ JJHOUR。ICO 图标文件,用于主窗口和对话框。
■ HELLO。RC 资源描述档。本例有一份菜单、一个图标、和一个对话框。
■ STDAFX。H 包含AFXWIN。H 。
■ STDAFX。CPP 包含STDAFX。H ,为的是制造出Prepiled header 。
■ HELLO。H 声明CMyWinApp 和CMyFrameWnd 。
■ HELLO。CPP 定义CMyWinApp 和CMyFrameWnd 。
注意:没有模块定义文件。DEF ?是的,如果你不指定模块定义文件,联结器就使用默认值。
每有WM_PAINT 消息
发生,Hello MFC 字符串
即「从天而降」
Application object
MainFrame object,
是一个全域对象,代
代表主窗口,其基础
表整个程序,其基础
类别是CFrameWnd
类别是CWinApp
图6…2 Hello 程序中的两个对象
352
…………………………………………………………Page 415……………………………………………………………
第6章 MFC 程式的生死因果
STDAFX。H STDAFX。CPP
#include #include
HELLO。CPP HELLO。RC
HELLO。H
#include #include 〃resource。h〃
CMyWinApp #include 〃resource。h〃 #include
class declaration #include 〃hello。h〃
CMyWinApp theApp; Icon description
CMyFrameWnd
class declaration
CMyWinApp
Menu description
class definition
RESOURCE。H
Dialog Template
CMyFrameWnd
#define IDM_xxx
class definition
Message Map
图6…3 Hello 程序的基本文件架构。一般习惯为每个类别准备一个 。H (声
明)和一个 。CPP (实作),本例把两类别集中在一起是为了简化。
HELLO。MAK (请在DOS 窗口中执行nmake hello。mak。环境设定请参考p。224)
#0001 # filename : hello。mak
#0002 # make file for hello。exe (MFC 4。0 Application)
#0003 # usage : nmake hello。mak (Visual C++ 5。0)
#0004
#0005 Hello。exe : StdAfx。obj Hello。obj Hello。res
#0006 link。exe /nologo /subsystem:windows /incremental:no
#0007 /machine:I386 /out:〃Hello。exe〃
#0008 Hello。obj StdAfx。obj Hello。res
#0009 msvcrt。lib kernel32。lib user32。lib gdi32。lib mfc42。lib
#0010
#0011 StdAfx。obj : StdAfx。cpp StdAfx。h
#0012 cl。exe /nologo /MD /W3 /GX /O2 /D 〃WIN32〃 /D 〃NDEBUG〃 /D 〃_WINDOWS〃
#0013 /D 〃_AFXDLL〃 /D 〃_MBCS〃 /Fp〃Hello。pch〃 /Yc〃stdafx。h〃
#0014 /c StdAfx。cpp
#0015
#0016 Hello。obj : Hello。cpp Hello。h StdAfx。h
#0017 cl。exe /nologo /MD /W3 /GX /O2 /D 〃WIN32〃 /D 〃NDEBUG〃 /D 〃_WINDOWS〃
#0018 /D 〃_AFXDLL〃 /D 〃_MBCS〃 /Fp〃Hello。pch〃 /Yu〃stdafx。h〃
#0019 /c Hello。cpp
#0020
#0021 Hello。res : Hello。rc Hello。ico jjhour。ico
#0022 rc。exe /l 0x404 /Fo〃Hello。res〃 /D 〃NDEBUG〃 /D 〃_AFXDLL〃 Hello。rc
353
…………………………………………………………Page 416……………………………………………………………
第篇 湷觥 FC 程式設計
RESOURCE。H
#0001 // resource。h
#0002 #define IDM_ABOUT 100
HELLO。RC
#0001 // hello。rc
#0002 #include 〃resource。h〃
#0003 #include 〃afxres。h〃
#0004
#0005 JJHouRIcon ICON DISCARDABLE 〃JJHOUR。ICO〃
#0006 AFX_IDI_STD_FRAME ICON DISCARDABLE 〃JJHOUR。ICO〃
#0007
#0008 Main