第1章 Visual C++ 编程基础

27
第1第 Visual C++ 第第第第 第第 Windows 第第第第 第第第第第第 第第 :、 第第 第第第第第第第第 第第 MFC 第第第第第第 第第第第第第第第第第第第第第第 第第 MFC 第第第第第第 教教教教 Visual C++ 第第第第 第第第第 ---- 第第第第

description

第1章 Visual C++ 编程基础. 教学目标. 了解 Windows 编程基础:消息和事件、资源管理、 设备独立性 等概念 了解 MFC 类的基础知识 熟练掌握用向导建立应用程序框架 明确 MFC 应用程序结构. 《Visual C++ 程序设计》电子教案----王明福编. 教学内容. 1.1 Windows 编程概念 1.2 MFC 基础 1.3 第一个 MFC 应用程序 1.4 应用程序分析. 返 回. 1.1 Windows 编程概念. - PowerPoint PPT Presentation

Transcript of 第1章 Visual C++ 编程基础

Page 1: 第1章   Visual C++ 编程基础

第 1章 Visual C++编程基础

了解 Windows编程基础:消息和事件、资源管理、设备独立性等概念

了解 MFC类的基础知识 熟练掌握用向导建立应用程序框

架 明确 MFC应用程序结构

教学目标

《 Visual C++程序设计》电子教案 ---- 王明福编

Page 2: 第1章   Visual C++ 编程基础

教学内容

1.1 Windows 编程概念

1.2 MFC基础

1.3 第一个MFC应用程序

1.4 应用程序分析

Page 3: 第1章   Visual C++ 编程基础

1.1 Windows编程概念 返 回

Windows 程序设计是基于事件驱动,程序的运行是由事件的发生来控制的。消息驱动机制是 Windows 程序设计的精髓。

1.1.1 事件与消息

当用户按下一个键、移动鼠标或单击鼠标按钮时,计算机通知 Windows系统已经发生了一个事件,以及事件的种类、发生的时间和发生的位置(如坐标值)。事件以如下三种方式产生:

● 通过输入设备,如键盘和鼠标,产生硬件事件。

● 通过屏幕上可视的对象,如菜单、工具栏按钮、滚动条和对话框上的控件。

● 来自 Windows 内部,例如,当一个后面的窗口显示到前面来。

Windows 消息是在 Windows.h 文件中用宏定义的常数。消息常数名通常为 WM_XXX ,例如, WM_WUIT 、 WM_CHAR 。

例如:当用户单击鼠标左键时,将发送 WM_LBUTTONDOWN 消息,而双击则发送 WM_LBUTTONDBLCLK 消息。

Page 4: 第1章   Visual C++ 编程基础

1.1.2 消息驱动 DOS 程序是由一系列预先定义好的操作序列的组合,具有一定的开头、中间过程和结束,也就是程序直接控制程序事件和过程的顺序。它的基本模型如图 1-1(a) 所示。

事件驱动的程序设计不是由事件的顺序来控制,而是由事件的发生来控制,而这种事件的发生是随机的、不确定的,并没有预定的顺序。

它在程序设计过程中除了完成所需功能之外,更多地考虑了用户的各种输入,并根据需要设计相应的处理程序。程序开始运行时,处于等待用户输入事件状态,然后取得事件并作出相应反应,处理完毕又返回并处于等待事件状态。如图 1-1(b) 所示。

Page 5: 第1章   Visual C++ 编程基础

1.1.3 消息响应函数 消息响应函数是用于处理特定消息的一些代码。例如,当用户点击某菜单项时,希望程序弹出一个口令对话框,那么,只要在相应的消息处理函数中编写弹出一个口令对话框的代码。

1.1.4 资源管理 程序员设计任何应用程序均将涉及到诸如菜单、对话框、消息框以及按钮等标准格式数据。 Windows 将这些数据保存在资源文件中,程序员可通过编辑工具编辑、修改这些资源文件,使其提供所需的菜单或按钮,并将其放入设计的程序之中。

