9.1.1 图像处理

45
9.1.1 9.1.1 图图图图 图图图图 1. 图图图图图图 1) Visual C++ 的 Picture 的的 的的的的 (Picture) 的的的 Visual C++ 的的的的的的 的的的的 的的的 一, VB 的的 Ima ge 的的的的的的的的的的的的的的的的 (BMP GIF JPEG 的 ) 的的的的的的的的的的的的的的 的的的的的的的的的的的的 、。 2) Microsoft Forms 2.0 Image 的的 的的的的Microsoft Windows 的的 Microsoft Forms 2. 0 Image 的的的的的的的的的的的的3) Microsoft Web 的的的 Web 的的的的的的 Web 的的的的 的的的 的的的的的 。一 Internet 的的的的的的的的的 的的的 WWW ( 的的的 ) 的的的的的的 ( 的的的的的的的的) 的的的的的

Upload: alena

Post on 16-Mar-2016

155 views

Category:

Documents


5 download

DESCRIPTION

1. 常用图像控件. 9.1.1 图像处理. 1) Visual C++ 的 Picture 控件. 静态图片 (Picture) 控件是 Visual C++ 中颇具微词的一个控件,它不像 VB 中的 Image 控件可以显示出绝大多数的图像文件 (BMP 、 GIF 、 JPEG 等 ) 而只显示出在资源中的图标、位图、光标以及图元文件的内容。. 2) Microsoft Forms 2.0 Image 控件. 作为弥补, Microsoft Windows 提供 Microsoft Forms 2.0 Image 控件来试图缓和上述的局面。. - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: 9.1.1    图像处理

9.1.1 9.1.1 图像处理图像处理1. 常用图像控件1) Visual C++ 的 Picture 控件 静态图片 (Picture) 控件是 Visual C++ 中颇具微词的一个控件,它不像VB 中的 Image 控件可以显示出绝大多数的图像文件 (BMP 、 GIF 、 JPEG 等 ) 而只显示出在资源中的图标、位图、光标以及图元文件的内容。2) Microsoft Forms 2.0 Image 控件 作为弥补, Microsoft Windows 提供 Microsoft Forms 2.0 Image控件来试图缓和上述的局面。 3) Microsoft Web 浏览器

Web 浏览器又称为 Web 客户程序。它是一种用于获取 Internet 网上资源的应用程序,是查看 WWW( 万维网 ) 中超文本文档 ( 也包括图像及多媒体 ) 的重要工具。

Page 2: 9.1.1    图像处理

9.1.1 9.1.1 图像处理图像处理2. BMP2. BMP 图像显示及处理图像显示及处理如果不使用控件,也可以通过 Windows API 相关函数将一个外部 BMP 文件图像显示出来,并可通过读写像素将图像进行拉普拉斯锐化处理。所谓“锐化”,是在增强图像边缘效果的同时增加了图像的噪声。

Page 3: 9.1.1    图像处理

9.1.2 9.1.2 使用媒体控制接口使用媒体控制接口 (MCI)(MCI)1. MCI 设备类型

设备类型设备类型 说 明说 明 设备类型设备类型 说 明说 明animationanimation 动画设备动画设备 scannerscanner 图形扫描设备图形扫描设备cdaudiocdaudio CDCD音频设备音频设备 sequencersequencer MIDIMIDI设备设备datdat 数字音频磁带机数字音频磁带机 vcrvcr 录相机设备录相机设备digitalvideodigitalvideo 数字视频设备数字视频设备 videodiscvideodisc 影碟播放设备影碟播放设备otherother 未定义的未定义的 MCIMCI设备设备 waveaudiowaveaudio 波形音频设备波形音频设备overlayoverlay 窗口中的模拟设备窗口中的模拟设备

2. MCI 编程步骤mciSendCommand 函数原型如下:

MCIERROR mciSendCommand( MCIDEVICEID IDDevice, UINT uMsg,

DWORD fdwCommand, DWORD dwParam );

Page 4: 9.1.1    图像处理

9.1.2 9.1.2 使用媒体控制接口使用媒体控制接口 (MCI)(MCI)

