简介:本书深入介绍使用Microsoft的Visual C++进行图形用户界面(GUI)开发的过程,涵盖了MFC库的理解与应用,文档/视图架构的核心概念,GUI设计的资源编辑器使用,标准控件的自定义行为,以及事件驱动编程的基本原理。本书还介绍了如何利用ActiveX控件和COM技术,以及如何通过ATL和MFC ActiveX控件创建可重用组件。掌握这些技术对于开发Windows应用程序至关重要。
1. Visual C++界面编程基础
理解界面编程的重要性
在现代软件开发中,用户界面(UI)是与用户交互的重要桥梁,它直接影响用户体验。Visual C++作为一种强大的开发工具,提供了丰富的界面编程接口和组件。掌握Visual C++界面编程,可以让开发者构建功能丰富、操作直观的应用程序。
掌握基本概念
界面编程不仅仅涉及控件的拖放,更重要的是理解事件处理、消息机制和用户交互逻辑。Visual C++的界面编程基础包括对话框、控件类、属性设置等方面。这些基础知识是构建复杂界面的基石。
开始界面编程
Visual C++通常使用MFC(Microsoft Foundation Classes)库进行界面编程。从创建一个新的MFC应用程序开始,我们可以利用Visual Studio的向导来生成一个基础的界面框架。开发者需要熟悉MFC的文档-视图结构,了解如何使用工具栏、菜单栏、状态栏和各种控件来构建应用界面。
一个简单的Visual C++界面编程示例可以如下编写:
// MyDialog.h
class CMyDialog : public CDialog
{
// ... 类的声明
};
// MyDialog.cpp
BOOL CMyDialog::OnInitDialog()
{
CDialog::OnInitDialog();
// 初始化界面元素,例如设置按钮文本等
SetWindowText(_T("这是一个示例对话框"));
return TRUE;
}
// 在应用程序的某个地方使用对话框
CMyDialog dlg;
dlg.DoModal();
在上面的代码示例中,我们定义了一个名为 CMyDialog
的对话框类,并在其初始化函数 OnInitDialog
中设置了对话框的标题。创建对话框对象并调用 DoModal
来显示对话框。这只是界面编程中的一小部分,更多深入的内容会在后续章节中展开讨论。
2. MFC库及其在GUI开发中的应用
2.1 MFC库概述
2.1.1 MFC的结构和组成
MFC(Microsoft Foundation Classes)库是微软公司提供的一套C++类库,它封装了大部分Windows API,并为开发Windows应用程序提供了框架和对象模型。MFC的主要目的是简化基于Windows平台的GUI(Graphical User Interface)开发。
MFC库的核心组件包括以下几个部分:
- 文档-视图结构: MFC推荐使用文档/视图架构来分离数据和显示逻辑,这在复杂的应用程序中是极其重要的。
- 应用程序类: 包括CWinApp及其派生类,用于管理整个应用程序的生命周期。
- 窗口框架: CFrameWnd类及其派生类用于表示应用程序的主窗口和子窗口。
- 控件类: 包括按钮、编辑框、列表框等控件类,简化了这些控件的使用。
- 绘图和打印: 提供了绘图设备上下文(CDC)和打印相关的类。
- 集合和字符串: 包括各种容器类和字符串处理类。
通过封装底层的Win32 API调用,MFC能够提供更加直观和面向对象的编程接口,但同时也增加了一定程度的抽象层次。了解MFC的结构和组成是掌握其在GUI开发中应用的基础。
2.1.2 MFC与Win32 API的关系
虽然MFC是封装Win32 API的高级库,但MFC并不是完全独立于Win32 API的。实际上,MFC在底层仍然使用Win32 API来完成大部分工作,只是将这些调用封装在了更加面向对象的类中。这种设计使得MFC程序可以享有Win32 API的强大功能,同时拥有面向对象编程的优势,比如代码复用、模块化等。
开发者在使用MFC时不需要直接与Win32 API打交道,但如果需要实现更底层的功能,或者进行性能优化,直接使用Win32 API调用会更加高效。因此,了解MFC和Win32 API之间的关系对于深度定制和优化MFC程序是很有帮助的。
2.2 MFC基本类的应用
2.2.1 CWinApp类的作用和使用
CWinApp
是MFC中所有应用程序类的基类。它负责维护整个应用程序的状态信息,并处理应用程序的启动和终止。
创建一个MFC应用程序通常涉及创建一个 CWinApp
的派生类,并在其中重写 InitInstance
方法,该方法包含应用程序初始化时的代码。例如,启动应用程序的主窗口就是在这个方法中完成的。
class CMyApp : public CWinApp
{
public:
virtual BOOL InitInstance();
};
BOOL CMyApp::InitInstance()
{
m_pMainWnd = new CMyFrameWnd();
m_pMainWnd->ShowWindow(m_nCmdShow);
m_pMainWnd->UpdateWindow();
return TRUE;
}
上面的代码展示了如何通过创建一个MFC应用程序的实例来启动主窗口。在 InitInstance
方法中,我们创建了主窗口的实例,并显示它。
2.2.2 CFrameWnd类与窗口框架
CFrameWnd
类用于创建窗口框架,通常是应用程序的主窗口或者MDI(Multiple Document Interface)框架窗口。它管理窗口的创建、销毁以及窗口的其他属性。
创建一个窗口框架需要实例化 CFrameWnd
或者它的派生类,并且可以设置窗口的标题、大小和其他属性。例如:
class CMyFrameWnd : public CFrameWnd
{
public:
CMyFrameWnd();
};
CMyFrameWnd::CMyFrameWnd()
{
Create(NULL, _T("My Application Window"));
// 其他窗口创建后的设置代码...
}
通过上述代码,我们可以创建一个具有默认大小和标题的窗口框架。开发者可以进一步添加菜单、工具栏和状态栏等,来丰富窗口的功能。
2.2.3 CDocument类与文档管理
CDocument
类负责管理应用程序中的数据,通常与视图关联起来,使得视图可以显示和编辑文档内容。文档类是文档/视图架构中的关键部分,它将数据模型与视图模型分开。
为了使用 CDocument
类,我们需要创建其派生类,并在其中定义自己的数据结构。在文档类中,还应实现数据的加载和保存方法。
class CMyDoc : public CDocument
{
protected:
// 声明文档类的属性,例如:
// CArchive m_strData;
public:
virtual BOOL OnNewDocument();
virtual void Serialize(CArchive& ar);
};
BOOL CMyDoc::OnNewDocument()
{
// 初始化新文档,例如清空数据等
return CDocument::OnNewDocument();
}
void CMyDoc::Serialize(CArchive& ar)
{
// 实现数据的保存和加载
if (ar.IsStoring())
{
// 将数据写入到archive中
}
else
{
// 从archive中读取数据
}
}
这段代码展示了如何创建文档类以及其基本的序列化方法。序列化功能对于文档的持久化和读取是不可或缺的,开发者可以根据实际需要扩展序列化的逻辑。
2.3 MFC消息映射机制
2.3.1 消息映射的工作原理
MFC的消息映射机制是它与Win32 API相比,大大简化了事件驱动编程的复杂性。消息映射将窗口过程函数中的消息处理代码转换为更加面向对象的代码。
消息映射通过宏定义将消息映射到类的成员函数。这些映射宏通常包含消息类型和对应的处理函数。例如, ON_COMMAND
宏用于映射命令消息到处理函数。
BEGIN_MESSAGE_MAP(CMyFrameWnd, CFrameWnd)
ON_COMMAND(ID_FILE_NEW, &CMyFrameWnd::OnFileNew)
ON_WM_PAINT()
END_MESSAGE_MAP()
在上面的代码中, ON_COMMAND
宏用于将文件新建命令映射到 OnFileNew
函数, ON_WM_PAINT
宏用于处理窗口绘制消息。
2.3.2 消息处理函数的编写
消息处理函数是应用程序响应各种消息(如键盘事件、鼠标事件、窗口消息等)的入口点。编写消息处理函数时,需要了解不同消息的参数和返回值。
对于命令消息,如 OnFileNew
函数,它通常不带参数。而对于窗口消息,如 OnPaint
函数,它需要处理 CPaintDC
对象来进行绘图操作。
void CMyFrameWnd::OnFileNew()
{
// 文件新建的处理逻辑
}
void CMyFrameWnd::OnPaint()
{
CPaintDC dc(this); // 设备上下文用于绘制
// 在这里添加绘图代码
}
在编写消息处理函数时,要注意遵循MFC约定,例如对于 OnPaint
函数,必须使用 CPaintDC
对象来避免绘图过程中的闪烁。
以上章节内容展示了MFC库的结构组成、基本类的应用,以及消息映射机制的工作原理和消息处理函数的编写方法。这些知识为MFC编程打下了坚实的基础,并为后续章节中更加复杂的话题提供了必要的铺垫。接下来将深入探讨文档/视图架构及其设计模式,这是MFC高级应用中的核心内容。
3. 文档/视图架构及其设计模式
3.1 文档/视图架构解析
文档/视图架构是MFC应用程序中用于分离数据和视图的一种设计模式。这种架构不仅将用户界面的展现与数据内容的处理解耦,而且提高了代码的可维护性和可扩展性。
3.1.1 架构的核心概念和组成部分
文档/视图架构主要有三个核心部分组成:文档(document)、视图(view)和框架窗口(frame window)。文档对象负责数据的存储和管理,视图对象则负责数据的显示和与用户的交互,而框架窗口为文档和视图提供了用户界面的外壳。
在文档/视图架构中,一个文档对象可以拥有多个视图,每个视图都可以以不同的方式显示文档内容。例如,一个文档对象可以同时拥有一个普通文本视图和一个图形视图。
3.1.2 文档与视图的交互机制
文档和视图之间的交互主要通过一系列预定义的消息映射实现。MFC提供了一系列的消息映射宏来处理文档和视图之间的通信,比如 OnDraw()
函数用于绘制视图, UpdateAllViews()
用于通知所有视图文档已更新。
举个例子,当文档数据发生变化时,通过调用 UpdateAllViews()
,所有相关的视图都会更新显示内容。而当用户在视图中进行某些操作(如滚动视图),相应的视图会通知文档对象进行处理。
3.2 设计模式在架构中的应用
文档/视图架构实际上体现了软件设计中非常著名的模型-视图-控制器(MVC)模式。这种设计模式通过分离数据处理(模型)、数据展示(视图)和用户交互(控制器),使得系统更容易适应需求的变化。
3.2.1 MVC模式与文档/视图架构
在MFC的文档/视图架构中,文档对象充当模型的角色,负责处理和存储数据;视图对象则类似于MVC中的视图,负责数据的显示;而文档的打开、保存等操作则可以看作是控制器的职责。将这些功能分离可以使得每个部分都相对独立,便于维护和扩展。
3.2.2 设计模式的选择和实现
设计模式的选择依赖于应用程序的具体需求和设计目标。在选择设计模式时,需要权衡不同模式的优缺点和适用场景。例如,如果应用程序需要支持多种视图来展示同一数据源,那么MVC模式是一个很好的选择。在实现时,则需要详细设计每个类和对象的职责、接口以及它们之间的通信方式。
通过精心设计和实现文档/视图架构以及相应的设计模式,开发者可以构建出结构清晰、易于理解和维护的MFC应用程序。下一章节将探讨资源编辑器在界面设计中的作用和重要性。
4. 资源编辑器在界面设计中的作用
4.1 资源编辑器的界面设计功能
4.1.1 资源的分类和编辑
资源编辑器是Visual C++开发环境中的一个重要组件,它允许开发者以可视化方式创建和编辑应用程序的资源。资源包括程序中用到的所有非代码元素,比如图标、菜单、对话框、字符串和位图等。这些资源通常与程序的源代码分离存放,有助于维护和更新程序的用户界面。
通过资源编辑器,开发者可以避免直接编码界面元素,使得界面设计更加直观。资源编辑器提供了丰富的控件和工具,允许开发者快速构建标准的用户界面组件。例如,对话框编辑器允许用户拖放按钮、文本框等控件到对话框模板中,并设置其属性。
4.1.2 图标、菜单和对话框的创建
在资源编辑器中,创建图标、菜单和对话框是开发者日常工作的一部分。这些元素是构成应用程序用户界面的关键组件,它们直接影响到用户体验。
图标是应用程序的象征,通常显示在窗口的标题栏或任务栏中。资源编辑器提供了画板工具,用户可以通过像素级的操作绘制或修改图标。菜单编辑器允许用户设计程序的菜单栏和上下文菜单。开发者可以添加菜单项,设置快捷键,并定义每个菜单项的动作。对话框编辑器是创建和定制对话框的工具,开发者可以添加控件,设计布局,并处理用户的输入。
4.2 资源与代码的结合
4.2.1 资源文件与源代码的关联
资源文件(通常以 .rc
为扩展名)是包含资源定义的文本文件,它们与C++源代码通过 #include
指令关联。在项目中,资源文件被编译器处理,转换成二进制资源,然后链接到最终的可执行文件中。
当资源被修改后,开发者需要更新资源文件并重新编译。为了确保资源与代码正确关联,开发者需要使用资源标识符。这些标识符是开发者在资源编辑器中为每个资源指定的唯一标识,它们在源代码中通过宏定义出现,使得代码可以引用对应的资源。
4.2.2 资源更新后的代码修改方法
当资源发生变化时,开发者需要在代码中作出相应的调整。例如,如果添加了新的菜单项,就需要在代码中添加处理该菜单项动作的事件处理函数。如果更改了对话框布局,相关的对话框处理代码也需要更新以匹配新的布局。
一种常见的做法是使用类向导(Class Wizard)来管理资源和代码之间的关联。类向导可以自动生成处理资源事件的代码框架,减少手动编辑的错误。此外,开发者需要在源代码中引用资源标识符,使用这些标识符来加载资源和访问资源属性。
代码示例:
// 假设有一个菜单资源ID为ID_FILE_NEW
void CYourApp::OnFileNew()
{
// 处理新建文件的逻辑
}
// 假设有一个对话框资源ID为IDD_YOUR_DIALOG
void CYourApp::ShowYourDialog()
{
CYourDialog dlg;
dlg.DoModal();
}
在上述代码中, OnFileNew
函数和 ShowYourDialog
函数分别处理了菜单项点击事件和对话框显示的逻辑。资源与代码之间的关联通过资源标识符(如 ID_FILE_NEW
和 IDD_YOUR_DIALOG
)来实现。
资源编辑器与代码的结合使得Visual C++的界面编程更为高效和直观。理解这一过程对于设计动态且易于维护的用户界面至关重要。通过不断更新和优化,开发者可以确保应用程序的用户界面与功能需求保持同步。
5. 控件使用与自定义
5.1 标准控件的使用
在图形用户界面(GUI)编程中,标准控件提供了与用户进行交互的基本元素,如按钮、文本框、列表框等。这些控件的使用可以大大加快开发进程,提高程序的可用性和美观性。本节将深入探讨如何使用标准控件,包括它们的属性、事件以及如何进行布局和样式定制。
5.1.1 常用控件的属性和事件
标准控件种类繁多,每种控件都有一系列的属性和事件,允许开发者控制其行为和外观。以按钮控件为例,我们可以设置其文本、大小、位置等属性,并且可以通过关联不同的事件处理器来响应用户的点击动作。
下面是一个简单按钮控件使用的示例代码:
CButton m_button; // 定义按钮对象
m_button.Create(_T("Click Me"), WS_VISIBLE | WS_CHILD | BS_PUSHBUTTON,
CRect(10, 10, 100, 30), this, IDC_MY_BUTTON); // 创建按钮
该代码创建了一个按钮控件,并设置了其显示文本、样式和位置。 IDC_MY_BUTTON
是该按钮的标识符,用于后续引用和事件处理。
事件处理方面,按钮控件最常见的事件是 BN_CLICKED
,它在用户点击按钮时触发。开发者需要为该事件编写一个事件处理函数,如:
void CYourDialog::OnBnClickedButton()
{
AfxMessageBox(_T("Button clicked!"));
}
5.1.2 控件的布局和样式定制
布局管理是指定控件在界面上的位置和尺寸的过程。在MFC中,可以使用布局控制类如 CFormView
、 CDialog
等来管理布局。此外,可以通过编程方式动态调整控件的属性,比如大小、颜色和字体等。
以下是一个定制控件样式的方法:
CButton m_button;
m_button.SetTextColor(RGB(255, 0, 0)); // 设置按钮文字颜色为红色
m_button.SetFont(&font, TRUE); // 设置按钮文字字体
其中 font
是预定义的 CFont
对象, RGB
宏用于定义颜色。
5.2 自定义控件的创建和应用
当标准控件不能满足特定需求时,可以创建自定义控件。自定义控件可以是现有控件的扩展,也可以是完全新设计的控件。创建自定义控件的过程涉及到了解控件的绘制机制,事件处理以及如何将控件集成到应用程序中。
5.2.1 自定义控件的基本步骤
创建自定义控件通常包括以下几个步骤:
-
继承和实现 :选择一个合适的MFC类作为基类(如
CButton
),创建一个派生类并在其中实现特定功能。 -
消息映射 :在派生类中添加消息映射,以便处理特定的窗口消息,如鼠标点击、绘制等。
-
控件绘制 :重写
OnPaint()
方法来定制控件的外观。 -
属性和事件 :添加新的属性和事件,可以使用
DDX/DDV
机制和控件消息来实现。 -
注册控件 :使用
AfxRegisterControlClass
函数在应用程序启动时注册自定义控件。
下面是一个简单的自定义控件示例代码:
class CMyButton : public CButton
{
public:
afx_msg void OnPaint();
DECLARE_MESSAGE_MAP()
// 其他自定义功能...
};
BEGIN_MESSAGE_MAP(CMyButton, CButton)
ON_WM_PAINT()
// 其他消息映射...
END_MESSAGE_MAP()
void CMyButton::OnPaint()
{
CPaintDC dc(this); // 设备上下文
// 绘制自定义按钮
}
5.2.2 自定义控件的样式和行为
自定义控件不仅要在视觉上与众不同,还要有独特的行为和交互方式。开发者可以利用MFC提供的绘图工具和消息处理机制来赋予控件这些特性。
例如,可以实现以下功能来增强控件的交互性:
- 视觉效果 :通过绘制复杂的背景、渐变色、图片等。
- 特殊行为 :响应非标准的鼠标事件,如
WM_MOUSEMOVE
来实现悬浮效果。 - 状态反馈 :自定义控件通过改变视觉样式来反馈不同的状态,比如启用/禁用状态。
最终,这些控件可以通过资源编辑器添加到资源文件中,并在对话框或其他容器控件中实例化使用。自定义控件的应用不仅丰富了用户的界面体验,也为开发者提供了极大的灵活性和扩展性。
通过这些示例和步骤,我们可以看到自定义控件为我们的应用程序带来了极大的灵活性和定制能力。下面的表格总结了标准控件与自定义控件的一些对比信息:
特性 | 标准控件 | 自定义控件 |
---|---|---|
开发时间 | 较短,因为大部分功能已经实现 | 较长,需要详细设计和实现 |
功能限制 | 固定,满足大部分标准需求 | 可自定义,没有明显功能限制 |
可扩展性 | 有限 | 强大 |
维护性 | 较容易,因为是标准实现 | 较难,需要对代码有深入了解 |
通过本章节的介绍,我们详细学习了如何在MFC应用程序中使用标准控件,并深入到了如何创建和应用自定义控件。在下一章节中,我们将进一步探讨事件驱动编程的概念,这将帮助我们理解控件事件如何在MFC应用程序中工作。
6. 事件驱动编程概念
6.1 事件驱动编程原理
6.1.1 事件的定义和触发机制
事件驱动编程是现代应用程序开发中的一种核心范式,尤其在图形用户界面(GUI)程序设计中占据主导地位。事件可以被理解为程序运行过程中发生的“事情”,这些“事情”可能是用户输入(如鼠标点击、键盘按键)、系统状态变化(如窗口最小化、最大化)或程序内部事件(如定时器到期、数据加载完成)。
事件的触发机制是基于发布-订阅模式。在这种模式中,事件的生成者(发布者)不会直接调用特定的代码来处理事件,而是“发布”事件通知。事件的消费者(订阅者)则会“订阅”这些事件,并定义当这些事件发生时需要执行的代码,即事件处理程序。
6.1.2 事件与消息的关联
在许多编程环境中,事件最终通过消息的形式呈现给应用程序。消息是一种系统级的信息传递机制,用于通知应用程序发生了一个特定的事件。例如,在Windows操作系统中,几乎所有的用户交互都被转换为消息,并放入应用程序的消息队列中。
在Windows编程中,使用Win32 API或MFC框架时,消息通常是由一个称为消息循环的机制处理的,该机制检查消息队列中的每条消息,并将它们分发到相应的事件处理函数中。这样的设计允许应用程序在等待用户交互或其他事件的同时执行其他任务。
6.2 事件处理机制
6.2.1 事件处理器的设计
事件处理器,也称为事件处理函数或事件处理程序,是当特定事件发生时由事件驱动框架调用的代码块。设计良好的事件处理器应遵循最小化原则,即仅包含与特定事件直接相关的逻辑。
创建事件处理器的一般步骤包括:
- 定义事件处理器函数,包括必要的参数。
- 将事件处理器与事件关联,这可以通过事件处理函数的属性设置、在代码中显式关联或使用特定的编程工具来完成。
- 实现事件处理函数,编写处理事件的逻辑。
在MFC中,事件处理器经常通过消息映射宏与特定的消息或命令ID关联。例如,一个按钮点击事件可能通过消息映射与一个名为 OnBnClickedButton
的函数关联。
// 示例:MFC消息映射宏关联按钮点击事件
ON_BN_CLICKED(IDC_MY_BUTTON, &CMyClass::OnBnClickedButton)
6.2.2 事件的响应与处理流程
事件的响应和处理流程通常包括以下步骤:
- 事件生成:用户操作或系统动作生成一个事件。
- 事件转换:事件被转换为一个或多个消息,这些消息被放入应用程序的消息队列。
- 消息检索:应用程序的消息循环检索队列中的消息。
- 消息分发:消息被分派到对应的事件处理函数。
- 事件处理:事件处理函数根据事件类型执行相应的处理逻辑。
- 结果反馈:处理逻辑执行后,应用程序可能会更新界面或进行其他操作以反馈结果。
处理流程的效率对于应用程序的性能至关重要。为了避免阻塞和提高响应速度,事件处理通常应该是快速的,并且不包含耗时或阻塞的操作。在复杂的情况下,可能需要将耗时的操作放到后台线程中执行,以避免冻结用户界面。
// 示例:简单的按钮点击事件处理函数
void CMyClass::OnBnClickedButton()
{
// 处理按钮点击事件
AfxMessageBox(_T("Button clicked!"));
}
在上述代码中, OnBnClickedButton
函数是一个事件处理器,用于响应按钮点击事件。它简单地显示了一个消息框。
事件驱动编程概念是构建现代GUI应用程序的基础。理解事件的定义、触发机制、事件与消息的关系,以及事件的响应处理流程,对于开发高效、用户友好的应用程序至关重要。下一章将继续深入探讨ActiveX控件与COM技术,这些技术扩展了事件驱动编程的应用范围,特别是在软件组件集成和系统扩展方面。
7. ActiveX控件与COM技术
在现代软件开发中,ActiveX控件和组件对象模型(COM)技术曾经占据了重要的地位。虽然在某些领域它们已经让位给了更加现代化的技术,如.NET,但在许多遗留系统中,ActiveX控件与COM技术仍然扮演着关键角色。
7.1 ActiveX控件基础
7.1.1 ActiveX控件的定义和特点
ActiveX控件是一种可以被嵌入到网页中或者在桌面应用程序中使用的组件。这些控件可以在Internet Explorer等支持ActiveX技术的浏览器中运行,也可以在支持COM技术的桌面应用程序中使用。
ActiveX控件的几个关键特点包括:
- 可重用性 :开发者可以创建一个ActiveX控件,并在多个应用程序中重用它。
- 独立性 :ActiveX控件具有自己的属性、方法和事件,使其可以独立于宿主应用程序运行。
- 可交互性 :控件可以与其他应用程序和控件交互,例如,一个ActiveX控件可以包含另一个ActiveX控件。
7.1.2 ActiveX控件的注册和部署
部署ActiveX控件需要用户在客户端计算机上注册控件。这通常涉及以下步骤:
1. 开发者使用工具如Visual Studio创建ActiveX控件,并将其编译成DLL文件。
2. 使用 Regsvr32
工具注册DLL,使得控件可以被操作系统识别。
3. 在客户端上安装必要的安全证书,特别是当控件需要从Internet下载时,因为现代浏览器和操作系统对从Internet下载的ActiveX控件有严格的安全限制。
7.2 COM技术的核心概念
7.2.1 COM接口和实现
组件对象模型(COM)是一种由微软提出的跨编程语言的二进制接口标准。COM接口定义了一组方法,这些方法可以被调用来操作一个对象。
- 接口 :是定义了一组方法和属性的合约,但不提供实现。COM接口是用GUID(全局唯一标识符)唯一标识的。
- 实现 :是指特定接口的具体代码。一个接口可以由多个不同的对象实现。
7.2.2 COM与OLE技术的关系
COM技术与对象链接和嵌入(OLE)技术有着密切的联系。OLE最初被设计为一种方法,用于创建文档中嵌入的对象,如嵌入到Word文档中的Excel电子表格。
COM为OLE提供了底层的实现细节,使得OLE的实现更为复杂、强大和灵活。随着技术的发展,COM超越了OLE,成为一种广泛用于创建可重用组件和服务的技术标准。
7.3 ATL与MFC ActiveX控件的使用
7.3.1 ATL的介绍和使用场景
活动模板库(ATL)是微软推出的一种用于简化COM接口编程的C++模板库。ATL被设计为一种轻量级的解决方案,它提供了创建COM对象和ActiveX控件所需的基础结构。
使用ATL的场景主要包括:
- 快速开发小型的COM对象。
- 开发需要良好性能的组件。
- 在已有代码中插入COM或ActiveX功能。
7.3.2 MFC与ATL的混合使用策略
在开发复杂的Windows应用程序时,开发者可能会选择将MFC和ATL结合使用,以利用MFC的GUI开发能力和ATL的COM支持。
混合使用MFC和ATL的策略包括:
- 利用MFC的CFrameWnd类来创建窗口框架,使用MFC文档/视图架构管理文档。
- 对于需要提供COM接口的特定功能,可以使用ATL创建轻量级的COM对象。
- 确保MFC和ATL对象之间的正确初始化和资源管理,以防止内存泄漏和其他资源管理问题。
在实际应用中,这可能涉及到创建继承自MFC和ATL类的自定义类,并在其中协调两种技术的交互。由于MFC和ATL在处理消息映射和对象生命周期管理方面存在差异,因此需要特别注意这些方面的整合。
简介:本书深入介绍使用Microsoft的Visual C++进行图形用户界面(GUI)开发的过程,涵盖了MFC库的理解与应用,文档/视图架构的核心概念,GUI设计的资源编辑器使用,标准控件的自定义行为,以及事件驱动编程的基本原理。本书还介绍了如何利用ActiveX控件和COM技术,以及如何通过ATL和MFC ActiveX控件创建可重用组件。掌握这些技术对于开发Windows应用程序至关重要。