1.1.5 设备独立性 设备独立性或称设备无关性。在编程时,程序员不必关心诸如打印机、鼠标、键盘、显示器、声卡、显示卡、 CDROM 等多种设备的类型及其驱动程序。 Windows95/98/2000 提供了图形设备接口之类的各种抽象接口,使得在程序中可以通过调用标准函数与硬件交互,这些函数通过设备环境的数据结构,由 Windows 操作系统将其映射到相应的物理设备,而程序员则无需了解其提供的操作设备的各种指令。

返 回

Page 6: 第1章   Visual C++ 编程基础

1.2 MFC基础 VC++ 已集成了 MFC 库, VC++ 资源编辑器、 AppWziard 和ClassWizard 明显降低了应用程序编码的时间。 AppWziard 为整个应用程序生成框架代码,同时 ClassWizard 为消息处理程序生成原型和函数体。

1.2.1 MFC 类库简介

MFC ( Microsoft Foundation Class )类库是用来编写 Windows 应用程序的C++ 类集,封装了大部分Windows API 函数,所以使用 MFC 类库和 VC++提供的高度可视化的应用程序开发工具,使开发变得简单。

MFC 类库包括 CObject 类及其派生类以及其他类。有这样一些重要的类(都是 CObject 的派生类):

● 应用程序类 CWinApp 。● CWnd 类及派生类。● CDocument 及其 派 生 类 。 ● File Services 。 ● Graphical Drawing 。 ● Graphical Drawing Objects 。● Menus 。● ODBC Database和 DAO Database Support 。● Internet Services 。等等。

返 回

Page 7: 第1章   Visual C++ 编程基础

1.2.2 MFC 应用程序框架 在 VC++6.0 中, MFC AppWizard 能方便地生成应用程序框架,然后在此基础上进行进一步的编辑工作。 MFC AppWizard 生成的应用程序包括这样一些要素 :

● WinMain 函数。 Windows 要求应用程序必须有一个 WinMain 函数,它隐藏在应用程序框架中。

● 应用程序类。也称 CMyHelloApp 。该类的每一个对象代表一个应用程序。程序中默认定义一个全局 CMyHelloApp 对象,即 theApp 。

● 应用程序启动。启动应用程序时, Windows 调用应用程序框架内置的WinMain 函数, WinMain寻找 CWinApp 由派生出的全局构造的应用程序对象。

● 成员函数 CMyHelloApp :: InitInstance 。当 WinMain 函数找到应用程序对象时,它调用伪成员函数 InitInstance ,这个成员函数调用所需的构造并显示应用程序的主框架窗口。必须在派生的应用程序类中重载InitInstance ,因为 CWinApp 基类不知道需要什么样的主框架窗口。

● 成员函数 CWinApp::Run 。函数 Run隐藏在基类中,但是它发送应用程序的消息到窗口,以保持应用程序的正常运行。在 WinMain 调用InitInstance 之后,便调用 Run 。

Page 8: 第1章   Visual C++ 编程基础

● CMainFrame 类。类 CMainFrame 的对象代表应用程序的主框架窗 口 。 当 构造函 数 调 用 基 类 CFrameWnd 的 成 员 函 数 Create时, Windows创建实际窗口结构,应用程序框架把它连接到 C++ 对象,函数 ShowWindows 和 UpdateWindow 也是基类的成员函数,必须调用它们类显示窗口。

● 文档与视图类。这一部分比较复杂,会在后面的章节中单独提出详细讲解。

● 关闭应用程序。如果用户通过关闭主框架窗口类关闭应用程序,这个操作就将激发一系列事件的发生,包括 CMainFrame 对象的析构、从Run 中退出、从WinMain 中退出和 CMyHelloApp 对象的折构。

Page 9: 第1章   Visual C++ 编程基础

1.2.3 MFC 消息映射及处理 在 MFC 中,管理消息的方式是:当发生某一个消息(比如用户移动了鼠标和按下键盘等)该消息进入消息队列,操作系统根据消息提供的信息决定由那个应用程序来处理,该应用程序依照一定的方式查找应用程序中各个类的消息映射(一组宏,这些宏用来确定某个消息及相应的处理程序的对应关系)找到处理程序,然后由处理程序执行。

MFC 程序要处理消息的种类如下:

● Windows 消息。以 WM_ 开头,但 WM_COMMAND 例外。通常由窗口和视图来处理。