3. 3. 示例示例添加的控件添加的控件 IDID 号号 标 题标 题 其他属性其他属性

静态文本控静态文本控件件 IDC_DISPIDC_DISPFILEFILE

水平对齐、中垂直、下沉,其水平对齐、中垂直、下沉,其余默认余默认

按钮 按钮 IDC_FILEIDC_FILE 波形文波形文件件 默认默认

按钮按钮 IDC_PLAIDC_PLAYY 播放播放 默认默认

按钮按钮 IDC_STOIDC_STOPP 停止停止 默认默认

Page 5: 9.1.1    图像处理

9.1.2 9.1.2 使用媒体控制接口使用媒体控制接口 (MCI)(MCI)

控件控件 IDID 号号 变量类别变量类别 变量类型变量类型 变量名变量名 范围和大小范围和大小IDC_DISPFILEIDC_DISPFILE ValueValue CStringCString m_strFileNamem_strFileName

IDC_FILEIDC_FILE ControlControl CButtonCButton m_btnFilem_btnFile ————

IDC_PLAYIDC_PLAY ControlControl CButtonCButton m_btnPlaym_btnPlay ————

IDC_STOPIDC_STOP ControlControl CButtonCButton m_btnStopm_btnStop ————

控 件 变 量

Ex_Wave 运行结果

Page 6: 9.1.1    图像处理

1. MCIWnd 窗口类 MCIWnd 是一个控制多媒体设备的窗口类,它提供的函数、消息以及宏与上述的 MCI 的底层功能具体相似的方法。

#pragma comment (lib,"vfw32.lib")

2. 使用 MCIWnd 窗口类一般步骤 (1) 在程序中调用 MCIWndRegisterClass 函数注册 MCI 窗口类,以便以后用 CreateWindow 或 CreateWindowEx 函数创建窗口,或者直接调用函数 MCIWndCreate 创建窗口。

(2) 获得相应的窗口句柄后,就可调用 MCIWndOpen 宏来打开设备。 (3) 由于 MCIWnd 窗口提供了相应的媒体控制按钮,因而不需要用户编写额外的代码。

(4) 作为技巧,用户还应该跟踪 MCIWnd 窗口的一些消息来调整 MCIWnd 窗口。

9.1.3 9.1.3 使用使用 MCIWndMCIWnd 窗口类窗口类

Page 7: 9.1.1    图像处理

9.1.4 9.1.4 使用使用 OpenGLOpenGL

1.OpenGL 特点及功能(1) 建模功能(2) 变换功能(3) 颜色模式设置(4) 光照和材质设置(5) 纹理映射(6) 位图显示和图像增强

(7) 双缓存动画2.OpenGL 图形库

科学计算可视化、计算机动画和虚拟现实是当前计算机图形学的三个热点,而这三个热点的核心都是三维真实感图形的绘制。

OpenGL 图形库一共有几百个函数,主要由核心库、实用库和辅助库三个部分组成。

Page 8: 9.1.1    图像处理

9.1.4 9.1.4 使用使用 OpenGLOpenGL

3. 3. 用用 MFCMFC 编写编写 OpenGLOpenGL 程序程序 (1) 先设置设备环境 DC 的位图格式 (PIXELFORMAT) 属性,通过填写一个 PIXELFORMATDESCRIPTOR 的结构来完成,该结构决定了 OpenGL作图的物理设备的属性,比如该结构中的数据项 dwFlags 中 PFD_DOUBLEBUFFER 位,如果没有设置,通过该设备的 DC 作图的 OpenGL 命令就不可能使用双缓冲来做动画。

(2) 根据刚才的设备环境 DC 用 wglCreateContext 建立一个渲染环境 RC(Rendering Context , RC) ,并调用 wglMakeCurrent 使得 RC 与 DC 建立联系。

(3) 调用 OpenGL 函数作图。 (4) 作图完毕以后,先通过设置当前 RC 为 NULL ,断开和该渲染环境的联系,然后再根据 RC 句柄的有效性进行释放或者删除。

4. OpenGL 程序示例

Page 9: 9.1.1    图像处理

9.1.4 9.1.4 使用使用 OpenGLOpenGL Ex_OpenGL运行结果

