如何在VBA中获取执行进程窗口的句柄?

时间:2011-10-18 12:24:13

标签: vba

在我的VBA应用程序中,我使用以下命令启动IExplore进程:

Shell sIE, vbMaximizedFocus

现在我需要调整创建窗口的大小。为此,我可以使用SetWindowPos函数,它将窗口的句柄作为参数之一。我没有那个处理......

我会使用FindWindowLike函数(它会抛出窗口,将标题与模式进行比较并返回带有匹配标题的窗口句柄数组),但我不能依赖于窗口标题。我不能只调整所有IE窗口的大小。

所以,我正在考虑使用SOMETHING来处理我刚刚运行的进程的窗口。壳牌公司不提供此服务。

我有一些示例代码,如何使用CoCreateInstance函数在C ++中执行此操作:

    CoCreateInstance(CLSID_InternetExplorer, NULL, CLSCTX_LOCAL_SERVER, IID_IWebBrowser2, (void**)&m_pBrowser);
        if (m_pBrowser)
        {
            pom  = buffer;
            m_pBrowser->put_Visible(VARIANT_TRUE);
            m_pBrowser->Navigate(pom, &(_variant_t(flaga)), &vDummy, &vDummy, &vDummy);
            m_pBrowser->get_HWND((long *)&hWnd);
            if (hWnd != NULL)
            {
             ...
             ...

我会将此移植到VBA,但我不太确定,为第四个参数添加了什么:

  

RIID       [in]引用用于与对象通信的接口的标识符。

嗯,我不知道我应该通过的女巫界面...我甚至不确定我是否可以在VBA中使用它。

因此。有没有办法执行进程,这将为我提供一个窗口的句柄?

1 个答案:

答案 0 :(得分:2)

和蒂姆·威廉姆斯一起去。通过使用create对象来获取IE对象与使用shell调用,您可以非常轻松地完成此操作。这样可以更容易,因为您可以访问该对象,并且在事后不需要尝试查找窗口句柄。

Global Const SW_MAXIMIZE = 3
Global Const SW_SHOWMINIMIZED = 2
Global Const SW_SHOWNORMAL = 1

Declare Function apiShowWindow Lib "user32" Alias "ShowWindow" _
            (ByVal hwnd As Long, ByVal nCmdShow As Long) As Long

Public Function Test()

    Dim ie As Object

    'reference "Microsoft Internet Controls (ieframe.dll)", and
    'cast ie as "InternetExplorer" if you wish to use intellisense
    Set ie = CreateObject("InternetExplorer.Application")

    ie.Visible = True

    apiShowWindow ie.hwnd, SW_MAXIMIZE
End Function

如果您正在处理多个显示器或需要更多控制窗口,那么它会变得有点棘手。以下是我之前解决的问题之一:Is it possible to launch a browser window in VBA maximized in the current monitor?

EDIT。将窗口设置为某个位置:

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


'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 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 Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)

Public Sub RunIt()

    Dim ie As Object
    Dim r As RECT

    Set ie = CreateObject("InternetExplorer.Application")

        'draws a 400 pixel x 400 pixel window in position 0 (top left)
    r.x1 = 0
    r.y1 = 0
    r.x2 = r.x1 + 400
    r.y2 = r.y1 + 400

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

    ie.Visible = True
    ie.Navigate "www.google.com"

    'wait until navigated
    Do While ie.Busy Or ie.READYSTATE <> READYSTATE.READYSTATE_COMPLETE
        Sleep 60
    Loop

End Sub
相关问题