● 由控件和其他子窗口发送给父窗口的 WM_COMMAND 消息。这些消息中包括 EN_CHANGE 通知码。如当用户在编辑框中键入文本或进行修改,就回向系统发送一个带 EN_CHANGE 通知码的 WM_COMMAND 消息。

● 来自于用户界面对象的 WM_COMMAND 消息,如表 1-1 所示。这些用户界面对象包括菜单、工具栏按钮和快捷键。系统在处理这些用户界面对象的消息和前面有所不同,我们来看看标准的处理方式。

返 回

Page 10: 第1章   Visual C++ 编程基础

1.2.4 程序的运行过程 如图 1-2 所示,当运行用户应用程序时,程序中的框架首先获得控制权,然后依次执行下述功能:

(1) 做部分初始化工作。

(2) 构造应用程序的唯一应用类的对象,构造应用类对象时要调用其构造函数。

(3) 调用 WinMain() 函数(此函数也隐藏在应用框架内部)。

(4) 从 WinMain() 函数返回后,删除应用程序的唯一应用类的对象,删除时要调用其析构函数。

(5) 终止应用程序。

(6) 进行退出应用程序前的收尾工作,如删除注册的窗口类并释放其内存等。

(7) 返回

返 回

Page 11: 第1章   Visual C++ 编程基础

1.3 第一个 MFC应用程序

用 VC++ 编写 MFC 应用程序,是一种“填空式”的编程方法,一般有三个步骤:

(1) 创建工程:用 V C++ 的 MFC AppWizard 生成应用程序的工程文件,即应用程序的基本框架。 (2) 可 视化设 计 : 用 VC++ 自带的 工 具软件Winzards ,制作 Windows 风格的图形用户界面和各种控件。 (3) 编写代码:用 MFC ClassWizard 添加消息响应函数,然后 VC++提供的文本编辑器和 C++程序设计语言在函数中编写代码。

返 回

Page 12: 第1章   Visual C++ 编程基础

1.3.1 MyHello 应用程序 例 程 MyHello.exe 运 行 结果如 下 图 所 示 。主窗 口 显 示字符串:“ Hello ,我们开始 Visual C++ 编程了!”。

MyHello 程序由以下两步完成:

(1) 用 VC++6.0 的 MFC AppWizard ,创建应用程序的基本窗口框架。

(2) 编写显示字符串:“ Hello ,我们开始 Visual C++ 编程了!”的代码。

Page 13: 第1章   Visual C++ 编程基础

(1) 启动 VC++ ,从“ File” 菜单中选择“ New” ;

(2) 在 New 对 话 框 中 选 择 “ Project” 标 签 , 选 择 “ MFC AppWizard(exe)” 类型,告诉 VC++ 即将创建一个 EXE 程序。

(3) 在 “ Project name” 文 本 编 辑 框 中 输 入 “ MyHello” , 单 击 位于“ Location” 框右边的小按钮,再从下拉的对话框中选择“ D:\MYVC” 目录,使新创建的工程文件放置在“ D:\MYVC” 目录之下。

(分别指定了 MyHello.exe 程序的工程类型、工程名字和工程位置)

1.3.2 创建工程

Page 14: 第1章   Visual C++ 编程基础

(4) 单击“ OK”按钮。此时 Visual C++ 将显示 MFC AppWizard-Step 1 对话框。

(5)在 MFC AppWizard-Step 1 对话框中:

● Single Document选项表示单文档界面,简称 SDI ,这种类型应用程的主窗口只能容纳一个文档,如 Windows 自带的记事本。

● Multiple documents选项表示多文档界面,简称 MDI ,这种类型应用程容许同时打开多个文档,这些文档可以层叠于主窗口。 Microsoft Office产品就属于 MDI 应用程。

● Dialog based选项表示生成基于对话框的应用程序。

在本例中选择“ Single Document” ,创建一个基于单文档界面的应用程序。然后选择资源语言。

Page 15: 第1章   Visual C++ 编程基础

(6) 单击“ Finish” 按钮,结束 MFC AppWizard 的设计工作,此时Vc++ 将显示 New Project Information 窗口,显示前六步所做的选择的汇总信息。

(7) 单击“ OK” 。 VC++ 就创建了 MyHello 工程以及相关的所有文件。