Page 10: 9.1.1    图像处理

9.1.5 DirectX9.1.5 DirectX 编程编程1. DirextX 概述

DirectX 是 Microsoft 开发的基于 Windows平台的一组 API ,它是为高速的实时动画渲染、交互式音乐和环境音效等高要求应用开发服务的。

2. Direct3D 编程(1) 用 MFC AppWizard(exe) 创建一个默认的单文档应用程序 Ex_D3D

(2) 为 CEx_D3DView 类添加两个保护型对象,如下面的代码:protected:

LPDIR m_pD3D // Direct3D 对象的接口指针

LPDIRECT3DDEVICE m_pDevice // 设备对象的接口指针

Page 11: 9.1.1    图像处理

9.1.5 DirectX9.1.5 DirectX 编程编程

void CEx_D3DView::OnInitialUpdate() void CEx_D3DView::OnInitialUpdate() {{

CView::OnInitialUpdate();CView::OnInitialUpdate();// // 创建创建 Direct3DDirect3D 对象,并获取接口对象,并获取接口 IDirect3D9IDirect3D9 的指针,的指针,// // 将通过该指针操作将通过该指针操作 Direct3DDirect3D 对象。对象。m_pD3D = ::Direct3DCreate9(D3D_SDK_VERSION);m_pD3D = ::Direct3DCreate9(D3D_SDK_VERSION);D3DPRESENT_PARAMETERS d3dpp;D3DPRESENT_PARAMETERS d3dpp;::ZeroMemory(&d3dpp, sizeof(d3dpp));::ZeroMemory(&d3dpp, sizeof(d3dpp));d3dpp.Windowed = TRUE;d3dpp.Windowed = TRUE; // // 创建窗口模式的创建窗口模式的 Direct3DDirect3D 程序程序d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;// // 调用方法调用方法 IDirect3D9::CreateDeviceIDirect3D9::CreateDevice 创建设备对象,并获取创建设备对象,并获取// // 接口接口 IDirect3DDevice9IDirect3DDevice9 的指针,将通过该指针操作设备对象的指针,将通过该指针操作设备对象m_pD3D->CreateDevice(m_pD3D->CreateDevice(D3DADAPTER_DEFAULT,D3DADAPTER_DEFAULT,// // 使用缺省的显卡使用缺省的显卡D3DDEVTYPE_HAL,D3DDEVTYPE_HAL, // // 指定设备类型为指定设备类型为 HALHALm_hWnd,m_hWnd, // Direct3D// Direct3D 窗口的句柄窗口的句柄D3DCREATE_SOFTWARE_VERTEXPROCESSING,//D3DCREATE_SOFTWARE_VERTEXPROCESSING,// 软件顶点处理软件顶点处理&d3dpp, &m_pDevice);&d3dpp, &m_pDevice);}}

(3) 用 MFC ClassWizard 为 CEx_D3DView 类添加 OnInitialUpdate 函数的重载,并添加下列 Direct3D初始化代码:

Page 12: 9.1.1    图像处理

9.1.5 DirectX9.1.5 DirectX 编程编程 (4) (4) 用用 MFC ClassWizardMFC ClassWizard 为为 CEx_D3DViewCEx_D3DView类添加类添加 WM_DESTROYWM_DESTROY 消息消息

映射,并添加下列映射,并添加下列 Direct3DDirect3D 对象指针释放代码:对象指针释放代码: (5) 打开 stdafx.h 文件,添加 Direct3D 的头文件包含和库: (6) 在 CEx_D3DView::OnDraw 函数中添加下列绘制代码:

(7) 编译并运行

Page 13: 9.1.1    图像处理

9.1.5 DirectX9.1.5 DirectX 编程编程

// // 定义定义 FVFFVF 的顶点结构的顶点结构struct CUSTOMVERTEXstruct CUSTOMVERTEX{{

float x, y, z; float x, y, z; //// 顶点坐标顶点坐标DWORD color; DWORD color; //// 顶点颜色顶点颜色

};};//// 定义定义 FVFFVF 用到的数据项:坐标颜色用到的数据项:坐标颜色#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ | D3DFVF_DIFFUSE)#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ | D3DFVF_DIFFUSE)class CEx_D3DView : public CViewclass CEx_D3DView : public CView{{

