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

如何在VBA中获取已执行进程窗口的句柄?,vba,Vba,在我的VBA应用程序中,我使用以下命令启动IExplore进程: Shell sIE, vbMaximizedFocus 现在我需要调整创建的窗口的大小。为此,我可以使用SetWindowPos函数,它将窗口句柄作为参数之一。我没有那个把手 我会使用FindWindowLike函数(该函数用于抛出窗口,将标题与模式进行比较,并返回带有匹配标题的窗口句柄数组),但我不能依赖窗口标题。我不能只调整所有IE窗口的大小 所以,我想用一些东西,给我一个窗口来处理我刚刚运行的过程。壳牌公司不提供这项服务

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

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

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

所以,我想用一些东西,给我一个窗口来处理我刚刚运行的过程。壳牌公司不提供这项服务

我有一些示例代码,如何在C++中使用COCCREATEONTION函数:

    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,但我不太确定第四个参数应该放什么:

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

我不知道我应该通过什么考试。。。我甚至不确定我是否可以在VBA中使用它


所以。是否有一种执行流程的方法,可以为它的窗口提供一个句柄?

与Tim Williams一起讨论。通过使用createobject获取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
如果您要处理多个监视器,或者需要对窗口进行更多控制,那么它会变得有点棘手。以下是我之前的一个答案:

编辑。将窗口设置到特定位置:

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
公共类型RECT
x1尽可能长
y1只要
x2等长
y2只要
端型
公共枚举SetWindowPosFlags
SWP_异步窗口位置=&H4000
SWP_=和H2000
SWP_并条机=&H20
SWP_FRAMECHANGED=&H20
SWP_HIDEWINDOW=&H80
SWP_NOACTIVATE=&H10
SWP_NOCOPYBITS=&H100
SWP_NOMOVE=&H2
SWP_NOOWNERZORDER=&H200
SWP_NOREDRAW=&H8
SWP_NOREPOSION=SWP_NOOWNERZORDER
SWP_NOSENDCHANGING=&H400
SWP_NOSIZE=&H1
SWP_NOZORDER=&H4
SWP_显示窗口=&H40
结束枚举
公共枚举特殊indowHandles
HWND_TOP=0
HWND_底部=1
HWND_最顶端=-1
HWND_NOTOPMOST=-2
结束枚举
'摘自IE的ReadyState MSDN规范
枚举READYSTATE
READYSTATE\u未初始化=0
READYSTATE_加载=1
READYSTATE_已加载=2
READYSTATE_INTERACTIVE=3
READYSTATE_COMPLETE=4
结束枚举
将函数SetWindowPos Lib“user32.dll”(ByVal hWnd为Long,ByVal hwninsertafter为SpecialWindowHandles,ByVal X为Integer,ByVal Y为Integer,ByVal cx为Integer,ByVal cy为Integer,ByVal uFlags为SetWindowPosFlags)声明为布尔值
声明子睡眠库“kernel32”(ByVal dwms长)
公共子运行库()
模糊的物体
dimras RECT
设置ie=CreateObject(“InternetExplorer.Application”)
'在位置0(左上角)绘制一个400像素x 400像素的窗口
r、 x1=0
r、 y1=0
r、 x2=r.x1+400
r、 y2=r.y1+400
'HWND_TOP设置IE对象的Z顺序
'x2-x1==>宽度(以像素为单位)
'y2-y2==>高度(以像素为单位)
设置窗口位置,即hWnd,hWnd_顶部,r.x1,r.y1,(r.x2-r.x1),(r.y2-r.y1),SWP_异步窗口位置
可见=真实
浏览“www.google.com”
“等待导航
在ie忙或ie.READYSTATE READYSTATE.READYSTATE\u完成时执行此操作
睡60
环
端接头

为什么要使用Shell而不是CreateObject?因为我正在处理其他人的代码。如果有其他方法来实现我所需要的,我当然可以改变它,但是直到…谢谢你的回答,它在未来可能是有用的,但是在这个特定的地方,我需要设置窗口的宽度和高度,将其设置为屏幕的特定x和y点(最大化/最小化是不够的)。