【问题标题】:OLE Automation to launch MS Word and bring to frontOLE 自动化启动 MS Word 并将其带到前台
【发布时间】:2010-10-05 01:10:57
【问题描述】:

连接到正在运行的 MS Word 实例并将此应用程序置于最前面的“正确”(推荐)方法是什么?我正在从 VBA 应用程序中执行以下操作:

...
objWord = GetObject ("Word.Application")
if (objWord is nothing) then
  objWord = CreateObject("Word.Application")
end if
objWord.Activate()
objWord.Visible = true
objWord.WindowState = 1 'maximized
...

在带有 Word 2007 的 Windows XP 上运行,这在大多数情况下都有效 - 但有时无法将 Word 窗口置于最前面(而是在任务栏中闪烁 Word 的最小化图标)。

注意:我通过使用 FindWindow Win API 调用部分解决了这个问题:

hwnd = FindWindow("OpusApp", vbNullString)
If hwnd > 0 Then 
  SetForegroundWindow (hwnd)
end if

这不是 100%,因为(正如 drventure 指出的那样),如果 Word 的多个实例正在运行,您无法确定您将处理哪个。因为当我的代码启动 Word 时,它首先使用 GetObject,然后如果失败则使用 CreateObject,只要有一个 Word 实例开始运行,我就可以了。

【问题讨论】:

  • 您是否尝试检查 WindowState,然后重试最大化?
  • 当我检查窗口状态时,它总是 1(最大化)。此外,当我最小化调用应用程序时,Word 会最大化打开。所以,我认为问题不在于窗口状态,而在于 z 顺序。但我认为 Activate() 会将 Word 带到最前面?

标签: vba ms-word ole-automation


【解决方案1】:

Word(以及 Excel)只会注册加载到 ROT(运行对象表)中的 VERY FIRST INSTANCE。

ROT 是 GETOBJECT “获取对象”的地方,因此,在某些情况下,可能会加载两个 WinWord.exe 实例,一个可见,一个不可见,但不可见的实例是在 ROT 中注册的那个而可见的不是。

这会让你得到你所看到的行为。

不幸的是,如果没有一些 API 调用来枚举系统上所有打开的窗口,您总是冒着 GETOBJECT 无法获得您期望的对象的风险。

没有什么办法解决这个问题。

此外,你的最终目标还是有点可疑。

当您说“连接到正在运行的 MS Word 实例并将此应用程序置于最前面的“正确”方法是什么?”时,如果加载了 2 个或更多实际 Winword.exe 实例会发生什么?

您想“连接”到哪个并带到前面。无论如何,这都是掷骰子,除非您对打开的特定文档窗口特别感兴趣。

据我了解,Word 将在 ROT 中注册所有文档窗口,无论它是 Winword 的哪个实例,因此理论上您可以使用 Getobject 检索特定 DOCUMENT,从 DOCUMENT 对象中获取 APPLICATION 对象,然后制作它以 NORMAL 窗口状态可见。

这是一个文档的 GetObject 示例

http://support.microsoft.com/kb/307216

【讨论】:

  • 感谢您的回复。关于不知道 Word 的哪个实例会出现在前面,这是一个公平的任命。就我而言,我并不在乎,因为我正在使用 Word 实例创建一个新文档 - 所以,只要我可以将“我的”实例放在前面,就足够了。
  • 有一点需要注意。我注意到“不规则”使通过“CreateObject”创建的单词实例可见,然后尝试将其用作普通用户。
  • Windows 有时无法正确绘制,滚动条将停止工作,功能区有时会正常工作,而其他情况则不行。不知道为什么,虽然我怀疑当通过 CreateObject 创建时,单词 instance 并没有经历它的视觉部分的所有设置。用词来启动它最小化,然后通过 GETOBJECT 附加到该实例从来没有这些问题。
猜你喜欢
  • 2021-02-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多