……};};

(8) 在 Direct3D 中,所有的三维实体都是由三角形构成的。对于三角形的顶点格式, Direct3D采用了一种被称之为“可变形顶点格式 Flexible Vertex Format(FVF)” 的技术。打开 Ex_D3DView.h 文件,在 class CEx_D3DView 前面添加下列代码:

Page 14: 9.1.1    图像处理

9.1.5 DirectX9.1.5 DirectX 编程编程

protected:protected:LPDIRECT3D9LPDIRECT3D9 m_pD3D; m_pD3D; // Direct3D // Direct3D 对象的接口指针对象的接口指针LPDIRECT3DDEVICE9 m_pDevice;LPDIRECT3DDEVICE9 m_pDevice; // // 设备对象的接口指针设备对象的接口指针LPDIRECT3DVERTEXBUFFER9 m_pVB; // LPDIRECT3DVERTEXBUFFER9 m_pVB; // 顶点缓存区的的接口指针顶点缓存区的的接口指针void InitGeometry();void InitGeometry();

(9) 在 CEx_D3DView 类定义一个用于顶点缓存区的的接口指针对象及构造三角形的函数 InitGeometry ,如下面的代码:

(10) 在 CEx_D3DView::InitGeometry 函数中添加代码: (11) 在 CEx_D3DView::OnDestroy 函数中添加代码: (12) 在 CEx_D3DView::OnDraw 函数中添加代码:

Page 15: 9.1.1    图像处理

9.1.5 DirectX9.1.5 DirectX 编程编程(13) 编译并运行,结果如图所示。

Page 16: 9.1.1    图像处理

9.1.5 DirectX9.1.5 DirectX 编程编程

void CEx_D3DView::OnInitialUpdate() void CEx_D3DView::OnInitialUpdate() {{……

// // 因为使用顶点颜色渲染,所以要禁用光照处理因为使用顶点颜色渲染,所以要禁用光照处理m_pDevice->SetRenderState( D3DRS_LIGHTING, FALSE );m_pDevice->SetRenderState( D3DRS_LIGHTING, FALSE );// // 关闭“挑选”功能,允许渲染背面关闭“挑选”功能,允许渲染背面m_pDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE );m_pDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE );

}}

(14) 上述显示的结果是一个黑色的三角形,要想显示出其颜色,还需要在 CEx_D3DView:: OnInitialUpdate 函数中添加下列代码:

Page 17: 9.1.1    图像处理

9.1.5 DirectX9.1.5 DirectX 编程编程(15) (15) 再次编译并运行,最后的结果如图所示 再次编译并运行,最后的结果如图所示

Page 18: 9.1.1    图像处理

9.1.5 DirectX9.1.5 DirectX 编程编程3. 3. 使用使用 DirectXDirectX 向导向导

Page 19: 9.1.1    图像处理

9.1.5 DirectX9.1.5 DirectX 编程编程 Ex_DirectX运行结果

Page 20: 9.1.1    图像处理

9.2.1 DLL9.2.1 DLL 的概念的概念 DLLDLL 是建立在客户是建立在客户 // 服务器通信的概念上,包含若干函数、类或资服务器通信的概念上,包含若干函数、类或资

源的库文件,函数和数据被存储在一个源的库文件,函数和数据被存储在一个 DLL(DLL( 服务器服务器 ))上并由一个或上并由一个或多个客户导出而使用,这些客户可以是应用程序或者是其它的多个客户导出而使用,这些客户可以是应用程序或者是其它的 DLLDLL 。。DLLDLL 库不同于静态库,在静态库情况下,函数和数据被编译进一个二库不同于静态库,在静态库情况下,函数和数据被编译进一个二进制文件进制文件 ((通常扩展名为通常扩展名为 *.LIB)*.LIB) ,, Visual C++Visual C++ 的编译器在处理程序代的编译器在处理程序代码时将从静态库中恢复这些函数和数据并把他们和应用程序中的其他码时将从静态库中恢复这些函数和数据并把他们和应用程序中的其他模块组合在一起生成可执行文件。这个过程称为“静态链接”,此时模块组合在一起生成可执行文件。这个过程称为“静态链接”,此时因为应用程序所需的全部内容都是从库中复制了出来,所以静态库本因为应用程序所需的全部内容都是从库中复制了出来,所以静态库本身并不需要与可执行文件一起发行。身并不需要与可执行文件一起发行。

