一.新建工程■ COM 服 务 程 序 的 类 型:
---- 动 态 连 接 库(Dynamic Linking Library) 最 终 产 生 一 个 动 态 连 接 库(DLL) 形 式 的COM 服 务 程 序;
---- 应 用 程 序(Executable application) 最 终 产 生 一 个 可 执 行 程 序 类 型(EXE) 的COM 服 务 程 序;
---- NT 服 务(NT Service) 产 生 一 个 以NT 服 务 方 式 运 行 的COM 服 务 程 序。
■ 下一组选项
允 许 嵌 入Proxy/Stub 代 码。 由Microsoft 提 供 的MIDL 编 译IDL 文 件 以 后, 将 产 生 用 于 对 象 调 度(Marshaling) 的Proxy/Stub 的 代 码。 在 传 统 方 式 下, 这 部 分 代 码 与COM 服 务 程 序 的 代 码 是 分 离 的, 但 是 由 于 新 的COM 标 准 支 持 多 线 程 环 境 下 的COM 对 象 服 务, 因 此 在 动 态 连 接 库 的COM 服 务 程 序 中 也 要 有Proxy/Stub 的 支 持。 为 了 支 持 在 网 络 上 的 传 输,ATL 允 许 用 户 选 择 将Proxy/Stub 的 代 码 包 括 在 生 成 的DLL 代 码 中。 这 个 选 项 在EXE 和NT 服 务 类 型 的COM 应 用 条 件 下 不 可 选。
允 许 支 持MFC。 由 于ATL 对 除COM 以 外 的 基 本 的Windows 编 程 方 面 的 支 持 极 为 有 限, 同 时 许 多 程 序 员 对MFC 又 非 常 熟 悉, 因 此 在ATL 的 工 程 设 置 中 允 许 在ATL 工 程 内 部 支 持 使 用MFC, 即 可 以 使 用MFC 定 义 的 类。 这 一 特 点 给 开 发 人 员 提 供 了 许 多 方 便, 特 别 对 于 习 惯 使 用MFC 的 人 来 说, 能 够 使 用MFC 提 供 的 各 种 功 能 强 大 的 类 的 支 持, 而 不 必 直 接 使 用Windows SDK。 从 另 一 个 方 面 来 看, 在ATL 工 程 中 使 用MFC 同 时 就 丧 失 了ATL 代 码 轻 量 级 的 特 点。
支 持MTS。MTS 是Microsoft Transaction Server 的 缩 写, 它 是Microsoft 在COM 技 术 方 面 的 一 个 新 的 分 支, 这 里 不 做 详 细 说 明。
完 成 上 面 的 设 置 以 后, 可 以 选 择Finish 完 成 工 程 的 设 置,ATL 将 创 建 相 应 的 工 程。
二. 加入ATL类
完 成 工 程 的 创 建 和 设 置 以 后, 下 一 步 就 是 向 工 程 中 加 入 一 个 新 的ATL 类。Visual Studio 集 成 环 境 提 供 了 向 导 工 具"ATL Object Wizard" 用 于 加 入 一 个 新 的ATL 类。 操 作 过 程 并 不 复 杂, 只 是 一 组 对 话 框 操 作 而 已。
---- 首 先 通 过 集 成 环 境 的"Insert" 菜 单 下 的"New ATL Object..." 命 令 进 入"ATL Object Wizard" 对 话 框, 如 图1 所 示。
这 个 对 话 框 即 为 创 建ATL 对 象 的 向 导 起 始 界 面。 对 话 框 的 左 边 部 分 说 明 了 待 创 建 对 象 的 基 本 类 型, 这 里 主 要 有 以 下 几 种 类 型:
- 对 象(Object) 基 本 的COM 对 象 类 型;
- 控 制(Control) ActiveX Control 类 型 的ATL 对 象,复合控件 (Composite Control);
可以包含(类似于对话框)其他 ActiveX 控件或 Windows 控件的 ActiveX 控件。复合控件包含以下内容:
- 实现复合控件的对话框模板。
- 调用时自动注册复合控件的自定义资源 REGISTRY。
- 实现复合控件的 C++ 类。
- 由复合控件公开的 COM 接口。
- 包含复合控件的 HTML 测试页。
默认情况下,此控件将 m_bWindowOnly 设置为真,以指示这是一个有窗口的控件。它实现接收映射。
- 其 他(Miscellaneous) 辅 助 功 能, 如 对 话 框 的 生 成 等,DHTML 控件;
ATL DHTML 控件使用 HTML 指定用户界面。DHTML UI 类包含 COM 映射。默认情况下,此控件将 m_bWindowOnly 设置为真,以指示这是一个有窗口的控件。
- 数 据 访 问(Data Access) 数 据 访 问, 支 持MTS 等。
---- 右 边 部 分 说 明 了 每 种 类 型 的 详 细 内 容。 对 于 一 般 的COM 服 务 程 序, 使 用 对 象 表 中 的 简 单 对 象(Simple Object) 就 可 以 了。
---- 选 定 待 创 建 对 象 的 基 本 类 型 以 后, 单 击"Next" 按 钮 进 入 下 一 步, 进 入 对 象 属 性 设 置 对 话 框。 对 象 属 性 设 置 分 为 两 个 过 程: 先 是 对 象 名 字 标 识 的 设 定, 然 后 是 对 对 象 的 基 本 属 性 进 行 设 置。 首 先 是 对 象 的 名 字 标 识 设 置, 如 图2 所 示。
在 对 象 标 识 编 辑 框 中 输 入 待 创 建 对 象 的 名 字,ATL 对 象 向 导 将 同 步 地 根 据 用 户 输 入 的 对 象 标 识 设 定 该 对 象 的C++ 标 识 和COM 标 识。 对 象 的C++ 标 识 包 括 对 象 的 类 名、cpp 文 件 名 和 头 文 件 名。COM 标 识 包 括 对 象 在 类 型 库 中 的CoClass 段 和 实 现 的 主 接 口 的 名 字, 同 时 还 有 在 系 统 注 册 表 中 的 类 型 名 以 及ProgID。
---- 对 象 名 字 标 识 设 置 完 成 以 后, 选 择 对 象 属 性 页(Attribute) 进 入 对 象 的 属 性 设 置 页 面, 如 图 所 示。
对 象 的 属 性 设 置 是ATL 对 象 创 建 过 程 中 最 复 杂 的 部 分, 包 括 以 下 几 个 主 要 部 分:
- 对 象 的 线 程 模 型(Thread Model)
对 象 的 线 程 模 型 是COM 对 象 在 多 线 程 环 境 下 被 访 问 时 对 访 问 方 式 的 控 制, 缺 省 情 况 下 在ATL 中 采 用 的 是 套 间 模 型Apartment, 由 系 统 通 过 消 息 队 列 方 式 提 供 并 发 控 制。
- 对 象 的 接 口 模 型(Interface)
COM 对 象 的 接 口 可 以 是 双 接 口(Dual Interface)。 双 接 口 不 同 于 普 通 接 口(Custom Interface) 之 处 在 于 双 接 口 是 从Automation 基 本 接 口IDispatch 继 承 的, 而 普 通 接 口 是 从IUnknown 接 口 直 接 继 承 来 的。 缺 省 的 接 口 模 型 是 双 接 口。
- 对 象 的 聚 合 模 型(Aggregate)
COM 规 范 不 允 许 对 象 的 实 现 继 承, 但 是 可 以 通 过 聚 合 方 式 重 用 其 他 的COM 对 象。ATL 对 象 属 性 设 置 中 的 聚 合 模 型 可 以 指 定 待 创 建 的COM 对 象 是 否 支 持 聚 合 模 型。 缺 省 的 选 项 是 支 持 对 象 的 聚 合。
- 对 象 对 错 误 处 理 的 支 持(Support ISupportErrorInfo)
选 取 这 个 选 项 可 以 在 对 象 的 运 行 过 程 中 支 持 错 误 处 理。 缺 省 情 况 下 这 个 选 项 不 被 选 中。
- 对 象 对 连 接 点 的 支 持(Support Connection Points)
连 接 点 是COM 对 象 的 事 件 机 制。 选 中 这 个 选 项 可 以 使 待 创 建 的COM 对 象 具 有 发 出 事 件 的 能 力。 缺 省 情 况 下 该 选 项 不 被 选 中。
- 对 象 对 自 由 线 程 调 度 的 支 持(Free Thread Marshaller, 简 称FTM)
对 象 的 自 由 线 程 调 度 是 对 象 在 处 于 自 由 线 程 模 型 状 态 下, 为 了 简 化 对 象 的 访 问 过 程 而 采 用 的 一 种 优 化 策 略。 缺 省 情 况 下 该 选 项 不 被 选 中。
---- 对 于 上 述 的 任 何 一 个 选 项 的 详 细 描 述 都 涉 及 到COM 技 术 一 些 核 心 的 内 容, 并 且 都 已 超 出 本 文 的 范 围, 因 此 本 文 只 对ATL 给 出 的 缺 省 选 项 加 以 说 明, 对 这 些 内 容 感 兴 趣 的 读 者 可 以 参 考Microsoft 提 供 的 文 档。
---- 完 成 了 上 面 的 设 置 以 后, 就 可 以 按"OK" 按 钮 完 成 对 象 的 创 建 过 程。 下 一 步 就 是 向 所 生 成 的ATL 类 的 接 口 中 加 入 成 员 函 数 的 定 义, 以 及 接 口 成 员 函 数 的 实 现 过 程。
三.加 入 接 口 定 义, 实 现 接 口 函 数
加 入 了ATL 类 定 义 之 后, 我 们 可 以 打 开Visual C++ 集 成 环 境 下 项 目 管 理 器(Workspace) 中 的Class View 来 检 查 生 成 的 类 定 义 的 情 况。我 们 可 以 看 到 一 个 新 的 类 已 经 生 成, 同 时 还 生 成 了 相 应 的 接 口 定 义。ATL Object Wizard 为 我 们 生 成 了 类 定 义 的.h 和.cpp 文 件, 此 外 还 有 用 于 接 口 定 义 的IDL 文 件。 有 了 这 些 文 件 以 后, 我 们 就 可 以 为 接 口 加 入 成 员 函 数, 完 成 类 的 定 义。
首 先 在Class View 中 选 中 相 应 的 接 口, 显 示 为 接 口IATLTest, 单 击 鼠 标 右 键 打 开 菜 单, 如 图。 此 弹 出 式 菜 单 定 义 了 为 接 口 加 入 属 性 和 方 法 的 操 作。 选 取 其 中 的"Add Method" 项 可 以 为 接 口 加 入 方 法 成 员, 选 取"Add Property" 则 可 以 为 接 口 加 入 新 的 属 性 成 员
加 入 属 性 和 方 法 的 对 话 框 可 以 参 看 图6 和 图7。 如 果 我 们 要 在 接 口 中 加 入 一 个 方 法, 则 选 取"Add Method" 菜 单 命 令。 假 设 方 法 名 为ABC, 方 法 的 返 回 类 型 为COM 规 定 的HRESULT 类 型。 我 们 也 可 以 定 义 非HRESULT 返 回 类 型 的 函 数, 但 是 这 需 要 手 工 修 改 接 口 定 义 的IDL 文 件。 我 们 定 义ABC 方 法 的 一 个 参 数 为a, 类 型 为 整 数 型。 完 成 了 方 法 的 定 义 以 后, 单 击"OK" 按 钮 则 把 此 方 法 加 入 到 接 口 中
属 性 的 加 入 过 程 是 类 似 的。 属 性 加 入 对 话 框 要 求 指 定 属 性 的 类 型、 名 字 以 及 属 性 的 访 问 方 式。 在 属 性 和 方 法 的 编 辑 对 话 框 中 都 有 一 个"Attributes" 按 钮, 在 给 出 了 一 个 属 性 或 方 法 的 基 本 定 义 之 后, 单 击 此 按 钮, 可 以 对 属 性 和 方 法 的 一 些 高 级 特 性 进 行 设 置。 方 法 成 员 加 入 以 后, 我 们 可 以 通 过Class View 来 检 查ATL 为 我 们 所 做 的 工 作, 如 图8 所 示。 首 先 我 们 看 到ATL 在 接 口 的 定 义 中 加 入 了 该 方 法 的 定 义, 同 时 在 对 应 的ATL 类 定 义 中, 也 加 入 了 一 个 相 应 的 方 法 的 定 义, 在 类 对 应 的.cpp 文 件 中, 加 入 了 此 方 法 的 实 现 框 架。 此 后, 我 们 只 要 在 这 个 函 数 框 架 中 加 入 该 方 法 的 代 码 逻 辑, 一 个 接 口 函 数 的 定 义 和 实 现 就 基 本 完 成 了。 依 照 这 种 方 式, 我 们 可 以 完 成 整 个COM 对 象 的 定 义 和 实 现。 完 成 以 上 的 步 骤 之 后, 我 们 就 可 以 编 译 连 接 应 用 了。