OLE Automation 将推出 MS Word 并将其推向前台
连接到正在运行的 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 实例开始运行,我就可以了。
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:
...
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).
NOTE: I partially resolved this issue by using the FindWindow Win API call:
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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
Word(以及 Excel)将仅注册在 ROT(运行对象表)中加载的第一个实例。
ROT 是 GETOBJECT“获取对象”的地方,因此,在某些情况下,可能会加载两个 WinWord.exe 实例,一个可见,一个不可见,但不可见实例是在 ROT 中注册的实例,可见实例是在 ROT 中注册的实例。一个不是。
这会让你看到你所看到的行为。
不幸的是,如果没有一些 API 调用来枚举系统上所有打开的窗口,您始终会面临 GETOBJECT 无法获取您期望的对象的风险。
没有太多办法解决这个问题。
此外,无论如何,你的最终目标都有点可疑。
当您问“连接到正在运行的 MS Word 实例并将该应用程序置于前端的“正确”方法是什么?”时,如果加载了 2 个或更多实际的 Winword.exe 实例,会发生什么情况?
您想要“连接”哪个并将其带到前面。无论如何,这都是掷骰子的结果,除非您对打开的特定文档窗口特别感兴趣。
据我了解,Word 将在 ROT 中注册所有文档窗口,无论它是哪个 Winword 实例,因此理论上您可以使用 Getobject 检索特定文档,从 DOCUMENT 对象获取 APPLICATION 对象,然后使其可见正常窗口状态。
以下是文档的 GetObject 示例
http://support.microsoft.com/kb/307216
Word (and Excel for that matter) will ONLY register the VERY FIRST INSTANCE that loads in the ROT (Running object table).
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.
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.
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?
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.
Here's an example of GetObject for a document
http://support.microsoft.com/kb/307216