Page 21: 9.1.1    图像处理

9.2.2 9.2.2 动态链接库的创建动态链接库的创建 在在 Visual C++ 6.0Visual C++ 6.0 开发环境中,使用应用程序向导中的开发环境中,使用应用程序向导中的 Win3Win32 Dynamic-Link Library2 Dynamic-Link Library 可以创建非可以创建非 MFCMFC 动态库,使用动态库,使用 MFC AMFC AppWizard(dll)ppWizard(dll) 可以创建常规可以创建常规 DLLDLL 和扩展和扩展 DLLDLL 。。

Page 22: 9.1.1    图像处理

9.2.3 9.2.3 动态链接库的访问动态链接库的访问 (1) 用 MFC AppWizard创建一个默认的单文档应用程序 Ex_USEDLL ,但在向导的第 5步MFC 库设为使用静态链接库,如图所示。(2) 将 Ex_DLL 工程中的 Debug目录中的 Ex_DLL.dll 、 Ex_DLL.lib两个文件复制到 Ex_USEDLL 工程目录中。

Page 23: 9.1.1    图像处理

1. 创建一个 ActiveX 控件程序 选择“文件”“新

建”菜单,在弹出的“新建”对话框中选择“工程”标签,这时显示出一系列的应用程序项目类型。选择M

FC AppWizard(dll) 的项目类型,在工程框中输入项目名 Ex_O

CX ,结果如图所示。

9.3.1 9.3.1 创建创建 ActiveXActiveX 控件控件

Page 24: 9.1.1    图像处理

9.3.1 9.3.1 创建创建 ActiveXActiveX 控件控件向导第 1步对话框 向导第 2步对话框

Page 25: 9.1.1    图像处理

9.3.1 9.3.1 创建创建 ActiveXActiveX 控件控件创 建 的 程 序 框 架

Page 26: 9.1.1    图像处理

9.3.1 9.3.1 创建创建 ActiveXActiveX 控件控件3. 3. 属性的添加属性的添加

按 Ctrl+W快捷键,打开 MFC ClassWizard对话框。单击 [Add Property](添加属性 ) 按钮,弹出如图所示的对话框。

Page 27: 9.1.1    图像处理

9.3.1 9.3.1 创建创建 ActiveXActiveX 控件控件4. 4. 属性表的建立属性表的建立

BEGIN_PROPPAGEIDS(CEx_OCXCtrl, 1)

PROPPAGEID(CEx_OCXPropPage::guid)

END_PROPPAGEIDS(CEx_OCXCtrl)

(1) 打开 Ex_OCXCtl.cpp 文件,在靠前的部分中可以看到下面的代码:

BEGIN_PROPPAGEIDS(CEx_OCXCtrl, 2)

PROPPAGEID(CEx_OCXPropPage::

guid)

PROPPAGEID(CLSID_CColorPropPage)

END_PROPPAGEIDS(CEx_OCXCtrl)

(2) 为库存属性 ForeColor 建立属性页,如下面的代码。

Page 28: 9.1.1    图像处理

9.3.1 9.3.1 创建创建 ActiveXActiveX 控件控件 (3)(3)将项目工作区切换到“将项目工作区切换到“ ResourcResourceView”eView”页面,打开页面,打开 IDD_PROPPAIDD_PROPPAGE_EX_OCXGE_EX_OCX 对话框资源,将其字对话框资源,将其字体设置为“宋体,体设置为“宋体, 99 号”,并添加号”,并添加如图所示的控件,取默认的如图所示的控件,取默认的 IDID 号号 ..(4) 按 Ctrl+W快捷键,打开 MFC ClassWizard对话框,切换到“ Member Variables”页面,选择类名为 CEx_OCXPropPage ,双击控件 ID号,按表所示为控件添加相关联的变量,是设置 IDC_EDIT1 控件与 nHatch 属性相关联的变量时的对话框。

