64
数数数数数数 VC 数数 ++ 数数数数

数字图像处理 - VC ++介绍

Embed Size (px)

DESCRIPTION

数字图像处理 - VC ++介绍. 电子信息. 1 面向对象程序设计思想. 1.1 面向对象程序设计的特点 (1) 抽象性 用 C++ 语言可以将该图形描述如下: 圆形 (circle) : 数据抽象: double x , y , r ; 行为抽象: setx() ; sety() ; setr() ; draw() ;. (2) 封装性 (3) 继承性 (4) 多态性. 1.2 面向对象的标记 如 图给出了类的标记方法和一个 point 类的标记实例。. 图:类的标记图. - PowerPoint PPT Presentation

Citation preview

Page 1: 数字图像处理 - VC ++介绍

数字图像处理- VC ++介绍

电子信息

Page 2: 数字图像处理 - VC ++介绍

1 面向对象程序设计思想1.1 面向对象程序设计的特点

(1) 抽象性用 C++ 语言可以将该图形描述如下:圆形 (circle) :数据抽象:double x , y , r ;行为抽象:setx() ; sety() ; setr() ; draw() ;

Page 3: 数字图像处理 - VC ++介绍

(2) 封装性 (3) 继承性 (4) 多态性

Page 4: 数字图像处理 - VC ++介绍

ˈ̞

Êý¾Ý³ÉÔ±

³ÉÔ±º¯Êý

Point

int x,y;

point(int,int);point(point);int getx();int gety();

图:类的标记图

• 1.2 面向对象的标记• 如图给出了类的标记方法和一个 point 类的标记

实例。

Page 5: 数字图像处理 - VC ++介绍

P1

int x,y;

point(int,int);point(point);

int gety();

¶ÔÏóÃû

Êý¾Ý³ÉÔ±

³ÉÔ±º¯Êý int getx();

对象的标记图

• 对象是类的实例,在 Cord/Yourdon 标记中,对象是在相应类标记外加一个圆角矩形框,如图所示。

Page 6: 数字图像处理 - VC ++介绍

2 类和对象2.1 类的声明

类的声明即类的定义,声明一个类的语法与结构的声明类似,其一般形式为:

class < 类名 >

{

private :< 私有成员函数和数据成员的说明 >

public :< 公有成员函数和数据成员的说明 >

} ;< 各个成员函数的实现 >

Page 7: 数字图像处理 - VC ++介绍

其中, class 是声明类的关键字; < 类名 > 是标识符,表示声明的类的名字;类声明体内的函数和变量称为这个类的成员,分别称为成员函数和数据成员。 类的成员函数用于对数据成员进行处理,又称为“方法”,程序中通过类的成员函数来访问其内部的数据成员,成员函数是类与外部程序之间的接口。一般类中成员函数的原型声明写在类定义体内,用以说明该成员函数的形式参数和返回值类型,而成员函数的定义体一般写在类定义之外。通常采用下面的形式定义成员函数:< 类型标识符 > < 类名 >::< 成员函数名 >(< 形参表 >)

{

< 函数体 >

}

Page 8: 数字图像处理 - VC ++介绍

例如:» class rectangle» {» private:» int x,y,weight,high;» public:» rectangle(int xx,int yy,int w,i

nt h)» {x = xx; y = yy; weight = w; h

igh = h;}» inline int area(); » };» inline int rectangle::area()» {» return weight * high;» }

Page 9: 数字图像处理 - VC ++介绍

2.2 对象类和对象的关系相当于普通数据类型与其变量的关系。

类是一种逻辑抽象概念,声明一个类只是定义了一种新的数据类型,对象说明才真正创建了这种数据类型的物理实体。由同一个类创建的各个对象具有完全相同的数据结构,但它们的数据值可能不同。

一旦创建了一个类的对象,程序就可以用运算符“ .”来引用类的公有成员,其一般形式为

< 对象名 > . < 公有数据成员名 >

Page 10: 数字图像处理 - VC ++介绍

或< 对象名 > . < 公有成员函数名 ( 实参表 )>

例如,前面我们定义一个 rectangle 类,现在我们定义一个 rectangle 的对象 r1 ,通过对象 r1 完成对成员函数 area() 的调用。

