深入浅出MFC第2版(PDF格式)-第86部分
按键盘上方向键 ← 或 → 可快速上下翻页,按键盘上的 Enter 键可回到本书目录页,按键盘上方向键 ↑ 可回到本页顶部!
————未阅读完?加入书签已便下次继续阅读!
第7章 簡單而完整:MFC 骨幹程式
利用Visual C++ 工具完成Scribble step0
我已经在第4章示范过AppWizard 的使用方法,并实际制作出Scribble Step0 程序,这
里就不再重复说明了。完整的骨干程序源代码亦已列于第4章。
这些由「生产线」做出来的程序代码其实对初学者并不十分合适,原因之一是容易眼花撩
乱,有许多#if。。。#endif、批注、奇奇怪怪的符号(例如//{ 和//});原因之二
是每一个类别有自己的。H 档和。CPP 文件,整个程序因而幅员辽阔(六个。CPP 档和六
个。H 档)。
图7…4 是Scribble step0 程序中各类别的相关资料。
类别名称 基础类别 类别声明于 类别定义于
CScribbleApp CWinApp Scribble。h Scribble。cpp
CMainFrame CMDIFrameWnd Mainfrm。h Mainfrm。cpp
CChildFrame CMDIChildWnd Childfrm。h Childfrm。cpp
CScribbleDoc CDocument ScribbleDoc。h ScribbleDoc。cpp
CScribbleView CView ScribbleView。h ScribbleView。cpp
CAboutDlg CDialog Scribble。cpp Scribble。cpp
图7…4 Scribble 骨干程序中的重要组成份子
骨干程序使用哪些MFC 类别?
对,你看到的Scribble step0 就是一个完整的MFC 应用程序,而我保证你一定昏头转向
茫无头线程。没有关系,我们才刚启航。
如果把标准图形接口(工具栏和状态列)以及Document/View 考虑在内,一个标准的
MFC MDI 程序使用这些类别:
423
…………………………………………………………Page 486……………………………………………………………
第篇 湷觥 FC 程式設計
MFC 类别名称 我的类别名称 功能
CWinApp CScribbleApp application object
CMDIFrame Wnd CMainFrame MDI 主窗口
Document/View
CMultiDocTemplate 直接使用 管理
CDocument CScribbleDoc Document ,负责数据结构与文件动作
CView CScribble View View ,负责资料的显示与打印
CMDIChild Wnd CChildFrame MDI 子窗口
CToolBar 直接使用 工具栏
CStatusBar 直接使用 状态列
CDialog CAboutDlg About 对话框
应用程序各显身手的地方只是各个可被改写的虚拟函数。这九个类别在MFC 的地位请看
图7…1 。下一节开始我会逐项解释每一个对象的产生时机及其重要性质。
Document/View 不只应用在MDI 程序,也应用在SDI 程序上。你可以在AppWizard 的
「Options 对话框」(图4…2b )选择SDI 风格。本书以MDI 程序为讨论对象。
为了对标准的MFC 程序有一个大局观,图7…4 显示Scribble step0 中各重要组成份子(类
别),这些组成份子在执行时期的意义与主从关系显示于图7…5 。
424
…………………………………………………………Page 487……………………………………………………………
第7章 簡單而完整:MFC 骨幹程式
Document
(CDocument 对象)
Application 对象
(CWinApp 对象)
Document Template 对象 工具栏(CToolBar 对象)
(CMultiDocTemplate 对象) { MDI Frame 窗口
(CMDIFrameWnd 对象)
状态列(CStatusBar 对象)
MDI Child 窗口
对话框(CDialog 对象) View
(Document Frame 窗口)
(CView 对象) (CMDIChildWnd 对象)
虚线框者表示,应用程序通常不必改写该基础类别,可直接拿来使用.
图7…5 Scribble step0 程序中的九个对象 (几乎每个MFC MDI 程序都如此)
。
图7…6 是Scribble step0 程序缩影,我把执行时序标上去,对于整体概念的形成将有帮助。
#0001 class CScribbleApp : public CWinApp
#0002 {
注意:第6章的HelloMFC 程序是在
#0003 virtual BOOL InitInstance(); //
#0004 afx_msg void OnAppAbout(); //
类别中处理〃About〃 命令,这里的
#0005 DECLARE_MESSAGE_MAP() //程序却在CWinApp 衍生类别中处理之。到底,
#0006 }; //一个消息可以(或应该)在哪里被处理才是合理?
#0007 // 第9章「消息映射与命令绕行」可以解决这个疑惑。
#0008 class CMainFrame : public CMDIFrameWnd
#0009 {
#0010 DECLARE_DYNAMIC(CMainFrame)
#0011 CStatusBar m_wndStatusBar;
#0012 CToolBar m_wndToolBar;
#0013 afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
#0014 DECLARE_MESSAGE_MAP()
#0015 };
#0016
#0017 class CChildFrame : public CMDIChildWnd
#0018 {
425
…………………………………………………………Page 488……………………………………………………………
第篇 湷觥 FC 程式設計
#0019 DECLARE_DYNCREATE(CChildFrame)
#0020 DECLARE_MESSAGE_MAP()
#0021 };
#0022
#0023 class CScribbleDoc : public CDocument
#0024 {
#0025 DECLARE_DYNCREATE(CScribbleDoc)
#0026 virtual void Serialize(CArchive& ar);
#0027 DECLARE_MESSAGE_MAP()
#0028 };
#0029
#0030 class CScribbleView : public CView
#0031 {
#0032 DECLARE_DYNCREATE(CScribbleView)
#0033 CScribbleDoc* GetDocument();
#0034
#0035 virtual void OnDraw(CDC* pDC);
#0036 DECLARE_MESSAGE_MAP() // MFC 內部
#0037 };
Int AfxAPI AfxWinMain(!K)
#0038
{
#0039 class CAboutDlg : public CDialog
CWinApp* pApp = AfxGetApp();
#0040 {
AfxWinInit(!K);
#0041 DECLARE_MESSAGE_MAP()
pApp…》InitApplication();
#0042 };
#0043 pApp…》InitInstance();
nReturnCode = pApp…》Run();
#0044 //………………………………………………………………………………………………………………………………………………………………………………
#0045
}
#0046 CScribbleApp theApp;
#0047
#0048 BEGIN_MESSAGE_MAP(CScribbleApp; CWinApp)
#0049 ON_MAND(ID_APP_ABOUT; OnAppAbout)
#0050 ON_MAND(ID_FILE_NEW; CWinApp::OnFileNew)
#0051 ON_MAND(ID_FILE_OPEN; CWinApp::OnFileOpen)
#0052 ON_MAND(ID_FILE_PRINT_SETUP; CWinApp::OnFilePrintSetup)
#0053 END_MESSAGE_MAP()
#0054
#0055 BOOL CScribbleApp::InitInstance()
#0056 {
#0057 。。。
#0058 CMultiDocTemplate* pDocTemplate;
#0059 pDocTemplate = new CMultiDocTemplate(
#0060 IDR_SCRIBTYPE;
#0061 RUNTIME_CLASS(CScribbleDoc);
#0062 RUNTIME_CLASS(CChildFrame);
#0063 RUNTIME_CLASS(CScribbleView));
#0064 AddDocTemplate(pDocTemplate);
426
…………………………………………………………Page 489……………………………………………………………
第7章 簡單而完整:MFC 骨幹程式
#0065
#0066 CMainFrame* pMainFrame = new CMainFrame;
#0067 pMainFrame…》LoadFrame(IDR_MAINFRAME);
#0068 m_pMainWnd = pMainFrame;
#0069 ! K // MFC 內部
#0070 pMainFrame…》ShowWindow(m_nCmdShow); CFrameWnd::Create
#0071 pMainFrame…》UpdateWindow();
#0072 return TRUE;
#0073 } CWnd::CreateEx
#0074
#0075 BEGIN_MESSAGE_MAP(CAboutDlg; CDialog)
::CreateWindowEx
#0076 END_MESSAGE_MAP()
#0077
#0078 void CScribbleApp::OnAppAbout()
#0079 {
#0080 CAboutDlg aboutDlg;
#0081 aboutDlg。DoModal();
#0082 }
#0083
#0084 IMPLEMENT_DYNAMIC(CMainFrame; CMDIFrameWnd)
WM_CREATE
#0085
#0086 BEGIN_MESSAGE_MAP(CMainFrame; CMDIFrameWnd) wm_cre
#0087 ON_WM_CREATE()
#0088 END_MESSAGE_MAP()
#0089
#0090 static UINT indicators'' =
#0091 {
#0092 ID_SEPARATOR;
#0093 ID_INDICATOR_CAPS;
#0094 ID_IND