Page 29: 9.1.1    图像处理

9.3.1 9.3.1 创建创建 ActiveXActiveX 控件控件

BOOL CEx_OCXPropPage::OnInitDialog() BOOL CEx_OCXPropPage::OnInitDialog() { { COlePropertyPage::OnInitDialog();COlePropertyPage::OnInitDialog();

m_Spin.SetRange(0, 5);m_Spin.SetRange(0, 5);return TRUE; // return TRUE unless you set the focus to a contrreturn TRUE; // return TRUE unless you set the focus to a contr

olol}}

(5) 将 MFC ClassWizard对话框切换到“ Message Maps”页面,为 CEx_OCXPropPage 类添加 WM_INITDIALOG 消息映射,并添加下列代码 ︰

Page 30: 9.1.1    图像处理

9.3.1 9.3.1 创建创建 ActiveXActiveX 控件控件5. 5. 事件的添加事件的添加

用 MFC ClassWizard 可以方便地进行 ActiveX 控件的事件的添加

Page 31: 9.1.1    图像处理

9.3.2 9.3.2 测试和使用测试和使用 ActiveXActiveX 控件控件1.使用 ActiveX Control Text Container

测试属性和方法 属性对话框

Page 32: 9.1.1    图像处理

9.3.2 9.3.2 测试和使用测试和使用 ActiveXActiveX 控件控件2. 2. 在在 Visual C++Visual C++ 程序中使用程序中使用

Page 33: 9.1.1    图像处理

9.4.1 9.4.1 进程和线程进程和线程 进程是应用程序的执行实例,每个进程是由私有的虚拟地址空间、进程是应用程序的执行实例,每个进程是由私有的虚拟地址空间、

代码、数据和其它系统资源组成。进程在运行时创建的资源随着进程代码、数据和其它系统资源组成。进程在运行时创建的资源随着进程的终止而死亡。线程是一个独立的执行流,是进程内部的一个独立的的终止而死亡。线程是一个独立的执行流,是进程内部的一个独立的执行单元,相当于一个子程序,它对应执行单元,相当于一个子程序,它对应 Visual C++Visual C++ 中的中的 CWinThreadCWinThread类的对象。单独一个执行程序运行时,默认运行包含一个主线程,主类的对象。单独一个执行程序运行时,默认运行包含一个主线程,主线程以函数地址的形式提供程序的启动点,如线程以函数地址的形式提供程序的启动点,如 mainmain或或 WinMainWinMain函函数。当主线程终止时,进程也随之终止,但根据需要,应用程序又可数。当主线程终止时,进程也随之终止,但根据需要,应用程序又可以分解成许多独立执行的线程,每个线程并行的运行在同一进程中。以分解成许多独立执行的线程,每个线程并行的运行在同一进程中。

Page 34: 9.1.1    图像处理

9.4.2 9.4.2 线程的管理和操作线程的管理和操作1. 1. 线程的启动线程的启动

创建一个用户界面线程,首先要从CWinThread类产生一个派生类,同时必须使用 DECLARE_DYNCREATE和 IMPLEMENT_DYNCREATE来声明和实现该 CWinThread 派生类。 第二步是根据需要重载该派生类的一些成员函数,如 ExitInstance、 InitInstance、 OnIdle、 PreTranslateMessage等函数,最后启动该用户界面线程,调用其中一个版本的 AfxBeginThread函数,如下面的函数原型: CWinThread* AfxBeginThread( CRuntimeClass* pThreadClass, int nPriority = THREAD_PRIORITY_NORMAL, UINT nStackSize = 0, DWORD dwCreateFlags = 0, LPSECURITY_ATTRIBUTES lpSecurityAttrs = NULL );

Page 35: 9.1.1    图像处理

9.4.2 9.4.2 线程的管理和操作线程的管理和操作2. 2. 线程的优先级线程的优先级

CWinThread 类中有以下两个成员函数用于线程优先级的操作:int GetThreadPriority();

BOOL SetThradPriority(int nPriority);