rectangle r1(10,10,20,20);

r1.area() ;需要注意,只有用 public 定义的公有成员才能

使用圆点操作符访问,对象中的私有成员是类中隐藏的数据,不允许在类外的程序中被直接访问,只能通过该类的公有成员函数来访问它们。

Page 11: 数字图像处理 - VC ++介绍

2.3 构造函数和析构函数(1) 构造函数

构造函数是在类中声明的一种特殊的成员函数,作用是在对象被创建时使用特定的值构造对象,将对象初始化为一个特定的状态。

构造函数的名字与它所属的类名相同,被声明为公有函数,且没有任何类型的返回值,在创建对象时被自动调用。

构造函数作为类的一个成员函数,具有一般成员函数所有的特性,它可以访问类的所有数据成员,可以是内联函数,可以带有参数表,还可以带默认的形参值。构造函数也可以重载,以提供初始化类对象的不同方法。

Page 12: 数字图像处理 - VC ++介绍

例如,前面定义的 rectangle 类的构造函数为rectangle(int xx,int yy,int w,int h){x = xx; y = yy;

weight = w; high = h;}

每个类都必须有构造函数,若类定义时没有定义任何构造函数,编译器会自动生成一个不带参数的缺省构造函数,其形式如下:

< 类名 >::< 缺省构造函数名 >()

{

//……

}

Page 13: 数字图像处理 - VC ++介绍

(2) 析构函数一个对象失效时,要调用该对象所属类的析构函数。

析构函数的功能是用来释放一个对象的。析构函数本身并不实际删除对象,而是进行系统放弃对象内存之前的清理工作,使内存可用来保存新的数据,它与构造函数的功能正好相反。

Page 14: 数字图像处理 - VC ++介绍

例 : 构造函数和析构函数的例题。• #include <iostream.h>• class point• {• private:• int x, y;• public:• point(int xx = 0, int yy = 0)

• {

• x = xx;

• y = yy;

• cout << " 构造函数被调用 "<< endl;

• }• ~point(){ cout << " 析构函数被调用 "<< endl;

}• int get_x() {return x;}• int get_y() {return y;}• };

Page 15: 数字图像处理 - VC ++介绍

– void main ()– {– point a(15, 22);– }

• 程序的运行结果为:• 构造函数被调用• 析构函数被调用

Page 16: 数字图像处理 - VC ++介绍

3 使用 AppWizard 开发 MFC 应用程序

3.1 生成MFC应用程序框架例 3-1 使用 MFC AppWizard 生成一个简单的 MFC 应用程

序。建立 MFC 应用程序框架一般可以通过以下步骤来实现:

(1) 启动 MFC AppWizard :定义项目名称。在 File菜单下选择 New ,出现如图 3-l 所示的 New 对话框。

Page 17: 数字图像处理 - VC ++介绍

图 3-1 New 对话框

Page 18: 数字图像处理 - VC ++介绍

在图 3-1 中选择MFC AppWizard[exe] ,在 Project name文本输入框中输入新建的项目名如 Mymfc后,单击 OK按钮,将弹出 MFC AppWizard-Step 1对话框,如图 3-2 所示。

Page 19: 数字图像处理 - VC ++介绍

图 3-2 MFC AppWizard-Step 1 对话框

Page 20: 数字图像处理 - VC ++介绍

(2)  MFC AppWizard-Step 1 对话框:选择应用程序的类型和语言。在设置好上述选项后,单击 Next按钮,将弹出 MFC AppWizard-Step 2 对话框,如图 3-3 所示。

Page 21: 数字图像处理 - VC ++介绍

图 3-3 MFC AppWizard-Step 2 对话框

Page 22: 数字图像处理 - VC ++介绍

(3) MFC AppWizard-Step 2 :修改类的信息。• 在 MFC AppWizard-Step 6 of 6 对话框中,可以设置

向导生成的文件名和类名。• 在设置好文件名和类名后,单击 Finish按钮,将弹出

新建工程信息对话框,该对话框列出了关于新建立的应用程序项目文件的相关信息,如图 3-4 所示。

Page 23: 数字图像处理 - VC ++介绍

图 3-4 新建项目信息对话框

Page 24: 数字图像处理 - VC ++介绍

