第 六 章 O L E 自 动 化
所 谓 OL E 自 动 化 ( O L E A u to m a tio n ) 是 W ind ow s 应 用 程 序 之 间 相 互 操 纵 的 一种 技 巧 被 操 纵 的 一 端 称 为 自 动 化 对 象 或 自 动 化 服 务 器 而 操 纵 自 动 化 对象 的 一 端 称 为 自 动 化 控 制 器 或 自 动 化 客 户 一 个 应 用 程 序 或 DL L 可 以 兼 具服 务 器 和 客 户 两 种 角 色 本 章 的 重 点 是 怎 样 操 纵 OL E 自 动 化 对 象 怎 样 创建 自 动 化 服 务 器
1 怎 样 操 纵 自 动 化 对 象
要 操 纵 自 动 化 对 象 您 首 先 要 创 建 自 动 化 控 制 器 或 者 称 自 动 化 客 户 在 C+ + Bu i ld e r 3 中 要 创 建 自 动 化 客 户 有 两 种 方 式 引 入 类 型 库 和 调 用V a r ia n t::E x e c
6. 1 . 1 通 过 引 入 类 型 库 来 操 纵 自 动 化 服 务 器
要 引 入 自 动 化 服 务 器 的 类 型 库 使 用 P ro ject 菜 单 上 的 Im port T y pe L ib ra r y 命 令 C+ + Bu ild e r 3 将 打 开 Im port T y pe L ibra r y 对 话 框 如 图 6 .1 所 示
图 6 .1 引 入 类 型 库
选 择 其 中 一 个 类 型 库 如 M ic ros oft W o rd 8 .0 O b je c t L ibra ry 然 后 单 击 OK 按 钮 如 果 要 引 入 的 类 型 库 没 有 列 出 来 可 能 是 因 为 还 没 有 注 册 此 时 就单 击 A d d 按 钮 先 注 册
引 入 了 类 型 库 后 C+ + Bu ild e r 3 会 自 动 生 成 该 类 型 库 的 C+ + 外 套 文 件 从 中可 以 看 出 类 型 库 中 的 所 有 GU ID 常 量 和 组 件 类 (C o C la s s )
如 果 要 通 过 自 动 化 服 务 器 中 的 双 重 接 口 来 操 纵 自 动 化 服 务 器 您 首 先 要 用一 个 Co C la s s 客 户 代 理 类 来 创 建 自 动 化 对 象 的 一 个 实 例 程 序 示 例 如 下T C O M W o rd B a s ic w b = C o A p p licatio n : : C re ate( ) ;
注 意 您 必 须 在 自 动 化 客 户 程 序 中 包 含 C+ + 外 套 的 头 文 件 否 则 上 面 一 行
代 码 将 出 错 因 为 编 译 器 找 不 到 C o A p p lic a tio n 和 TC O M W o rd B a s ic 的 声 明
创 建 了 自 动 化 对 象 的 实 例 后 您 就 可 以 调 用 自 动 化 对 象 中 的 方 法 完 整 的示 例 如 下
v o id _ fa s tc a ll T F o rm 1 ::B u tto n 1 C lic k ( T O b je c t * S e n d e r )
{
T C O M W o rd B a s ic w b = C o A p p lic a tio n ::C re a te ( ) ; if (O p e n D ia lo g 1 -> E x e c u te ( ))
w b -> F ile P rin t( V a r ia n t::N o P a ra m ( ) , V a r ia n t::N o P a ra m ( ) , V a r ia n t::N o P a ra m ( ) ,
V a r ia n t::N o P a ra m ( ) , V a r ia n t::N o P a ra m ( ) , V a r ia n t::N o P a ra m ( ) , V a r ia n t::N o P a ra m ( ) , V a r ia n t::N o P a ra m ( ) , V a r ia n t::N o P a ra m ( ) , V a r ia n t::N o P a ra m ( ) , V a r ia n t::N o P a ra m ( ) , V a r ia n t::N o P a ra m ( ) , V a r ia n t( O p e n D ia lo g 1 -> F ile N a m e ) , V a r ia n t::N o P a ra m ( ) ) ;
}
如 果 要 通 过 自 动 化 服 务 器 中 的 调 度 接 口 来 操 纵 自 动 化 服 务 器 首 先 要 用
Co C la s s 客 户 代 理 类 来 创 建 自 动 化 对 象 的 一 个 实 例 程 序 示 例 如 下
W o rd B a s ic D is p w b = C o A p p lic a tio n :: C re a te ( ) ;
调 用 B in d 函 数 并 且 把 'W ord .B a s ic '作 为 参 数 传 递 给 它 完 整 的 示 例 如 下
v o id _ fa s tc a ll T F o rm 1 ::B u tto n 1 C lic k ( T O b je c t * S e n d e r )
{
W o rd B a s ic D is p w b = C o A p p lic a tio n ::C re a te ( ) ; w b .B ind ( 'W ord .B a s ic ') ;
if (O p e n D ia lo g 1 -> E x e c u te ( ))
w b .F ile P rin t( V a r ia n t::N o P a ra m ( ) , V a r ia n t::N o P a ra m ( ) , V a r ia n t::N o P a ra m ( ) ,
V a r ia n t::N o P a ra m ( ) , V a r ia n t::N o P a ra m ( ) , V a r ia n t::N o P a ra m ( ) , V a r ia n t::N o P a ra m ( ) , V a r ia n t::N o P a ra m ( ) , V a r ia n t::N o P a ra m ( ) , V a r ia n t::N o P a ra m ( ) , V a r ia n t::N o P a ra m ( ) , V a r ia n t::N o P a ra m ( ) , V a r ia n t( O p e n D ia lo g 1 -> F ile N a m e ) , V a r ia n t::N o P a ra m ( ) ) ;
}
注 意 这 里 调 用 w b 的 方 法 时 用 小 圆 点 而 不 是 ->
6. 1 .2 通 过 调 用 Variant::E xec 来 操 纵 自 动 化 服 务 器
如 果 您 不 能 打 开 自 动 化 服 务 器 的 类 型 库 您 就 只 能 通 过 调 用 V a r ia n t::E x e c 来操 纵 自 动 化 服 务 器
首 先 您 要 创 建 一 个 V a r ia n t类 型 的 变 量 用 这 个 变 量 来 引 用 自 动 化 服 务 器
V a r ia n t w b = V a r ian t :: C re a teO b ject('W o rd . B as ic ') ;
然 后 调 用 V a r ia n t::E x e c 作 为 外 套 来 执 行 自 动 化 服 务 器 中 的 某 个 方 法 完 整 的示 例 如 下
v o id _ fa s tc a ll T F o rm 1 ::B u tto n 1 C lic k ( T O b je c t * S e n d e r )
{
V a r ia n t w b = V a r ia n t::C re a te O b je c t('W o rd .B a s ic ') ; if (O p e n D ia lo g 1 -> E x e c u te ( ))
w b .E x e c( P ro c ed u re(" F i le P r in t" ) < < N a m e d P aram (" F i le N a m e " , V a r ia n t( O p e n D ia lo g 1 -> F i le N a m e ) ) )
}
最 后 我 们 再 谈 一 谈 自 动 化 对 象 的 生 存 期 问 题 以 上 述 程 序 示 例 为 例 如 果 wb 变 量 被 声 明 为 全 局 的 那 么 这 个 自 动 化 对 象 的 生 存 期 就 与 应 用 程 序 的 生 存期 是 相 同 的 如 果 wb 变 量 在 某 个 例 程 内 部 声 明 该 自 动 化 对 象 的 生 存 期 与局 部 变 量 的 生 存 期 是 相 同 的 因 此 一 般 来 说 您 没 有 必 要 显 式 地 删 除 自动 化 对 象 的 实 例
- 1 .3 迟 后 联 编
从 本 质 上 讲 自 动 化 对 象 也 是 类 只 不 过 它 是 专 门 实 现 ID is p a tc h 接 口 的 类因 此 访 问 自 动 化 对 象 中 的 特 性 和 方 法 与 访 问 一 般 类 中 的 特 性 和 方 法 是 很相 似 的
不 同 的 是 访 问 OL E 自 动 化 对 象 的 特 性 和 方 法 采 用 的 是 迟 后 联 编 也就 是 说 不 需 要 事 先 声 明 特 性 和 方 法 的 原 型 编 译 器 也 不 进 行 类 型 检 查 至 于 特 性 和 方 法 能 不 能 访 问 成 功 要 到 运 行 期 实 际 访 问 后 才 知 道 如 果 实 际访 问 没 有 成 功 将 触 发 EO le E rro r异 常
造 成 访 问 失 败 的 原 因 可 能 有 这 么 几 种 情 况
-
可
能 是 因 为 自 动 化 对 象 的 实 例 还 没 有 创 建 或 者 没 有 取 得 对 自 动 化 对 象的 引 用
-
特 性
或 方 法 的 标 识 符 在 自 动 化 对 象 中 不 存 在
-
参 数
的 个 数 及 数 据 类 型 不 匹 配 尽 管 有 的 自 动 化 对 象 支 持 参 数 可 省 略 的
调 用 但 没 有 遵 循 有 关 参 数 省 略 的 规 则 ( 后 面 将 详 细 介 绍 怎 样 省 略 参数 )
-
方
法 调 用 出 现 在 表 达 式 中 但 该 方 法 并 没 有 返 回 一 个 值
-
即
使 没 有 上 述 错 误 但 自 动 化 对 象 本 身 也 可 能 出 现 异 常
6.2 怎 样 创 建 自 动 化 服 务 器
自 动 化 服 务 器 分 为 三 类 一 是 In -P ro c e s s 型 的 服 务 器 二 是 O u t- O f-P ro c e s s ( 或称 为 Lo c a l) 型 的 服 务 器 三 是 R e m o te 型 的 服 务 器 不 管 是 哪 种 类 型 的 服 务 器其 基 本 特 征 是 一 致 的 都 要 实 现 ID is p a tc h 接 口 并 输 出 自 动 化 对 象
所 谓 In -P ro c e s s 服 务 器 一 般 是 动 态 链 接 库 (D L L ) 它 没 有 单 独 的 进 程 地 址 空间 而 是 直 接 映 射 到 客 户 程 序 的 进 程 地 址 空 间 中 运 行 创 建 这 一 类 服 务 器的 好 处 在 于 多 个 自 动 化 客 户 可 以 同 时 共 享 OL E 服 务 访 问 自 动 化 对 象 的 特性 和 方 法 是 直 接 的
所 谓 O u t- O f-P ro c e s s 服 务 器 一 般 是 可 单 独 执 行 的 应 用 程 序 (E X E ) 有 它 自己 的 进 程 地 址 空 间 而 自 动 化 客 户 运 行 在 另 一 个 进 程 地 址 空 间 W o rd 就 是一 个 典 型 的 O u t- O f-P ro c e s s 服 务 器 这 种 跨 进 程 通 信 的 能 力 是 由 ID is p a tc h 接口 提 供 的
所 谓 R e m o te 服 务 器 是 指 服 务 器 与 客 户 程 序 跨 越 了 机 器 边 界 限 于 目 前 的DC OM 版 本 R e m o te 服 务 器 必 须 是 可 执 行 程 序 不 过 将 来 也 可 能 是 动 态 链接 库
C+ + Bu ild e r 3 在 创 建 自 动 化 服 务 器 方 面 作 了 重 大 改 进 采 用 了 一 种 全 新 的 体
系 结 构 即 A c tiv e X 框 架 并 且 实 现 了 与 类 型 信 息 的 无 缝 连 接 您 将 会 发 现创 建 自 动 化 服 务 器 实 际 上 主 要 就 是 生 成 类 型 信 息
如 果 要 创 建 O u t- O f-P ro c e s s 型 的 自 动 化 服 务 器 首 先 要 使 用 F ile 菜 单 上 的
N e w A p p lic a tio n 命 令 开 始 一 个 新 的 项 目 因 为 O u t- O f- P ro c e s s 型 的 自 动化 服 务 器 是 EX E 然 后 再 创 建 一 个 自 动 化 对 象 加 到 自 动 化 服 务 器 中
要 创 建 一 个 自 动 化 对 象 使 用 F ile 菜 单 上 的 N e w 命 令 打 开 N e w I te m s 对 话 框 翻 到 A c tiv e X 页 双 击 A u to m a tio n O b je c t 图 标 C+ + Bu ild e r 3 将 打 开 A u to m a tio n O b je ct W izard 对 话 框 如 图 6 .2 所 示
图 6 .2 创 建 自 动 化 对 象 的 向 导
在 C la ss N a m e 框 内 输 入 自 动 化 对 象 的 类 名 单 击 OK 按 钮 C+ + Bu ild e r 3将 自 动 创 建 该 自 动 化 对 象 的 类 型 库 文 件 名 是 P ro je c t1 .T L B 并 且 自 动 打 开 T y pe L ibra ry 编 辑 器 显 示 类 型 信 息 最 后 先 按 C tr l+ F 9 键 编 译 程 序 如
果 没 有 错 误 按 F9 键 运 行 程 序 此 服 务 器 将 自 动 在 W ind ow s 中 注 册
3 自 动 化 对 象 的 类 型 库
如 果 保 存 刚 刚 创 建 的 项 目 您 就 会 发 现 向 导 自 动 生 成 了 下 列 文 件
-
类 型
库 文 件 P ro je c t1 .T L B
-
类 型
库 的 接 口 描 述 文 件 P ro je c t1_T L B .C P P
-
自 动
化 对 象 中 接 口 的 实 现 单 元 文 件 U n it2 . P AS
向 导 自 动 生 成 类 型 库 文 件 P ro je c t1 .T L B 不 过 此 文 件 是 个 二 进 制 文 件 只 能用 T y p e L ib r a ry 编 辑 器 打 开 代 码 编 辑 器 能 打 开 的 是 类 型 库 的 接 口 描 述文 件 P ro je c t1_T L B .C P P 它 是 由 T y p e L ib r a r y 编 辑 器 维 护 的 您 不 要 直接 修 改 这 个 文 件
自 动 化 向 导 能 够 自 动 创 建 TX X H 对 象 的 类 型 信 息 不 过 刚 开 始 的 时 候
T XXH 对 象 的 接 口 是 空 的 要 使 客 户 程 序 能 够 操 纵 它 您 应 当 在 IX X H 接 口
中 加 入 新 |
的 成 员 |
使 用 | V ie w |
菜 单 上 的 |
Ty p e |
L ib ra r y |
命 令 打 开 |
T y p e |
---|---|---|---|---|---|---|---|---|
L ib ra r y |
编 辑 器 |
如 图 | 6 .3 所 示 |
图 6 .3 Ty pe L ibra ry 编 辑 器
要 向 接 口 中 增 加 新 的 成 员 在 T y p e L ib r a ry 编 辑 器 中 选 择 IXXH 节 点 然后 您 可 以 有 三 种 操 作 方 式
- 是
单 击 工 具 栏 上 的 P rope r ty 或 M e thod 图 标 然 后 在 A ttrib u te s
页 修 改 成 员 的 属 性
二 是 在 IXXH 节 点 上 单 击 鼠 标 右 键 在 弹 出 的 菜 单 中 选 择 N e w 再 选 择
P rope r ty 或 M e thod 然 后 在 A ttrib u te s 页 修 改 成 员 的 属 性三 是 翻 到 Te x t 页 按 ID L 的 文 法 直 接 键 入 特 性 或 方 法 的 声 明
假 设 我 们 要 在 IXXH 接 口 中 增 加 一 个 M y C a p t io n 特 性 可 以 单 击 工 具 栏 上 的 P rope r ty 图 标 然 后 在 A ttrib u te s 页 的 N a m e 框 内 把 特 性 名 改 为 M y C a p tio n 把 数 据 类 型 改 为 W ide S tr ing 单 击 工 具 栏 上 的 R e f r e s h 按 钮
刷 新 类 型 库 新 加 入 的 特 性 就 自 动 加 到 类 型 库 的 描 述 文 件 中 您 可 以 在 IX X H
接 口 的 声 明 中 找 到 M y C a p t io n 特 性 的 声 明
in te r fa c e IXXH : p u b l ic ID is p a tc h
{
pub l ic :
v ir tu a l HR E S UL T S T DM E T HODC AL L T YP E g e t_ M y C a p t io n ( B S T R * V a lu e ) = 0 ; v ir tu a l HR E S UL T S T DM E T HODC AL L T YP E s e t_ M y C a p t io n ( B S T R V a lu e ) = 0 ;
}
接 下 来 您 可 以 打 开 IX X H 接 口 的 实 现 单 元 U n it2 的 头 文 件 找 到
G e t_ M y C a p tio n 和 S e t_ M y C a p tio n 的 声 明
c la s s AT L _ NO _ V T A B L E T XXH Im p l : AUT OOB J E C T _ IM P L ( T X XH Im p l , XXH , IXXH)
{
pro te c te d:
S T D M E T H O D ( g e t_M y C a p t ion( B S T R * V a lu e ) ) ; S T D M E T H O D ( s et_ M y C ap t io n ( B S T R V a lu e));
};
在 U n it2 中自动出 现下列 代码 ( 注释是笔 者加的 )
/ /-
S T DM E T HOD IM P T XXH Imp l::g e t_ M y C a p tio n ( B S T R * V a lu e )
{
tr y
{
// 在这里写 代码 用于读 M y C a p tio n 特性
}
catch ( E x c ep t io n & e )
{
re tu rn E rro r( e .M e s s a g e .c _ s tr ( ) , I ID _ IX X H ) ;
}
re tu rn S _ OK;
};
/ /-
S T DM E T HOD IM P T XXH Imp l::s e t_ M y C a p tio n ( B S T R V a lu e )
{
tr y
{
// 在 这 里 写 代 码 用 于 设 置 M y C a p tio n 特 性
}
catch ( E x c ep t io n & e )
{
re tu rn E rro r( e .M e s s a g e .c _ s tr ( ) , I ID _ IX X H ) ;
}
re tu rn S _ OK;
};
您 要 做 的 就 是 定 义 G e t_ M y C a p tio n 和 Se t_ M y C a p tio n 用 于 读 写 M y C a p t io n 特性
假 设 我 们 要 在 IXXH 接 口 中 增 加 一 个 M ove 函 数 单 击 工 具 栏 上 的 M e thod 按 钮 然 后 在 A ttrib u te s 页 的 N a me 框 内 把 函 数 名 改 为 M ove 单 击 工具 栏 上 的 R e fre s h 按 钮 刷 新 类 型 库 您 可 以 在 IX X H 接 口 的 声 明 中 找 到 M ove 函 数 的 声 明
in te r fa c e IXXH : p u b l ic ID is p a tc h
{
pub l ic :
v ir tu a l HR E S UL T S T DM E T HODC AL L T YP E M o v e ( v o id ) ;
};
接 着 您 可 以 打 开 IX X H 接 口 的 实 现 单 元 U n it2 的 头 文 件 找 到 M ove 函 数 的声 明
c la s s AT L _ NO _ V T A B L E T XXH Im p l : AUT OOB J E C T _ IM P L ( T X XH Im p l , XXH , IXXH)
{
pro te c te d:
S T DM E T HOD ( M o v e ( ) ) ;
};
在 U n it2 中 自 动 出 现 下 列 代 码 ( 注 释 是 笔 者 加 的 )
S T DM E T HOD IM P T XXH Imp l::M o v e ( )
{
tr y
{
// 在这里写 代码 用于定 义 M o v e 函数
}
catch ( E x c ep t io n & e )
{
re tu rn E rro r( e .M e s s a g e .c _ s tr( ), IID _ IX X H );
}
re tu rn S _ OK;
};
假 设 我 们 要 在 类 型 库 中 加 入 一 个 枚 举 类 型 D ra g M ode 单 击 工 具 栏 上 的 En u m 图 标 然 后 在 A ttrib u te s 页 的 N a m e 框 内 把 枚 举 类 型 名 称 改 为 D ra g M ode 注 意 GU ID 框 的 内 容 不 能 修 改 刚 开 始 的 时 候 D ra g M ode 中
还 没 有 定 义 枚 举 常 量 翻 到 Te x t 页 然 后 参 照 下 列 格 式 键 入 枚 举 常 量
ty pe de f e num ta gD ra gM o d e
{
[ h e lps tr ing(" d m M a nua l" ) ] dm M a nua l = 0 ,
[ h e lps tr ing(" d m A u to m a t ic " ) ] d m A u to m a tic = 1
} D rag M o d e ;
创 建 In -P ro ce ss 型 的 自 动 化 服 务 器
前面讲的 是怎样 创 建 O u t- O f-P ro c e s s 型的 自动化服 务器 现 在我们要 创建一 个 In - P ro c e s s 型 的 自 动 化 服 务 器 由 于 In -P ro c e s s 型 的 自 动 化 服 务 器 通 常 是 动 态 链 接 库 因 此 您 首先 要 创 建 一 个 A c tiv e X 项 目 ( 库 ) 然 后 把 自 动 化 对 象 加 到 这 个 项 目 中 操 作 步 骤 是 这 样的
使 用 F ile 菜 单 上 的 N e w 命 令 打 开 N e w I te m s 对 话 框 翻 到 A c tiv e X
页 |
双 击 |
A c tiv eX L ib rary |
图 标 |
C+ + Bu i ld e r 3 将 建 立 一 个 A c tiv e X 项 目 |
|
---|---|---|---|---|---|
然 后 |
使 用 |
F ile 菜 单 上 的 |
N e w |
命 令 再 次 打 开 N e w I te m s 对 话 框 |
翻 |
到 A c tiv e X 页 双 击 A u to m a tio n O b je c t 图 标 打 开 A u to m a tio n O b je c t W iz a rd 对 话 框 在 C la ss N a m e 框 内 键 入 自 动 化 对 象 的 类 名 单 击 OK 按 钮 C+ + Bu ild e r 3 将 自 动 创 建 类 型 库 下 面 的 步 骤 与 创 建 O u t- O f- P ro c e ss 型 的 自 动 化 服 务 器 相 同 此 处 不 再 赘 述
注 册 和 调 试 自 动 化 对 象
对 于 O u t- o f-P ro c e s s 型 的 自 动 化 服 务 器 来 说 由 于 它 本 身 就 是 个 可 执 行 程 序
因 此 第 一 次 运 行 自 动 化 服 务 器 程 序 的 时 候 它 就 自 动 在 W ind ow s 中 注 册也 可 以 采 用 这 种 方 式 注 册 自 动 化 服 务 器 就 是 使 用 Ru n 菜 单 上 的
P a ra m e te rs 命 令 打 开 R u n P a ra m e te rs 对 话 框 在 R u n P a ra m e te rs 框 内 键 入 / reg s e rv er 如 果 要 取 消 自 动 化 服 务 器 的 注 册 在 R u n P a ra m e te rs 框 内 键 入 / unre g s e rv e r
对 于 In -P ro c e s s 型 的 自 动 化 服 务 器 来 说 由 于 它 没 法 单 独 运 行 要 注 册 In - P ro ces s 型 的 自 动 化 服 务 器 您 得 使 用 Ru n 菜 单 上 的 R e g is ter A c tiv eX Se rv e r 命 令 要 从 W ind ow s 中 取 消 自 动 化 服 务 器 的 注 册 使 用 Ru n 菜单 上 的 U n re g is te r A c t iv e X S e rv e r 命 令
要 调 试 O u t- O f-P ro c e ss 型 的 自 动 化 服 务 器 比 较 简 单 因 为 它 本 身 就 是 个 可 执行 程 序 您 只 要 事 先 在 源 程 序 中 设 好 断 点 然 后 启 动 自 动 化 服 务 器 程 序运 行 一 个 客 户 程 序 在 客 户 程 序 中 访 问 自 动 化 对 象 的 特 性 和 方 法 如 果 遇到 断 点 C+ + Bu ild e r 3 的 调 试 器 就 接 管 对 服 务 器 程 序 的 控 件 权 这 样 您 就 可以 采 用 诸 如 单 步 跟 踪 等 手 段 调 试 它 了
要 调 试 In -P ro c e s s 型 的 自 动 化 服 务 器 (D L L 或 OC X) 首 先 要 使 用 Ru n 菜 单上 的 P a ra m e te rs 命 令 打 开 R u n P a ra m e te rs 对 话 框 在 H o s t A p p lic a tio n 框 内 指 定 一 个 宿 主 程 序 ( 实 际 上 就 是 前 面 所 说 的 客 户 程 序 ) 再 用 这 个 宿 主 程序 访 问 自 动 化 对 象