vba OLE 自动化启动 MS Word 并置于前台

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3860250/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-11 12:09:07  来源:igfitidea点击:

OLE Automation to launch MS Word and bring to front

vbams-wordole-automation

提问by Ed Schembor

What is the "correct" (recommended) method for connecting to a running instance of MS Word and bringing this application to the front? I am doing something like the following from a VBA app:

连接到正在运行的 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
...

Running on Windows XP with Word 2007, this works most of the time - but periodically, fails to bring the Word window to the front (and instead flashes the minimized icon for Word in the task bar).

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

NOTE: I partially resolved this issue by using the FindWindow Win API call:

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

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

This is not 100% because (as drventure pointed out), if multiple instances of Word are running, you cannot be certain which you will get a handle to. Since when my code launches Word it uses GetObject first and then CreateObject if that fails, as long as there is one instance of Word running to start with, I am OK.

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

采纳答案by DarinH

Word (and Excel for that matter) will ONLY register the VERY FIRST INSTANCE that loads in the ROT (Running object table).

Word(和 Excel 就此而言)将仅注册在 ROT(运行对象表)中加载的非常第一个实例。

The ROT is where GETOBJECT "gets the object", so, in certain circumstances, its' possible to have two instances of WinWord.exe loaded, one visible, one not, but the invisible instance is the one registered in the ROT and the visible one is NOT.

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

That'll get you the behavior you're seeing.

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

Unfortunately, without some API calls to enumerate all the open windows on the system, you always run the risk that GETOBJECT won't get you the object that you're expecting it to.

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

There's not much of a way around this.

没有太多办法解决这个问题。

Besides, you're end goal is a bit suspect anyway.

此外,无论如何,你的最终目标有点可疑。

When you say "What is the "correct" method for connecting to a running instance of MS Word and bringing this application to the front?", what happens if there are 2 or more actual instances of Winword.exe loaded?

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

Which would you want to "connect" to and bring to the front. that's a roll of the dice anyway, unless you're specifically interested in a particular DOCUMENT window that's open.

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

From what I understand, Word will register ALL document windows in the ROT, regardless of which instance of Winword it is, so you could theoretically Use Getobject to retrieve a particular DOCUMENT, get the APPLICATION object from the DOCUMENT object and then make it VISIBLE with a NORMAL windowstate.

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

Here's an example of GetObject for a document

这是文档的 GetObject 示例

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

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