(4) 单击图 3-4 中的 OK按钮,应用程序向导所有的工作就全部完成了,这时向导已经为用户生成了一个可执行的应用程序框架,如图 3-5 所示。

Page 25: 数字图像处理 - VC ++介绍

图 3-5 MFC 自动生成的应用程序框架

Page 26: 数字图像处理 - VC ++介绍

(5) 编译运行。 MFC AppWizard已经生成了一个基本的应用程序, Mymfc 应用程序的运行结果如图 3-6 所示。

图 3-6 Mymfc 应用程序的运行结果

Page 27: 数字图像处理 - VC ++介绍

3.2 查看 AppWizard 生成的信息(1) 生成的 C++ 类• 这里建立的是一个基于文档 /视图结构、单文档、无 OLE、无数据库选项的最基本的程序框架所需的类 (文档 /视图结构将在后面详细介绍 ) ,所以 MFC AppWizard 为 Mymfc

程序生成了四个类。• CMymfcApp :应用程序类,负责程序的初始化、运行以及

结束处理;• CMainFrame :主窗口类,负责主窗口的创建、显示和搜索用户命令以及消息派发;

• CMymfcDoc :文档类,负责应用程序文档的装载和维护,文档是应用程序需要保存的任何内容;

Page 28: 数字图像处理 - VC ++介绍

• CMymfcView :视图类,负责为文档提供一个或几个视图,视图的作用是为显示和修改文档提供人机界面。

• 它们的基类及其声明和定义文件如表 3-1 所示。

Page 29: 数字图像处理 - VC ++介绍

表 3-1 MFC AppWizard 生成的类

类名称 基 类 类声明文件 类实现文件 CMymfcApp CMainFrame CMymfcDoc CMymfcView

CWinApp CFrameWnd CDocument CView

Mymfc.h MainFrm.h Hel1oDoc.h MymfcView.h

Mymfc.cpp MainFrm.cpp MymfcDoc.cpp MymfcView.cpp

Page 30: 数字图像处理 - VC ++介绍

• (2) 生成的文件• AppWizard 创建项目时,在指定的\ Mymfc目录下创

建了许多文件,这些文件包含了框架程序的所有的类、全局变量的声明和定义,如图 3-7 所示。

Page 31: 数字图像处理 - VC ++介绍

图 3-7 \ Mymfc目录下创建的文件

Page 32: 数字图像处理 - VC ++介绍

• 1) 工作区、项目和类信息文件• AppWizard 生成的应用程序框架是通过项目工作区

来管理的。所以,无论选择什么类型的应用程序, AppWizard 都要为应用程序生成相应的工作区、项目和类信息文件。本例的工作区、项目和类信息文件如表 3-2 所示。

Page 33: 数字图像处理 - VC ++介绍

表 3-2 Mymfc 应用程序的工作区、项目和类信息文件

文 件 名 说 明 Mymfc.dsw 工作区文件,它保存了当前工作区所包含的项目的信息 Mymfc.dsp 项目文件,它包含当前项目的设置、项目中包含的文件等信息

Mymfc.clw 类信息文件,它含有能被 AppWizard 用来编辑现有类或增加新类的信息。

AppWizard还用这个文件来保存创建和编辑消息映射与对话框数据所需的信息,以及创建虚拟成员函数所需的信息

Page 34: 数字图像处理 - VC ++介绍

• 2) 应用程序头文件和源文件• 根据应用程序的类型——单文档、多文档或基

于对话框, AppWizard 将自动创建一些应用程序源文件和头文件,这些文件分别是应用程序类、对话窗口类等的声明文件和类实现文件。在本例中, AppWizard 生成的头文件和源文件如表 3-3 所示。

Page 35: 数字图像处理 - VC ++介绍

表 3-3 Mymfc 应用程序的头文件和源文件文 件 名 说 明

Mymfc.h 应用程序的主头文件,它含有所有全局符号和用于包含其他头文件的#include伪指令

Mymfc.cpp 应用程序的主源文件。它将创建 CMymfcApp类的一个对象(从 CWinApp派生),并覆盖 InitInstance成员函数

MainFrm.h, MainFrm.cpp

从 CFrameWnd(SDI 应用程序 )或 CMDIFrameWnd(MD 应用程序 )派生 C MainFrame类

