Как я могу получить дескриптор окна исполняемого процесса в VBA? - PullRequest
0 голосов
/ 18 октября 2011

В моем приложении VBA я запускаю процесс IExplore с:

Shell sIE, vbMaximizedFocus

Теперь мне нужно изменить размер созданного окна. Для этого я могу использовать функцию SetWindowPos, которая принимает дескриптор окна в качестве одного из аргументов. И у меня нет этой ручки ...

Я бы использовал функцию FindWindowLike (которая запускает окна, сравнивает заголовок с шаблоном и возвращает массив дескрипторов окон с соответствующим заголовком), но я не могу полагаться на заголовок окна. Я не могу просто изменить размер всех окон IE.

Итак, я думал об использовании ЧТО-ТО, что дало бы мне представление о окне процесса, который я только что запустил. Shell не предоставляет этого.

У меня есть пример кода, как это сделать в C ++ с помощью функции CoCreateInstance:

    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 Ответ

2 голосов
/ 18 октября 2011

Чтобы пойти вместе с Тимом Уильямсом.Вы можете сделать это довольно легко, используя create object, чтобы получить объект IE против вызова оболочки.Это облегчает задачу, поскольку у вас есть доступ к объекту, и вам не нужно пытаться искать дескриптор окна после факта.

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

Если вы работаете с несколькими мониторами или вам нужен больший контроль надокно, то становится немного сложнее.Вот один из моих предыдущих ответов на этот адрес: Возможно ли открыть окно браузера в VBA, развернутое в текущем мониторе?

РЕДАКТИРОВАТЬ.Установить окно в определенную позицию:

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...