是否可以在当前监视器中最大化的VBA中启动浏览器窗口?

时间:2011-07-18 20:32:00

标签: vba multiple-monitors

我需要能够从VBA代码启动浏览器窗口(这部分很简单),但我还需要它在当前监视器上显示最大化。为了让事情变得更好(阅读:更糟),我需要支持四显示器显示器。因此,用户可以在4个独立的监视器上激活4个窗口,并且根据哪个窗口/监视器触发网站打开,它应该在该监视器中最大化。

正如我之前提到的,推出一个网站是微不足道的(是的,IE是一个要求。嘘。):

Shell ("cmd /c start c:\progra~1\intern~1\iexplore.exe http://www.google.com")

然而,围绕这一点的一些细节很麻烦,即:

  1. 我可以指定新流程中显示的窗口的启动位置吗?
  2. 我可以指定新流程中显示的窗口最大化吗?
  3. 我可以使用this Win32 Function检测两个以上的监视器吗?
  4. 知道哪个监视器是当前监视器,我可以指定哪个监视器显示新窗口吗?
  5. 任何指示我正确方向的建议都会有所帮助!

1 个答案:

答案 0 :(得分:2)

我以为这是从Excel调用的。想法是您传递Excel对象窗口句柄(hWnd)并从User32检索其“矩形”对象。使用此矩形数据,然后使用SetWindowPos API调用创建IE实例并将IE对象覆盖在目标Rectangle的上方。最后,我们使用ShowWindowAsync API命令发出Maximize命令,然后加载到网站中。我目前无法在双​​显示器上进行测试,但它应该会给你一个良好的开端。

Public Type RECT
   x1 As Long
   y1 As Long
   x2 As Long
   y2 As Long
End Type

Public Enum SetWindowPosFlags
     SWP_ASYNCWINDOWPOS = &H4000
     SWP_DEFERERASE = &H2000
     SWP_DRAWFRAME = &H20
     SWP_FRAMECHANGED = &H20
     SWP_HIDEWINDOW = &H80
     SWP_NOACTIVATE = &H10
     SWP_NOCOPYBITS = &H100
     SWP_NOMOVE = &H2
     SWP_NOOWNERZORDER = &H200
     SWP_NOREDRAW = &H8
     SWP_NOREPOSITION = SWP_NOOWNERZORDER
     SWP_NOSENDCHANGING = &H400
     SWP_NOSIZE = &H1
     SWP_NOZORDER = &H4
     SWP_SHOWWINDOW = &H40
End Enum

Public Enum SpecialWindowHandles
    HWND_TOP = 0
    HWND_BOTTOM = 1
    HWND_TOPMOST = -1
    HWND_NOTOPMOST = -2
End Enum

    Const SW_SHOWNORMAL As Integer = 1
    Const SW_SHOWMINIMIZED As Integer = 2
    Const SW_SHOWMAXIMIZED As Integer = 3

'taken from IE's ReadyState MSDN Specs
Enum READYSTATE
    READYSTATE_UNINITIALIZED = 0
    READYSTATE_LOADING = 1
    READYSTATE_LOADED = 2
    READYSTATE_INTERACTIVE = 3
    READYSTATE_COMPLETE = 4
End Enum

Declare Function GetWindowRect Lib "user32.dll" (ByVal hWnd As Long, rectangle As RECT) As Boolean

Declare Function SetWindowPos Lib "user32.dll" (ByVal hWnd As Long, ByVal hWndInsertAfter As SpecialWindowHandles, ByVal X As Integer, ByVal Y As Integer, ByVal cx As Integer, ByVal cy As Integer, ByVal uFlags As SetWindowPosFlags) As Boolean

Declare Function ShowWindowAsync Lib "user32.dll" (ByVal hWnd As Long, ByVal windowMode As Integer) As Boolean

Public Sub Test()

    BrowseIEMaxFromParent Application.hWnd, "www.google.com"
End Sub

Public Sub BrowseIEMaxFromParent(targetHWND As Long, url As String)

    Dim ie As Object
    Dim xlRect As RECT

    Set ie = CreateObject("InternetExplorer.Application")

    If GetWindowRect(targetHWND, xlRect) Then

        ie.Visible = True

        'HWND_TOP sets the Z Order to our IE Object
        'x2 - x1 ==> Width (In Pixels)
        'y2 - y2 ==> Height (In Pixels)
        If SetWindowPos(ie.hWnd, HWND_TOP, xlRect.x1, xlRect.y1, (xlRect.x2 - xlRect.x1), (xlRect.y2 - xlRect.y1), SWP_ASYNCWINDOWPOS) Then

            'use constants from above for size mode, enums won't work as it needs integer type
            ShowWindowAsync ie.hWnd, SW_SHOWMAXIMIZED

            ie.Navigate url

            'wait until navigated
            While ie.Busy Or ie.READYSTATE <> READYSTATE.READYSTATE_COMPLETE
                DoEvents
            Wend

        Else
            MsgBox "Failed to Set Position"
        End If
    Else
        MsgBox "Failed to Find HWND"
    End If
End Sub