MymfcDoc.h, MymfcDoc.cpp

从 CDocument类派生并实现名为 CMymfcDoc的文档类,含有用于初始化文档、串行化(保存和装入)文档和用于调试诊断的一些成员函数的框架

MymfcView.h, MymfcView.cpp

派生并实现名为 CMymfcView 的视图类,用于显示和打印文档数据。CMymfcView类是从 CView或它的派生类派生出来的,含有绘制视图和用于调试诊断的一些成员函数框架

Page 36: 数字图像处理 - VC ++介绍

• 3) 资源文件• 4) StdAfx.cpp 和 StdAfx .h

3.3 浏览项目信息与添加代码• (1) 浏览项目信息• 前面生成的 Mymfc 应用程序在项目工作区窗口中显示

如图 3-8 所示。

Page 37: 数字图像处理 - VC ++介绍

图 3-8 Mymfc项目工作区窗口

Page 38: 数字图像处理 - VC ++介绍

• 切换到 ClassView 中,展开 ClassView顶层的文件夹后,显示 Mymfc项目中所包含的所有的类。双击 CMymfcApp 类的图标 ( 或单击图标旁的 +号 ) 时, ClassView展开该类并显示其类成员,如图 3-9 所示。

Page 39: 数字图像处理 - VC ++介绍

图 3-9 项目Mymfc 的类视图

Page 40: 数字图像处理 - VC ++介绍

• 项目中增减 C++ 类或者在类中增减成员,都可以在 ClassView 中进行。

• 切换工作区视图到 ResourceView ,可以看到 AppWizard 自动为 Mymfc 程序生成的资源名称和类型,资源类型包括图标、菜单、加速键、工具栏、版本信息等,如图 3-10 所示。

Page 41: 数字图像处理 - VC ++介绍

图 3-10 项目Mymfc 的资源视图

Page 42: 数字图像处理 - VC ++介绍

(2) 添加代码• 添加成员变量一般有两种方法:• 第一种方法是利用 VC++ 的可视化编程工具,具体步骤为:在 Workspace窗口的 ClassView选项卡中选择要添加成员变量的类。右击此类,在弹出菜单中单击Add Member Variable选项,将出现如图 3-11 所示的Add Member Variable 对话框。

Page 43: 数字图像处理 - VC ++介绍

图 3-11 Add Member Variable 对话框

Page 44: 数字图像处理 - VC ++介绍

4 MFC 应用程序框架与Win32 程序的关联

4.1 MFC应用程序框架对Win32程序的封装(1) Windows程序的基本结构• WinMain(…)

• {

• WNDCLASS wndclass ;

• RegisterClass ( &wndclass);

• CreateWindow (…);

• ShowWindow (…) ;

• UpdateWindow (…);

• While (GetMessage (&msg,NULL,0,0))

Page 45: 数字图像处理 - VC ++介绍

• {• TranslateMessage (&msg); • DispatchMessage (&msg);• }• }• WndProc (hwnd, message, wPara

m, lParam)

Page 46: 数字图像处理 - VC ++介绍

• {• switch (message)• {• case …•

• case WM_DESTROY:• PostQuitMes

sage (0);• default:• return DefWindowPr

oc (hwnd,message,wParam,lParam);• }• return (0);• }

Page 47: 数字图像处理 - VC ++介绍

(2).MFC类对WinMain和WndProc的封装• 在 MFC 类中,与应用程序框架相关的类如图 3-12 所示。

Page 48: 数字图像处理 - VC ++介绍

CWnd

CFrameWnd

CWinThread

CWinApp

CDocument

CView

CCmdTarget

CObject

图 3-12 MFC 应用程序相关的几个类

Page 49: 数字图像处理 - VC ++介绍

• 通常在应用程序中,我们直接操作的不是上面这些类,而是以这些类为基类派生出来的类。例如,在 Mymfc程序中, AppWizard 生成的类与这些类的派生关系如下:

• 基类派生类

• CWinApp CMymfcApp

• CFrameWnd CMainFram

• CDocument CMymfcDoc

• CView CMymfcView

Page 50: 数字图像处理 - VC ++介绍

