Visual C++ 程序设计

Preview:

DESCRIPTION

Visual C++ 程序设计. 网络技术学院 梁普选. 教学目的. 掌握可视化与面向对象的编程模式 掌握 Windows 平台下软件运作机制及其开发方法. 教学安排. 总学时 (60) = 理论 (40) + 实验 (20). 教学参考书. [1] 马安鹏 《Visual C++ 6 程序设计导学 》 清华大学出版社 [2] 潘爱民译 《Visual C++ 技术内幕 》 清华大学出版社 [3] 侯俊杰 《 深入浅出 MFC》 华中科技大学出版社 - PowerPoint PPT Presentation

Citation preview

网络技术学院

梁普选

Visual C++ 程序设计

1.掌握可视化与面向对象的编程模式

2.掌握 Windows 平台下软件运作机制及其开发方法

教学目的

总学时 (60) = 理论 (40) + 实验 (20)

教学安排

教学参考书

[1] 马安鹏《 Visual C++ 6 程序设计导学》 清华大学出版社

[2] 潘爱民译《 Visual C++ 技术内幕》 清华大学出版社

[3] 侯俊杰 《深入浅出 MFC 》 华中科技大学出版社

[4] 许福《 Visual C++ 6 编程实例与技巧》 电子工业出版社

学习方法学习方法

听课看书为先导;听课看书为先导;实践环节紧配合;实践环节紧配合; 输入一段程序;编译并投入运行;将运行输入一段程序;编译并投入运行;将运行过程;运行结果;源代码与书本知识联系在过程;运行结果;源代码与书本知识联系在一起。一起。 分析总结才能领会软件开发真谛。分析总结才能领会软件开发真谛。

[1] 微软基础类库 MFC 与应用程序框架[2] 对话框与控件编程[3] [3] 文档视图与框架窗口文档视图与框架窗口[4] 绘图[5] 数据库编程[6] 多线程编程[7] 网络编程

教学内容

第第 11 讲 讲 C++C++ 基础基础1.1 1.1 类与对象类与对象

1.2 1.2 数据成员与成员函数数据成员与成员函数

1.3 1.3 构造函数与析构函数构造函数与析构函数

1.4 1.4 基类与派生类基类与派生类

1.5 1.5 单继承与多继承单继承与多继承

1.6 1.6 函数重载与多态性函数重载与多态性

第 2 讲MFC 与应用程序框架

2.1 微软基础类库 MFC

积微软程序员 30 余年的心血-

Windows 平台下的几十万行优化的 C++ 代码、类库的集合,其中主要包含了开发 Windows 平台所需的软件资源。

微软基础类库 MFC

CDocument

CObject

CCmdTarget

CWinThread

CWinApp

COleControlModule

Application

user documentCDocTemplate

CSingleDocTemplateCMultiDocTemplate

CView

CWnd

CFrameView

2.2 Visual C++ 集成开发环境

1. 内嵌 MFC

2. 优质高效的 C++ 编译器3. 可视化集成开发环境4. 得心应手的软件开发工具 (1) 应用程序向导 AppWizard

(2) 类向导工具 ClassWizard

Visual C++ 开发实例

实例: 创建基于对话框的应用程序实例: 创建基于对话框的应用程序功能: 鼠标单击“按钮”,文本框输出功能: 鼠标单击“按钮”,文本框输出

字 符串:“字 符串:“ Hello VC++!” Hello VC++!” 掌握要点:掌握要点: AppWizard AppWizard 和 和 ClassWizaClassWiza

rdrd 的使用的使用

2.3 一个简单的一个简单的 MFCMFC 程序程序

创建窗体创建窗体 (P1)(P1)

1. 1. 定义应用类 定义应用类 CHelloAppCHelloApp

2. 2. 创建应用类对象创建应用类对象 (( 实例实例 ) HelloAp) HelloAp

pp

3. 3. 定义窗口类 定义窗口类 CHelloWindowCHelloWindow

4. 4. 实现应用类初始化函数 实现应用类初始化函数 InitInstance()InitInstance()

5. 5. 实现窗口类构造函数 实现窗口类构造函数

源代码分析:源代码分析:#include < afxwin.h > 作用:将 MFC 类库包含并加载到当前程序中

class CHelloApp : public CWinApp { public: virtual BOOL InitInstance();}; 主应用类 CHelloApp 派生自 CWinAp ,并重写初始化成员函数 InitInstance() 。

CHelloApp HelloApp; 创建主应用类对象class CHelloWindow : public CFrameWnd{ public: CHelloWindow();}; 定义主窗口类 CHelloWindow ,派生自MFC 中的 CFrameWnd 。主窗口类中声明了自己的构造函数。

BOOL CHelloApp::InitInstance() {m_pMainWnd = new CHelloWindow();m_pMainWnd->ShowWindow (m_nCmdShow);m_pMainWnd->UpdateWindow();return TRUE;} m_pMainWnd 是 MFC 中定义的主窗口指针 ; 主窗口指针指向了当前应用程序窗口; 因而调用主窗口指针的 ShowWindow 函数, 就是显示当前应用程序。