3. 线程的悬挂和恢复 CWinThread 类中,成员函数 SuspendThread 用来悬挂线程,暂停线程的执行, ResumeThread 用来恢复线程的执行。

4. 终止线程 终止线程有三种途径:一是可以在线程自身内部调用 AfxEndThread 来终止自身的运行;二是可以在线程的外部调用 TerminateThread 来强行终止一个线程的运行,然后调用 CloseHandle 函数释放线程所占用的堆栈;第三种方法是改变全局变量,使线程的执行函数返回,则该线程终止。

Page 36: 9.1.1    图像处理

9.4.3 9.4.3 线 程 通 信线 程 通 信

BOOL bEnd = FALSE;BOOL bEnd = FALSE; // // 定义的全局变量,用于控制线程的运行定义的全局变量,用于控制线程的运行CWinThreadCWinThread *pThread;*pThread;HWNDHWND hWnd;hWnd;UINT MyThreadFunc(LPVOID pParam)UINT MyThreadFunc(LPVOID pParam) // // 线程函数线程函数{{ while(!bEnd){while(!bEnd){ Beep(100,100);Beep(100,100); Sleep(1000);Sleep(1000);}}return 0;}return 0;}void CEx_ThreadView::OnInitialUpdate() void CEx_ThreadView::OnInitialUpdate() {{ hWnd = GetSafeHwnd();hWnd = GetSafeHwnd();pThread = AfxBeginThread(MyThreadFunc, hWnd); // pThread = AfxBeginThread(MyThreadFunc, hWnd); // 启动线程启动线程pThread->m_bAutoDelete = FALSE;pThread->m_bAutoDelete = FALSE; // // 线程设为手动删除线程设为手动删除CView::OnInitialUpdate();CView::OnInitialUpdate();}}

1. 利用用户定义的消息通信(1) 用 MFC AppWizard(exe) 创建一个默认的单文档应用程序 Ex_Thread 。(2) 用 MFC ClassWizard 为 CEx_ThreadView 类添加 OnInitialUpdate 的重载,并添加下列代码:

Page 37: 9.1.1    图像处理

(3) (3) 用用 MFC ClassWizardMFC ClassWizard 为为 CEx_ThreadViewCEx_ThreadView 类添加类添加 WM_DESTROYWM_DESTROY消息映射并添加下列代码:消息映射并添加下列代码:

void CEx_ThreadView::OnDestroy() void CEx_ThreadView::OnDestroy() {{ bEnd = TRUE;bEnd = TRUE; // // 改变变量,线程结束改变变量,线程结束WaitForSingleObject(pThread->m_hThread, INFINITE);WaitForSingleObject(pThread->m_hThread, INFINITE); // // 等待线程结束等待线程结束delete pThread;delete pThread; //// 删除线程删除线程CView::OnDestroy();CView::OnDestroy();}}

#define WM_USERMSG WM_USER + 200 lass CEx_ThreadView : public CView{…}

(4) 开 Ex_ThreadView.h 文件,在 class CEx_ThreadView语句前面添加用户消息的定义代码:

9.4.3 9.4.3 线 程 通 信线 程 通 信

Page 38: 9.1.1    图像处理

9.4.3 9.4.3 线 程 通 信线 程 通 信

UINT MyThreadFunc(LPVOID pParam)UINT MyThreadFunc(LPVOID pParam) // // 线程函数线程函数{{

while(!bEnd){while(!bEnd){Beep(100,100);Beep(100,100); Sleep(1000);Sleep(1000);}}::PostMessage(hWnd, WM_USERMSG, 0, 0);// ::PostMessage(hWnd, WM_USERMSG, 0, 0);// 发出用户消息发出用户消息return 0;return 0;

}}

(5) 打开 Ex_ThreadView.cpp ,找到映射消息的入口,添加代码(6) 在头文件 Ex_ThreadView.h 的消息声明处添加代码 (7) 在 Ex_ThreadView.cpp 文件的后面添加 OnUserMessage 函数的实现代码 (8) 在 MyThreadFunc 函数中添加下列代码:

Page 39: 9.1.1    图像处理

9.4.3 9.4.3 线 程 通 信线 程 通 信