4.2 MFC应用程序的启动流程• 下面是 Mymfc 程序的启动流程,如图 3-13 所示。

Page 51: 数字图像处理 - VC ++介绍

³ÌÐò¿ªÊ¼

³õʼ»¯È«¾Ö¶ÔÏótheApp

CMymfcApp¹¹Ô캯Êý

CWinApp¹¹Ô캯Êý

AfxWinMain ()

CMymfcApp::Run()

¿ÕÏÐ

WM_QUIT

CMymfcApp::

OnIdle()

Ïû좄 »·

CMymfcApp

InitInstance (){

OnFileNew () £»»ò OnFileOpen ();}

CMainFrame

CMainFrame (){

Create ( ¡ );}

CMymfcDoc

CMymfcDoc ()

{ ¡ }

CMymfcView

CMymfcView ()

{ ¡ }

Ïú»Ù´°¿Ú

³ÌÐò½áÊø

图 3-13 Mymfc 程序流程

Page 52: 数字图像处理 - VC ++介绍

需要解释的地方有以下几点:• (1) 应用程序类: CWinApp 的派生类,该类的每一个对象代表一个应用程序。程序中默认定义一个全局的对象,即 t

heApp 。• (2) Main 函数:启动应用程序时, Windows 调用应用程序

框架内置的 WinMain 函数, WinMain寻找由 CWinApp派生出的全局构造的应用程序对象 theApp 。

• (3) 函数 InitInstance :当 WinMain 函数找到应用程序对象 theApp 时,它调用虚成员函数 InitInstance ,这个成员函数调用所需的构造动态 ( 在程序运行时 ) 创建主窗口对象、视图对象和文档对象,以及主框架窗口和视图窗口,并显示应用程序的主框架窗口和视图窗口。

Page 53: 数字图像处理 - VC ++介绍

• (4) 成员函数 Run :函数 Run 隐藏在基类 CWinApp中,它负责从消息队列中读取应用程序的消息到窗口,以保持应用程序的正常运行。在 WinMain 调用 InitInstance 之后,便调用 Run 函数。

• (5) 成员函数 ExitInstance :如果用户通过关闭主框架窗口来关闭应用程序,这个操作就将激发一系列事件的发生,包括从 Run 中退出,从WinMain 中退出和应用程序对象的析构。

Page 54: 数字图像处理 - VC ++介绍

• 实际的 Mymfc 程序或者 MFC 应用程序的流程比Win32 程序要复杂许多,主要差别在于以下几点:

• (1) 程序的主函数名为全局函数 AfxWinMain() 而不是WinMain() 。

• (2) 一般 MFC 应用程序在 InitInstance 函数中,不仅创建了窗口对象和主窗口,还会创建视图对象和视图窗口、文档对象。

• (3) 读取应用程序的消息队列的代码在 CWinThread::Run() 中。因为 CWinThread 是 CWinApp 的基类,所以 CWinApp::Run() 会调用 CWinThread::Run() 。

Page 55: 数字图像处理 - VC ++介绍

5 MFC 应用程序的消息映射

5.1 消息类别(1) .窗口消息• 对于窗口消息,描述它的三个主要字段消息类别 mess

sge、附加参数 wParam 和 lParam 的格式如下:• messsge wParam

lParam

• WM_XXX 随 WM_XXX 而 变

Page 56: 数字图像处理 - VC ++介绍

• 窗口消息的产生一般包含下列途径:与窗口交互产生;系统产生。

• (2) .命令消息• 命令消息一般与处理用户的某个请求或者执行用户的某

个指令有关。描述它的三个主要字段消息类别 messape、附加参数 wParam 和 lParam 的格式如下:

• messsge wParam

lParam

• WM_COMMAND 低 16 位为命令 ID 高 16 位为 00L

Page 57: 数字图像处理 - VC ++介绍

• 命令消息的产生一般包含下列途径:•         选择菜单项;•         单击工具栏按钮;•         按加速键;•         程序产生命令。• (3) .控件消息• 描述控件消息的三种格式如下:•

Page 58: 数字图像处理 - VC ++介绍

• 1) 仿窗口消息格式。这种格式遵循窗口消息格式,是窗口消息集的一部分。格式为:

• messsge wParam lParam