Page 16: 第1章   Visual C++ 编程基础

1.3.3 编写程序代码

用 VC++ 编写 MFC 应用程序,是一种“填空式”的编程方法,因为在利用 MFC AppWizard 生成框架程序,使得程序员免去了大量模式化工作,我们只要根据目标程序的要求,看哪些地方需要修改,再往里填写代码。

在 Workspase 窗 口 的 FileView 标签( 工 程 资 源管理 器 ) 中选择MyHelloView.cpp 文 件 双 击 打 开 , 然 后找到 函 数 OnDraw(CDC* pDC) ,在其中添加显示字符串: "Hello, 我们开始 Visual C++ 编程了! "代码。

void CMyHelloView::OnDraw(CDC* pDC)

{ CMyHelloDoc* pDoc = GetDocument();

ASSERT_VALID(pDoc);

// TODO: add draw code for native data here

pDC->TextOut(100,80,"Hello, 我 们 开 始 Visual C++ 编 程了! ");

}

Page 17: 第1章   Visual C++ 编程基础

1.3.4 编译运行 MyHello 应用程序

编译、连接运行的操作步骤如下:

(1) 如下图所示,选择“ Build” 菜单中的“ Build MyHello.exe” 菜单项, VC++ 就会编译并连接成 MyHello.exe 程序。

(2) 选择“ Build” 菜单中的“ Execute MyHello.exe” 菜单项 , VC++就会执行 MyHello.exe 程序, MyHello.exe 程序主窗口也随之出现。

Page 18: 第1章   Visual C++ 编程基础

1.4 应用程序分析 返 回

用 MFC AppWizard 来帮助生成程序时, MFC 类做了很多工作,使用户很容易地就能够编写一个程序。 打开 Workspace 窗口中的 ClassView( 类视图 ) 标签,我们看到 MFC 生成了 5 个类,如图 1-13 所示。● CAboutDlg

● CMainFrame

● CMyHelloApp

● CMyHelloDoc

● CMyHelloView

对应每一个类 MFC Wizard 为我们生成了两个文件,分别以 .h 和 .cpp 结尾,在 ..h 文件中 MFC Wizard 定义了类和它的各种变量、函数,在 .cpp 文件中来生成类对象,实现这个类。

Page 19: 第1章   Visual C++ 编程基础

1.4.1 应用类CMyHelloApp

返 回

• 应用类 CMyHelloApp派生于 MFC中的 CWinApp类 • 其作用是初始化应用程序及运行该应用程序所需要的成员函数,而 CWinApp 类派生于 CWinThread 类,代表了程序中运行的主线程,它就是运行程序的本身,所以每一个基于 MFC创建的应用程序只能包含该类唯一的派生类对象。 MyHello.h 是应用程序的主头文件,它声明了CMyHelloApp类,其中: • 虚函数 InitInstance() 的作用是:设置注册数据库,载入标准设置(最近打开文件列表等)、注册文档模板并隐含地创建了主窗口、处理命令行参数和显示窗口,然后返回、进入消息循环。 CMyHelloApp类的完整代码如下:

Page 20: 第1章   Visual C++ 编程基础

class CMyHelloApp : public CWinApp{public:

CMyHelloApp(); // Overrides

// ClassWizard generated virtual function overrides//{{AFX_VIRTUAL(CMyHelloApp)public:virtual BOOL InitInstance();//}}AFX_VIRTUAL

// Implementation//{{AFX_MSG(CMyHelloApp)afx_msg void OnAppAbout();// NOTE - the ClassWizard will add and remove member functions

here.// DO NOT EDIT what you see in these blocks of generated code !//}}AFX_MSGDECLARE_MESSAGE_MAP()

};

Page 21: 第1章   Visual C++ 编程基础

1.4. 2 主框架窗口类CMainFrame

返 回

• 窗口类 CMainFrame派生于 CFrameWnd

• 主要用来管理应用程序的窗口,显示标题栏、工具栏、状态栏等。同时还要处理针对窗口操作的消息。

在窗口类 CMainFrame 中有:

• 两个主要函数 PreCreateWindow 和 OnCreate