CHelloWindow::CHelloWindow() { Create(NULL,"Hello World!",WS_OVERLAPPEDWINDOW,CRect(0,0,200,200)); } 构造函数中,创建主窗口标题为“”,大小尺寸为 200×200 ;窗口格式为可覆盖、有控制按钮。

向当前窗口中添加标签

实现过程见 P4

2.4 2.4 消息映射消息映射

应用程序窗口中的用户界面对象都具有两种可控制特性: 外观及它响应事件行为的能力。 例如:当鼠标单击【退出】按钮时,应用程序就要结束;当鼠标选择【打开文件】菜单时,弹出文件打开对话框。 消息映射作用: 识别源于系统内部或用户干预应用程序的消息,调用相应的函数实现用户实现的功能

实现步骤

1.声明消息映射宏

DECLARE_MESSAGE_MAP()

2. 创建消息映射宏 BEGIN_MESSAGE_MAP()

END_MESSAGE_MAP()

消息映射宏定义在 MFC 中,是 Windows应用程序的消息处理过程的入口

3. 定义响应消息的成员函数

( 声明在先定义在后 P8)

4. 添加消息入口项

例如:将鼠标单击消息与响应该消息的成员函数建立关联。

见 P8

5. 创建消息驱动源-控件

见 P8

实例:鼠标单击按钮,弹出消息框。实例:鼠标单击按钮,弹出消息框。P9P9

定义按钮标识符资源定义按钮标识符资源#define IDB_BUTTON 100#define IDB_BUTTON 100

声明响应鼠标单击消息的成员函数声明响应鼠标单击消息的成员函数afx_msg void HandleButton();afx_msg void HandleButton();

响应鼠标单击消息的成员函数响应鼠标单击消息的成员函数void CButtonWindow::HandleButton()void CButtonWindow::HandleButton()

{{

AfxMessageBox("Hello, Your Clicked AfxMessageBox("Hello, Your Clicked

Button1"); Button1");

}}

声明消息映射宏声明消息映射宏DECLARE_MESSAGE_MAP() DECLARE_MESSAGE_MAP()

定义消息映射宏定义消息映射宏BEGIN_MESSAGE_MAP(CButtonWindow, CFrameWBEGIN_MESSAGE_MAP(CButtonWindow, CFrameWnd)nd)

ON_BN_CLICKED(ON_BN_CLICKED(IDB_BUTTONIDB_BUTTON, , HandleButtonHandleButton) ) END_MESSAGE_MAP()END_MESSAGE_MAP()

创建按钮控件创建按钮控件CButton *button;CButton *button;button = new CButton();button = new CButton();

button->Create("Push me",WS_CHILD|WS_VISbutton->Create("Push me",WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON, r, this, IDB_BUTTON);IBLE|BS_PUSHBUTTON, r, this, IDB_BUTTON);

2.5 Win32 2.5 Win32 应用程序向导应用程序向导 AppWizardAppWizard 创建基于创建基于 MFCMFC 的三种不同类的三种不同类型的型的 Win32 Win32 应用程序。应用程序。 Win32 Win32 应用程序框架结构共性应用程序框架结构共性 主应用类;主应用类实例;主框架主应用类;主应用类实例;主框架 ((窗窗口口 ))类,文档类,视图类,各司其职。类,文档类,视图类,各司其职。

作用: (1) 创建用户自定义类;(2) 添加 /删除成员变量;(3) 添加 /删除成员函数;(4) 添加自定义消息及消息映射项;(5) 导入组件库; 要求熟练掌握

2.6 使用类向导 ClassWizard

一、设计阶段(1)提出设计目标及用户需求(2)确定拟采用的技术方案(3)划分功能模块(4)提取模块原型-创建设计模型

2.7 设计 Windows 应用程序一般流程

二、编码阶段(1)细化模块流程(2)攻克技术难点(3)界面设计(4) 代码设计(5) 代码调试

三、调试阶段 (1) 分步调试(2) 模块连调(3) 数据测试(4) 打包发布

四、用户反馈(1)修改(2)测试

2.8 Visual C++常用工具的使用1.属性对话框 用于设置控件及对话框的属性

2. 控件常用属性(1) ID:控件标识符,是该控件在程序中

的符号化的表示。 例如:文本框控件标识符: IDC_EDIT1 按钮控件标识符: IDC_BUTTON1(2) Caption: 控件标题,表示显示在控

件表面的字符串信息。 例如:静态文本控件的 Caption设置为

“姓名”,则显示:

3.ClassWizard 类向导工具(1)用于设置控件所表示的信息(2)实现对源程序编辑、修改。3.1 打开类向导的操作方法:(1)选中操作目标(2)Ctrl+W 例如:为 IDC_EDIT1添加变量m_Edit1,具体方法:选中对话框界面中的文本编辑框 IDC_EDIT1,出现下列界面:

接着按“添加成员变量”按钮,出现:

在源程序中呈现:

// Dialog Data//{{AFX_DATA(CXxxDlg)enum { IDD = IDD_XXX_DIALOG };

CEdit m_Edit1;//}}AFX_DATA

添加鼠标单击按钮消息,并用 OnButton1函数来响应用户鼠标的单击事件。void CXxxDlg::OnButton1() {

CString temp;m_Edit1.GetWindowText(temp);if(temp=="1234567")

MessageBox(" 口令正确 !");else

MessageBox(" 口令不正确 !");}

实例:向文本框 IDC_EDIT1中输入文本,当输入空格时将文本框内容添加到列表框中。(1)添加列表框 IDC_LIST1(2)为其设置成员变量m_List1(3)添加文本框内容改变的事件void CXxxDlg::OnChangeEdit1() { }

void CXxxDlg::OnChangeEdit1() {

CString temp;m_Edit1.GetWindowText(temp);if(temp.Right(1)==‘ '){

m_Edit1.SetWindowText("");m_List1.AddString(temp);

}}

3.1 模态对话框与非模态对话框1. 模态对话框 只有结束对话框的操作,才能进行其他的操作。

消息框是模态对话框int MessageBox{ HWND hWnd, //父级窗口句柄 LPCTSTR lpText, // 指向信息字符串的指针 LPCTSTR lpCaption, // 指向消息对话框标题的字

符串 UINT uType // 消息对话框的格式};

例如 : (详见 P35)

MessageBox(

NULL,

“ 设置是否合理?”,

“请选择” ,

MB_ICONWARNING+MB_YESNO+

MB_DEFBUTTON2

);

2. 创建模态对话框(P36~ P52)

(1) 添加对话框窗体界面(资源)包括控件

(2) 为对话框资源添加编程框架-添加对话框界面的类

(3) 创建与控件相关的变量

(4) 为控件添加消息函数

(5) 加载模态对话框

3. 非模态对话框

非模态对话框工作期间,可与其他窗体、控件交互。

例如: Word 中的“查找 /替换”对话框 Excel 中的图标向导对话框 …

4. 创建非模态对话框 (P53~ P57)

(1)添加对话框界面资源

(2)为对话框资源配置新的对话框派生类

(3)定义非模态对话框类指针

(4)初始化非模态对话框类指针

(5)实例化并创建非模态对话框

(6)加载并显示非模态对话框

3.2 通用对话框 MFC提供一组标准库支持通用对话框操作,它们分别为:

类 用途

CColorDialog 允许用户选择或创建颜色

CFileDialog 允许用户打开或保存一个文件

CFindReplaceDialog 允许用户用一个字符串替换文本中另一个字符串

CPageSetupDialog 允许用户输入页面参数

CFontDialog 允许用户从列出的字体中选择一种字体

CPrintDialog 允许用户设置打印机并打印文档

通用对话框的应用 (P57)

(1)向 VC 工程中添加通用对话框类

(2)在响应消息的成员函数中

加载通用对话框;

打开并显示通用对话框; 实现通用对话框的操作。

3.3 对话框集合 对话框集合是多个模态对话框的集合,单击标签可切换不同的对话框页面进行操作。 属性对话框是一种对话框集合模板,通常包含: 一个 CPropertySheet 类(或派生类)对象多个 CPropertyPage 类 (或其派生类 ) 的对象

创建属性页对话框 (P64)

(1) 打开 MFC 中的组件库

(2) 添加属性页对话框

(3) 给属性页对话框选择一个归宿

(4) 选择属性页对话框页面数

(5) 向指定类中添加成员函数,响应属性页对话框

3.4 使用控件控件是窗体中的基本元素,接收用户输入显示用户信息,实现了人机交互功能。1. 常用的控件类:CButton,CEdit, CComboBox;

CTree, CList

CPicture, CProgressCtrl

2. 控件的编程方法(1)向对话框中添加控件(2)为控件设置属性 (ID 标识符 )

(3)添加响应控件消息的成员函数(4)向消息函数中添加代码(5)运行并调试程序

3. 对话框综合实例 (P87)

第 4 讲 文档与视图

4.1 文档 - 视图结构 创建基于 MFC 的 Win 32 应用程序框架中包含:文档类 : 派生自 CDocument 类视图类 : 派生自 CView 类主框架类:派生自 CFrameWnd 类

4.2 用户数据的三种形态文档类:用于用户数据的组织和保存视图类:与界面结合,接受并显示数据主框架类:将文档 / 视图类组装在窗体中

(1) 文档数据:定义在文档类中,体现了用户 数据结

构(2) 界面数据:定义在视类或视窗框架类中,

这些数据与用户交互

(3) 数据串行化:利用串行化机制,将用户数 据驻留磁盘

4.3 文档 / 视图中的数据流层

视图数据

文档数据

串行化数据

图形用户界面

磁盘

主框架类( CFrame)

视图类 (CView)1. 接受用户输入2. 显示用户数据

文档类 (CDocument)1. 缓冲用户数据 (驻留内存 )2.永久驻留用户数据

用户自定义类存储用户数据结构、定义操作方法及相应的处理消息。

标题栏、菜单栏、工具栏、状态栏 (接收消息 )

4.4 用户数据的组织 (P107)

1. 基本思路:

以面向对象的思维模式将用户数据结构化,以类的形式将其封装。

在类定义中,数据成员体现了对象的基本特征属性,成员函数体现了数据操作方法。

例如:定义通信录数据结构

通信录类中应包含与通信录相关的数据成员; 包含与通信录相关成员函数,体现基本操作。

2.实现方法(1) 向当前工程 ( 单文档 ) 中添加新类(2) 向该类中添加数据成员(3) 修改构造函数及析构函数(4) 添加其他的成员函数示例: P108 例 3-1

要求:熟练掌握 ClassWizard 的用法

3. 用户数据结构在文档类中的体现

文档类中管理用户数据的方案

(1) 定义用户数据类的对象数组

(2) 定义用户数据类的动态数组结构

(3) 定义用户数据类的动态链表

(4) 定义用户数据类的键值对 (哈希表 )

4. 定义用户数据类的对象数组具体方法:

在文档类头文件中包含用户数据类;

在文档类头文件中定义用户数据类的对象

数组 (P112)

4.5 创建用户界面交互平台 (P112)

设计思路(1)向界面中添加必须的控件(2)设置各控件属性(3)为每个控件配置成员变量 ( 添加到视图类 )

(4)用数据交换机制实现文档数据与视图数据的交换。

设计要点

• 在视图类中获取文档类指针 ×××Doc* pDoc = GetDocument();

(2) 数据交换 将视图类的用户数据向界面显示输出UpdateData(FALSE);

将界面数据保存到视图类的成员变量UpdateData(TRUE);

示例: P112~ P118

实现学生成绩的输入,存储及其浏览

4.6 用户数据的存储 (P118)1. 用户数据的持久性

文档类中的用户数据结构

磁盘缓存: CArchive& ar

磁盘:永久性存储介质

文档类中对象的成员函数 Serialize(ar)

用户类中的成员函数 Serialize(ar)

2. 串行化机制 MFC 中的串行化指的是将内存数据作为数据流,与永久性存储设备交互的一种操作机制。串行化被定义在 MFC 中,是实现用户数据长期保存的一种技术措施。

3. 实现步骤 (P119)(1) 向用户数据类的头文件中添加串行化函

数原型(2) 在用户数据类的实现文件中添加串行化操作

(3) 在文档类的串行化函数中实现对用户数据类对象数组的序列化操作 (P120)

4. 示例 (P119~ P120)

4.7 使用集合类

集合类实现对用户数据的有效管理 (P124)

(1) 动态数组 CArray

(2) 动态链表 CList

(3) 哈希映射表 CMap

1. 集合类特点

CArray 提供一个大小可根据实际使用调整的有序动态数组

CList 提供一个有序的非索引的双向链表CMap 是一个键值对的集合,适合高效检

2. 模板类集合

模板集合类提供了较好的类型安全性,即使用模板类创建类型安全的集合类 。

数组 链表 映射

非模板类 CArray CList CMap

模板类 CTypedPtrArray CTypedPtrList CTypedPtrMap

3. 3. 链式存储用户数据链式存储用户数据 (P127)(P127)

(1) (1) 向标准预编译头文件中添加模板类库向标准预编译头文件中添加模板类库 #include <afxtempl.h>#include <afxtempl.h>

(2) (2) 在文档类头文件中定义模板链表类对象在文档类头文件中定义模板链表类对象CTypedPtrList<CObList, CStudent> CTypedPtrList<CObList, CStudent>

m_Student;m_Student;

(3)(3) 在视图类实现文件中实现用户数据的链在视图类实现文件中实现用户数据的链式存储式存储

4. 示例 (P128~131)

关键提示:

定义 POSITION 实例变量,获取链表头节点,尾节点及当前节点的位置 ( 指针 )

例如:

POSITION p1,p2;

p1=pDoc->m_Student.getHeadPosition();

实例:映射表的使用 (P134~P138)

4.8 4.8 用户数据类的消息映射用户数据类的消息映射 为了使用户数据类能直接响应外部消息,为了使用户数据类能直接响应外部消息,需要在文档类需要在文档类 // 视图类的消息路由中添加用视图类的消息路由中添加用户数据类对象。户数据类对象。

具体方法:具体方法: (P141~P143)(P141~P143)

4.10 综合实例(P140~P160)

第 5 讲 文档 / 视图类的结合5.1 视图类 为了体现多种不同的视图效果, MFC提供了视图模板供使用。 实现方法 ( P164)

类名 描述CScrollView 提供自动滚动或缩放功能CFormView 由对话框模板创建,提供可滚动的视图CRecordView 提供表单视图,直接与 ODBC记录集对象关联,基于对话框模板

设计CDaoRecordView

提供表单视图,直接与 Dao记录集对象关联,也是基于对话框模板设计

CCtrlView 是 CEditView,CListView,CTreeView和 CRichEditView的基类,它所提供的文档、视图结构同样适于 Windows NT中的新控件

CEditView 提供包含编辑控件的视图,支持文本的编辑、查找、替换及滚动等功能

CRichEditView 提供富文本编辑控件的视图,除了包含 CEditView功能之外,还支持字体等功能

CListView 提供包含列表控件的视图,类似于 Windows 资源管理器的右侧窗口

CTreeView 提供包含树状控件的视图,类似于 Windows 资源管理器的左侧窗口

5.2 文档视图类间起作用的成员函数

1. CView::GetDocument()

函数原型×××Doc* ×××View::GetDocument()

{

ASSERT(m_pDocument

->IsKindOf(RUNTIME_CLASS(CSZGLDoc)));

return (×××Doc*)m_pDocument;

}

作用:

在视图类中获得与其关联的文档类指针,意味在视图类中获取对文档数据 ( 用户数据 ) 直接访问的权利。

例如: P115

2. UpdateAllViews() 函数

函数原型: void UpdateAllViews( CView* pSender, LPARAM lHint = 0L, CObject* pHint = NULL );

参数说明:lHint 是一个 32位整数,其中包含关于文档被修改的信息pHint 是一个指向存储被更改对象信息的指针。pSender 指向与数据已发生改变的文档相关联的视图。

作用:文档类发出 UpdateAllView() 消息,

通知与该文档有关的所有视图更新界面显示,

保持内部数据与外观显示的一致性。

例如:pDoc->UpdateAllViews(NULL,0,NULL);

第 1 个参数为 NULL ,表示通知所有的视图需要

更新界面显示。更新的依据是文档数据发生了认为

的改变

3. CView::OnUpdate 函数函数原型:virtual void OnUpdate(CView* pSender, LP

ARAM lHint, CObject* pHint);

我们发现, OnUpdate 函数的参数与 UpdateAl

lView 函数的参数完全一致。的确如此,当文档类数据发生变化而调用更新视图函数,产生了更新视图的消息。该消息立即通知视图中的成员函数 OnUpdate 来响应更新视图的消息

文档数据被

更新

UpdateA

llView

s

View1

View2

ViewN-1

ViewN

.......

.......

OnUpdate

OnUpdate

OnUpdate

OnUpdate

结论:OnUpdate 函数中应添加数据显

示和刷新操作代码。 (P167)

4. CView::OnDraw 函数

函数原型: 函数原型: virtual void OnDraw( CDC* pDC ) = 0;

参数说明: pDC 指向文档数据映象的设备环境

指针。

注意:可由用户调用刷新界面显示;

更多的是当产生重绘消息 PAINT() 时,

由系统调用。

示例:示例: P166~P168P166~P168

示例:示例: P169~P176P169~P176

第 6 讲 Windows 绘图

6.1 6.1 与绘图相关的术语与绘图相关的术语

(1)(1)图形设备接口图形设备接口 GDIGDI

Graphics Device Interface 是 Windows 的

系统,负责在显示器和打印机上显示图形。

(2) (2) Window 设备无关性 Windows 图形主要由 GDI32.DLL 动态连结库输出的函数来处理,库函数由 GDI.EXE执行。 动态连结库调用用户安装的显示器或打印机驱动程序。显示器驱动程序访问显示器的视频显示卡,打印机驱动程序将 GDI命令转换为各种打印机理解的代码或者命令。显然,不同的显示卡和打印机要求不同的设备驱动程序 因而 Windows 中的绘图命令在不同的输出设备得到相同的结果。

(3)(3)窗口窗口刷新当发生窗口大小的调整,窗口的移动或

窗口被其他对象覆盖等情况后,都必须刷新窗口用户区的内容,以恢复用户区内原有的显示内容。 但Windows 系统并不总是记录窗口中需保存的内容,系统只能在有限几种情况下自动刷新。因此应用程序必须具有及时处理刷新请求和刷新图形的功能。 Windows 系统发送WM_PAINT 消息,将刷新请求传递给应用程序。

窗口移动后的刷新系统发送WM_PAINT 消息,由消息处理函数完成刷新。被覆盖区域的刷新 Windows 系统视图保存被覆盖区的副本,以备以后刷新。如果不能有效刷新,则向应用程序发送WM_PAINT 消息。对象穿越后的刷新 此时系统自动完成刷新任务。 窗口改变大小后系统发出 WM_SIZE 消息,由消息处理函数完成相应处理。

(4)(4) 设备环境-设备描述表设备环境-设备描述表 设备环境由设备环境由 CDCCDC 类及派生类描述,类及派生类描述, CCDCDC 类相当于作图的画布,提供绘图的场类相当于作图的画布,提供绘图的场地和基本素材(参数)地和基本素材(参数)

6.2 绘图坐标分为两种情况:

(1) 窗口客户区的缺省坐标

(2) 设备环境的逻辑坐标和窗口的物理坐标

(3) 坐标映射

(1)窗口客户区

( 0, 0) cxClient

cyClient

(2) 设备环境的逻辑坐标和物理坐标 如果要把一幅大小为如果要把一幅大小为 400*800mm400*800mm 的的图画画在图画画在 500*200500*200像素的像素的 WindowsWindows 窗口窗口中,则我们把中,则我们把 400*800mm400*800mm叫做叫做逻辑坐标逻辑坐标,,把把 WindowsWindows 窗口大小窗口大小 500*200500*200像素称作像素称作设备坐标设备坐标。。 如果在指定的一个窗体界面上画出 10×10 的网格,则该窗体的工作区实际宽度和高度就是设备坐标,而 10×10 的网格所参照的坐标系为逻辑坐标。

(3) 坐标映射 把 400×800mm400×800mm 的图画绘制在宽和高分的图画绘制在宽和高分别为别为 500×200500×200 的象素中,需要逻辑坐标向的象素中,需要逻辑坐标向物理坐标的投影,称为坐标映射。物理坐标的投影,称为坐标映射。 同样把同样把 10×1010×10 的网格线恰好画在指定的的网格线恰好画在指定的控件界面中,同样需要逻辑坐标和物理坐标控件界面中,同样需要逻辑坐标和物理坐标的映射。的映射。

(4) (4) 系统映射模式系统映射模式映射模式名称 逻辑单位 X 方向 Y 方向

MM_TEXT 像素 向右 向下

MM_LOMETRIC 0.1 mm 向右 向下

MM_HIMETRIC 0.01 mm 向右 向下

MM_LOENGLISH 0.01 inch 向下 向右

MM_HIENGLISH 0.001 inch 向下 向右

MM_TWIPS 1/1440 inch 向右 向下

MM_ISOTROPIC 可调整 (x==y) 可选择 可选择MM_ABISOTROPIC

可调整 (x!=y) 可选择 可选择

(1)画笔 CPen(int nPenStyle,int nWidth,DWO

RD crColor); nPenStyle 画笔风格PS_SOLID 实线PS_DOT 虚线nWidth 线宽度,以逻辑单位计数。crColor 线颜色,参数值范围 :0~255

6.3 绘图基本工具

(2) 画刷 - 填充颜色样式

实心刷子CBrush br;br.CreateSolidBrush(RGB(255,0,0));带阴影刷子CBrush::CreateHatchBrush(int nIndex, DWORD crColor);例如:创建一个十字线阴影的红色图案刷子CBrush br;br.CreateHatchBrush(HS_CROSS,RGB(255,0,0));

6.4 绘图基本步骤(1) 获取设备环境(2) 设置逻辑坐标及逻辑原点(3) 设置物理坐标及其设备原点(4) 初始化绘图工具(5) 调用绘图函数绘图(3) 释放设备环境结束绘图

6.5 6.5 绘图示例绘图示例 在指定标签控件中绘制学生成绩直方图在指定标签控件中绘制学生成绩直方图(1)(1)向界面中添加标签控件向界面中添加标签控件 设置标签设置标签 IDID 属性为:属性为: IDC_STATIC_DRIDC_STATIC_DR

AWAW(2)(2)获取标签物理的高度和宽度获取标签物理的高度和宽度CRect rc;CWnd* pWDraw=GetDlgItem(IDC_STATIC_D

RAW);pWDraw->GetClientRect(&rc);

(3) (3) 获取标签控件的绘图环境获取标签控件的绘图环境CStatic* pDraw=CStatic* pDraw=

(CStatic*)GetDlgItem(IDC_STATIC_DRAW);(CStatic*)GetDlgItem(IDC_STATIC_DRAW);CDC* pDC1=pDraw->GetDC();CDC* pDC1=pDraw->GetDC();

(4) (4) 设置坐标的映射模式设置坐标的映射模式 pDC1->SetMapMode(MM_ISOTROPIC);pDC1->SetMapMode(MM_ISOTROPIC);

(5) (5) 设置逻辑坐标设置逻辑坐标pDC1->SetWindowExt(200,200);pDC1->SetWindowExt(200,200);pDC1->SetWindowOrg(0,0);pDC1->SetWindowOrg(0,0);

(6) 设置物理坐标pDC1->SetViewportExt(rc.right,-rc.bottom);pDC1->SetViewportOrg(0,rc.bottom);

(7) 创建画笔HPEN pen1= CreatePen(PS_SOLID,1,RGB(0,128,255));pDC1->SelectObject(pen1);pDraw1->UpdateWindow();

(8) 绘制坐标线for(i=0;i<=10;i++)

{pDC1->MoveTo(0,i*20);pDC1->LineTo(200,i*20);

}

for(i=0;i<=10;i++){

pDC1->MoveTo(i*20,0);pDC1->LineTo(i*20,200);

}

6.6 绘制复杂图形

(1)画弧CDC::Arc(int x1,int y1, // 指定边框矩形左上角的逻辑坐标int x2,int y2, // 指定边框矩形右下角的逻辑坐标int x3,int y3, // 椭圆弧起始径线的确定点坐标int x4,int y4 // 椭圆弧终止径线的确定点坐标);

(2) 画封闭图形BOOL Polygon( LPPOINT lpPoints, int nCount );

6.7 输出文本设置前景色 : CDC::SetTextColor(int nColor);设置背景色 : CDC::SetBkColor(int nColor);文本输出函数 :CDC::TextOut(…);示例:dc.SetTextColor(WHITE);dc.SetBkColor(DK_BLUE);dc.TextOut(10,10,“Here it is.”);

第 7 讲 数据库编程

ODBC 是开放数据库互联标准协议,它是Microsoft客户 /服务器环境下的数据访问标准,在 Win32 环境下,用户可使用 ODBC数据源管理器获得对数据库访问权限 。

ODBC提供了一组标准应用程序编程接口,用户可使用 SQL语句实现对数据库的访问。

7.1 ODBC

7.2 ODBC 结构图

应用程序

驱动器管理程序

ODBC驱动程序

ODBC驱动程序

ODBC驱动程序

Oracle Sybase SQL Server

创建过程 (P240)

7.3 创建用户数据源

在 ODBC驱动程序的支持下,应用程序对数据库的访问是在两个常用的 MFC 类支持下而实现的。CDatabaseCRecordset

7.4 访问 ODBC 数据源

用户定义记录集

CObject

CDatabase

CRecordset

用户定义记录集

Connection

SQL 访问

(1) 建立数据库连接(2) 建立动态记录集(3)SQL 数据操作或记录集操作 添加;删除;编辑和修改(4)关闭记录集(5)关闭数据库连接

7.5 实现数据库访问

virtual BOOL Open( LPCTSTR lpszDSN, //ODBC 中注册的数据源名

BOOL bExclusive = FALSE, // 用户是否独占数据库

BOOL bReadOnly = FALSE, // 数据库数据是否为只读

LPCTSTR lpszConnect = “ODBC;”,//连接字符串的信息

BOOL bUseCursorLib = TRUE );// 是否加载 ODBC 光标库

throw( CDBException, CMemoryException );//抛出异常

(1) 建立数据库连接 (P242)

SQL 是结构化查询语言的缩写,使用 SQL命令实现数据库操作。

(2)SQL操作

命令 描述

CREATE 创建新表、字段和索引

DELETE 删除记录

INSERT 在数据库中用单一的操作加载一批数据

SELECT 在数据库中查找满足特定条件的记录

UPDATE 改变特定记录的字段值

DROP 删除数据库中的表或索引

ALTER 通过添加字段或改变字段定义来修改表

子句 描述

FROM 指出从中选定记录的表名

WHERE 指定所选记录必须满足的条件

GROUP BY 把选定的记录分成特定的组

HAVING 说明分组需要满足的条件

ORDER BY 按特定的次序将记录排序

SQL 实例 (P244)Select * From SZB Where 部门 =’ 化工学院’

实例:打开 Access 数据库 RSGL ,选择 SZB表中部门为“化工学院”的全部记录 .

CString SQLString(_T(“Select * From SZB Where 部门 =’ 化工学院’” ));

CDatabase db1;db1.Open( _T( "RSGL_DB" ), FALSE, FALSE, _T( "ODBC;" ),FALSE));

db1. ExecuteSQL(SQLString);

7.6 数据库操作

格式:INSERT INTO 目的表 [( 字段 1 [, 字段 2 [, …]])] VALUES ( 数值 1 [, 数值 2 [,…]])

例如:向数据库 RSGL 的 SZB表中添加一条新记录。CString SQLString(_T(“Insert into szb values(‘姓名’ ,’性别’ ,’部门’ ,....)”);CDatabase db1;db1.Open( _T( "RSGL_DB" ), FALSE, FALSE, _T( "ODBC;" ),FALSE));

db1. ExecuteSQL(SQLString);

(1) 添加记录

格式如下:UPDATE 表名 Set 新值 Where 准则

例如: 将数据表 Taxes 中的字段 Federal值更新为原值的 36%CDatabase m_dbCust;m_dbCust.Open( _T( "MYDATASOURCE" ), FALSE, FALSE, _T( "ODBC;UID=JOES" ),FALSE);

CString strCmd("UPDATE Taxes SET Federal = Federal* 0.36”);m_dbCust.ExecuteSQL( strCmd );

(2)更新记录

DELETE语句的调用格式如下:DELETE 字段列表FROM 数据表名Where 准则

(3)删除记录

(4)事物处理 事物处理是一种把若干条数据库表操

作命令聚合在一起执行的方法 , 以提高效率(特别是在网络环境)同时保证数据的一致性。

事务处理基本特征:

要么都做且做好,要么一件事也不做(如果有一件事做不好 ) 。

事务处理过程

先执行函数 BeginTrans() ,启动事物处理, 接着执行 ExecuteSQL()命令,对数据库表进行操作。 如果操作结果可接受(或是正确的),则用成员函数 CommitTrans()提交操作,把操作结果存盘,数据表磁盘更新。

否则作废刚才的操作,用函数 Rooback()回滚 ExecuteSQL() 的命令操作,恢复数据表的初始状态,保证数据库表数据的完整性。

CRecordset 对象表示数据表的动态内存映像,称为动态记录集。 动态集的主要作用是创建数据表视图,实现记录的查看、浏览、筛选等。 其次创建动态集的作用是可对数据表中的记录进行编辑修改和更新操作。

7.7 CRecordset 类

m_hstmt: 包含记录集的 ODBC语句句柄,类型为 HSTMT 。m_nFields : 包含记录集中的字段数量,类型为 UINT 。m_nParams: 包含记录集中参数数据成员的数量,类型为 UINT 。m_pDatabase: 指向数据源 (DSN) 的 CDatabase 对象的指针。m_strFilter: 作为过滤器选择符合某条件的记录,在 SELECT语句中起到 WHERE子句作用。m_strSort: 作为记录集字段排序的依据,在 SELECT语句中起到 ORDER BY子句作用。

7.8 CRecordset 成员变量

功能:预处理时,将被包含文件中的所有代码嵌入到该指令处。

实例:数据表查询和筛选

为了使简化数据库应用程序的开发过程, Visual C++6.0 中允许用户使用 ActiveX 控件处理处理,这些控件是: Adodc 、 RemoteData 、 DBGrid 和 MSFlexGrid等。

7.9 数据库有关 ActiveX 控件

功能:预处理时,将被包含文件中的所有代码嵌入到该指令处。

(1) Adodc 数据控件与 DataGrid 控件

功能:预处理时,将被包含文件中的所有代码嵌入到该指令处。

(2) MSFlexGrid 控件

功能:预处理时,将被包含文件中的所有代码嵌入到该指令处。

综合实例:

功能:预处理时,将被包含文件中的所有代码嵌入到该指令处。

7.9 ADO 数据库编程 ( 选 )

DLL 是一个 Windows 模块,其中包含许多全局函数为其他程序服务,并以库的形式驻留磁盘或内存。通常将 DLL 作为服务器,为Windows 应用程序提供全局函数的服务。

第 8 讲 动态链接库

功能:预处理时,将被包含文件中的所有代码嵌入到该指令处。

8.1 创建 DLL

功能:预处理时,将被包含文件中的所有代码嵌入到该指令处。

8.2 显式调用 DLL

功能:预处理时,将被包含文件中的所有代码嵌入到该指令处。

8.3 隐式调用 DLL

一个应用程序可一条到走到底,也可把各个部分同时进行,提高运行效率。一个监控程序默默无闻地在后台工作,而不影响前台用户交互操作,也是利用了多线程。 例如:使用 Windows 配置的磁盘碎片整理软件。通常情况下,这类的实用程序拥有许多管理选项,比如该实用程序应该相隔多长时间运行 1次,何时运行等。使用低优先级线程在后台运行该实用程序,并在系统空闲时间对驱动器进行碎片整理。

第 9 讲 多线程

如果一个线程只完成后台计算,不需要和用户交互,则可使用工作者线程

9.1 工作者线程

如需要创建一个与用户交互的程序,则应使用用户界面线程。 MFC 会给用户界面线程增加一个消息循环,这些用户界面线程可处理自己的消息队列中的消息

9.2 用户界面线程

(1)创建线程HANDLE CreateThread(

// 线程的安全属性 LPSECURITY_ATTRIBUTES lpThreadAttributes, DWO

RD dwStackSize, // 线程的堆栈深度 LPTHREAD_START_ROUTINE lpStartAddress, //

线程的起始地址 LPVOID lpParameter, // 新线程的 32位参数

DWORD dwCreationFlags, // 线程创建的特性

LPDWORD lpThreadId // 返回线程的 ID值

);

9.3 MFC 中线程函数

BOOL SetThreadPriority( HANDLE hThread, // 线程句柄

int nPriority // 线程优先级);

( 2)设置线程的优先权

如果在线程的执行过程中硬性终止,则可调用下列函数实现:VOID ExitThread( DWORD dwExitCode // 本线程的退出码 );说明:线程退出码是由 GetExitCodeThread函数得到,其函数原型如下:BOOL GetExitCodeThread( HANDLE hThread, // 线程句柄 LPDWORD lpExitCode // 线程的终止状态 - 本线程的退出码);

CMutex 类

9.4 线程同步

功能:预处理时,将被包含文件中的所有代码嵌入到该指令处。

9.5 线程实例