• WM_XXX 随 WM_XXX 而 变随WM_XXX 而变

• 2) 仿命令消息格式。此格式遵循命令消息格式,但是与命令消息的附加参数有区别。格式如下:

• messsge wParam lParam

• WM_COMMAND

• 低 16位为控件 ID ,高 16位为消息通知码 控件窗口句柄

Page 59: 数字图像处理 - VC ++介绍

• 3) 单独控件消息格式。这种格式是一种流行的控件消息表示格式,消息类别码为 WM_NOTIFY ,格式为:

• messsge wParam lParam

• WM_NOTIFY 控件 ID 指向 NMHDR 的指针

Page 60: 数字图像处理 - VC ++介绍

5.2 消息映射原理• MFC 应用程序对消息的处理大致分为两个阶段。第一阶段,

使用应用程序类的 Run() 函数把消息从应用程序的消息队列提取出来,并且发送到目标类对象,即主框架窗口类对象;第二阶段,因为所有消息的最终目标并不一定是主窗口类对象,也可能是其他类。

5.3 消息处理过程• 将经历下列过程:• (1) 应用程序类 Run() 函数调用 ::DispatchMessage(MSG *

msg)把消息交给全局函数 LRESULT AfxWndPorc(HWND

hwnd , UINT nmsg , WPARAM wParam , LPARAM l

Param) 。

Page 61: 数字图像处理 - VC ++介绍

• (2) AfxWndPorc(…) 接收消息,并寻找消息的目标窗口 CW

nd 对象,然后调用 LRESULT AfxCallWndProc(CWnd *p

Wnd , HWND hwnd , UINT msg , WPARAM wParam ,LPARAM lParam) 。

• (3) AfxCallWndProc(…) 存储消息的消息标志符和参数,然后调用目标窗口对象的虚函数 LRESULT WndProc(UINT n

msg , WPARAM wParam , LPARAM lParam) 。• (4) WndProc(…) 将发送消息给 BOOL OnWndMsg(UINT n

msg , WPARAM wParam , LPARAM lParam , LRESU

LT *pResult) 。 OnWndMsg(…)负责将消息分类为窗口消息、命令消息和控件消息三种,不同的消息类别将交给不同的消息处理函数去处理。

Page 62: 数字图像处理 - VC ++介绍

• (5) 如果消息类别是 WM_COMMAND ,则 OnWndMsg(…) 将调用 LRESUL OnCommand(WPARAM wParam , LPARAM lParam) ;如果消息类别是 WM_NOTIFY ,则 OnWndMsg(…) 将调用 BOOL OnNotify(WPARAM wParam , LPARAM lParam , LRESULT &pResult) ;其他则认为是窗口消息, OnWndMsg(…)将搜索目标窗口类或者基类的消息映射表,以判断该类及其基类能否处理该消息。如果不能处理此消息,OnWndMsg(…) 将把消息交给 LRESULT DefWindowProc(UINT nmsg , WPARAM wParam , LPARAM lParam) 函数进行默认处理。

Page 63: 数字图像处理 - VC ++介绍

• (6) OnCommand(…) 继续判断消息 lParam 参数是否为 0 。如果不为 0 ,则为控件消息,将通知控件处理该消息;如果 lParam 参数为 0 或者控件不能处理该消息,将调用 BOOL OnCmdMsg(UINT nID , int nCode , void *pExtra , AFX_CMDHANDLERlNFO *pHandlerlnfo) , OnCmdMsg(…) 将按照一定的路径搜索相应类的消息映射表,以确定能否处理该消息。

• (7)  OnNotify(…) 将通知控件处理该消息:如果控件不能处理该消息,则也将调用 OnCmdMsg(…)按照一定的路径搜索相应类的消息映射表。

Page 64: 数字图像处理 - VC ++介绍

• (8)  OnCmdMsg(…)按照已经规定好的路径搜索相应类的消息映射表,以便找到消息处理函数并执行,如果不能找到,则把相应的界面元素 ( 如菜单项 ) 变灰。OnCmdMsg(…)把搜索的结果反馈给 OnNotify(…) 和OnCommand(…) ,然后它们分别把处理的结果反馈给 OnCmdMsg(…) 函数,以便确定 OnCmdMsg(…)能否处理该消息。