void CEx_ThreadView::OnLButtonDown(UINT nFlags, CPoint point) void CEx_ThreadView::OnLButtonDown(UINT nFlags, CPoint point) {{bEnd = TRUE;bEnd = TRUE;CView::OnLButtonDown(nFlags, point);CView::OnLButtonDown(nFlags, point);

}}

(9) 用 MFC ClassWizard 为 CEx_ThreadView 类添加 WM_LBUTTONDOWN

消息映射,并添加下列代码:

(10) 编译运行。在视图客户区单击鼠标后,稍后就会出现一个消息对话框。

Page 40: 9.1.1    图像处理

9.4.3 9.4.3 线 程 通 信线 程 通 信

void CEx_ThreadView::OnInitialUpdate() void CEx_ThreadView::OnInitialUpdate() {{

hWnd = GetSafeHwnd();hWnd = GetSafeHwnd();eStart.SetEvent();eStart.SetEvent(); // teStart// teStart 事件有信号事件有信号pThread = AfxBeginThread(MyThreadFunc, hWnd);pThread = AfxBeginThread(MyThreadFunc, hWnd); // // 启动线程启动线程pThread->m_bAutoDelete = FALSE;pThread->m_bAutoDelete = FALSE; // // 线程设为手动删除线程设为手动删除CView::OnInitialUpdate();CView::OnInitialUpdate();

}}

2. 用事件对象实现通信修改 CEx_ThreadView::OnInitialUpdate 函数代码:

Page 41: 9.1.1    图像处理

9.4.4 9.4.4 线程同步线程同步

临界区是保证在某一个时间内只有一个线程可以访问数据的方法。临界区被释放后,另外的线程可以强占这个临界区,以便访问共享的数据。1. 临界区

2. 互斥 互斥与临界区很相似,但是使用时相对复杂一些。它不仅可以在同一应用程序的线程间实现同步,还可以在不同的进程间实现同步,从而实现资源的安全共享。

3. 信号量 信号量的用法和互斥的用法很相似,不同的是它可以同一时刻允许多个线程访问同一个资源。

Page 42: 9.1.1    图像处理

9.5.1 概 述1. Socket1. Socket 支持支持Socket 是一种网络编程接口,最初仅适用于 UNIX操作系统。随Windows操作系统的普及,微软和 Sun公司开发的基于 Windows操作系统的网络编程接口——Windows Sockets, Windows Sockets 编程是 Windows 网络编程的基础。

2. WinInet支持使用 WinInet 编写的 Internet 客户应用程序可以用 Internet协议 ( 如 Http 、 FTP 和 Gopher)从网络服务器上访问信息。 3. MAPI支持

如果要使开发的应用程序可以创建、操作、传输和存储邮件信息,则必须添加并提供 MAPI(Message API)支持。 4. ISAPI支持ISAPI(Internet Server API) 提供了一种简单有效的方法来扩展与 ISAPI兼容的WEB服务器。 ISAPI服务扩展是一个动态链接库 (DLL) ,可以被 HTTP服务器调用和装载。

Page 43: 9.1.1    图像处理

9.5.2 Windows Sockets 9.5.2 Windows Sockets 编程编程1. Windows Sockets 编程机制 (1) 启动和终止

由于 Windows Sockets 的主要服务是以动态链接库 WINSOCK.DLL 形式实现的,所以在使用任何其它的 Windows Sockets API 调用之前,

(2) 异步选择机制 Windows 程序设计是事件来进行驱动的。异步选择机制正是为了在 Windows Sockets 编程中提供一种网络事件驱动的程序设计方法。 (3) 异步请求机制

在 Windows Sockets 中,异步请求函数允许应用程序用异步方式获得请求的信息,如 WSAAsyncGetHostByAddr 等函数。

Page 44: 9.1.1    图像处理

9.5.2 Windows Sockets 9.5.2 Windows Sockets 编程编程2. Windows Sockets2. Windows Sockets 编程示例编程示例

Page 45: 9.1.1    图像处理

9.5.3 WinInet9.5.3 WinInet 应用应用 WinInet是以 WinSock 为基础,是比Winsock更高层的 API ,它在编写高性能的客户程序方面远远超过了WinSock 。