• 两 个 对 象 m_wndStatusBar ( 属 于 状 态 栏 类CStatusBar , 用 于创建管理 状 态 栏 ) 和 m_wndToolBar(属于工具栏类 CToolBar ,用于创建管理工具栏)。

类 CMainFrame 在 MainFrm.h 中定义,完整的代码如下:

Page 22: 第1章   Visual C++ 编程基础

class CMainFrame : public CFrameWnd{protected: // create from serialization only

CMainFrame();DECLARE_DYNCREATE(CMainFrame)

……//{{AFX_VIRTUAL(CMainFrame)virtual BOOL PreCreateWindow(CREATESTRUCT& cs);//}}AFX_VIRTUAL

…… protected: // control bar embedded members

CStatusBar m_wndStatusBar;CToolBar m_wndToolBar;

protected://{{AFX_MSG(CMainFrame)afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);//NOTE - the ClassWizard will add and remove member

functions here.// DO NOT EDIT what you see in these blocks of generated

code!//}}AFX_MSGDECLARE_MESSAGE_MAP()

};

Page 23: 第1章   Visual C++ 编程基础

1.4.3 文档类CMyHelloDoc

返 回

• 文档类 CMyHelloDoc派生于 CDocument 类。

• 主要用来存放应用程序的数据,以及文件的保存加载功能,文档类要通过与视图类来实现与用户的交互。

在文档类 CMyHelloDoc 中:

• 声明的 OnNewDocument 函数用于初始化文档, Serialize 函数串行化 ( 保存和装入 ) 文档, Dump 函数用于调试诊断。

文档类类 CMyHelloDoc 的详细代码如下:

Page 24: 第1章   Visual C++ 编程基础

class CMyHelloDoc : public CDocument{protected: // create from serialization only

CMyHelloDoc();DECLARE_DYNCREATE(CMyHelloDoc)

…… // ClassWizard generated virtual function overrides//{{AFX_VIRTUAL(CMyHelloDoc)public:virtual BOOL OnNewDocument();virtual void Serialize(CArchive& ar);//}}AFX_VIRTUAL

 // Implementationpublic:

virtual ~CMyHelloDoc();#ifdef _DEBUG

virtual void AssertValid() const;virtual void Dump(CDumpContext& dc) const;

#endif …… 

DECLARE_MESSAGE_MAP()};

Page 25: 第1章   Visual C++ 编程基础

1.4.4 视图类CMyHelloView

返 回

• 视图类 CMyHelloView派生于 CView 类

• 视图类用于管理视图窗口,它对应的对象在框架窗口中实现用户数据的显示和打印。

在视图类 CMyHelloView 中有:

• 与 文 档 数 据 相 关 的 三 个 函 数OnPreparePrinting 、 OnBeginPrintting 和 OnEndPrinting , 用 以实现数 据 打 印;声 明 了 返 回 CMYhelloDoc 指针的 函 数GetDocument 用以获取文档的指针,以实现对用户文档的数据的操作;声明了函数 OnDraw ,用以实现视图数据的显示和刷新。

视图类 CMyHelloView 的详细代码如下:

Page 26: 第1章   Visual C++ 编程基础

class CMyHelloView : public CView{protected: // create from serialization only

CMyHelloView();DECLARE_DYNCREATE(CMyHelloView)

 public:CMyHelloDoc* GetDocument();

 // Operationspublic:  //{{AFX_VIRTUAL(CMyHelloView)

public:virtual void OnDraw(CDC* pDC); // overridden to draw this viewvirtual BOOL PreCreateWindow(CREATESTRUCT& cs);protected:virtual BOOL OnPreparePrinting(CPrintInfo* pInfo);virtual void OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo);virtual void OnEndPrinting(CDC* pDC, CPrintInfo* pInfo);//}}AFX_VIRTUAL

 ……DECLARE_MESSAGE_MAP()

};

Page 27: 第1章   Visual C++ 编程基础

返 回

1 . Windows 程序设计的特点是什么?

2 . Windows 应用程序的优点是什么?

3. MFC AppWizard( 应用向导 ) 可以创建哪几类应用程序?各有何特点?

4. 请用 MFC AppWizard 创建一个基于对话框的应用程序,列出所创建的类,并与 MyHello 工程比较,观察他们的异同。

习 题