Сообщений 4    Оценка 133 [+1/-0]         Оценить  
Система Orphus

Как подключиться к запущенным экземплярам Explorer'a

Автор: Тимофей Чадов
The RSDN Group
Опубликовано: 14.03.2002
Исправлено: 13.03.2005
Версия текста: 1.0.1

Демонстрационное приложение - 6 KB

Объект SHDocVw::ShellWindows

Начиная с версии 4.71, оболочка содержит объект ShellWindows, который предоставляет доступ к коллекции уже запущенных экземпляров Internet Explorer'a. Назначение методов этого интерфейса вполне прозрачно. Свойство Count возвращает число элементов в коллекции. Метод Item позволяет получить указатель на интерфейс IWebBrowser2 соответствующего окна.

ПРИМЕЧАНИЕ

На самом деле коллекция ShellWindows содержит открытые окна не только Internet Explorer'a, но и Windows Explorer'a. Несмотря на это, к экземплярам обоих типов можно успешно обращаться через указатель на IWebBrowser2. Отличить Internet Explorer можно, например, по наличию объекта document.

Таким образом, воспользовавшись этой коллекцией можно не только узнать, сколько и каких окон Explorer'а открыто, но и получить практически полный контроль над ними. Действительно, имея указатель на IWebBrowser2, мы вольны делать с объектами Explorer'a все что заблагорассудится. Следующий пример просто закроет их. Нет, постойте, следующий пример закроет все окна Windows Explorer'a, а во всех окнах Internet Explorer'a изменит цвет фона на синий.

Листинг 1. EnumExp.cpp
#include <iostream>

// для CComPtr
#include <atlbase.h>

// ShellWindows
#include "exdisp.h"
// MSHTML
#include "mshtml.h"

void main()
{
    // Инициализируем COM
    CoInitialize(NULL);

    try 
    {
        CComPtr<IShellWindows> spShWin;
        if (FAILED(spShWin.CoCreateInstance( __uuidof( ShellWindows))))
            throw std::cout << "Couldn't create object SHDocVW::ShellWindows";            

        // Получаем количество открытых окон
        LONG nCount;
        spShWin->get_Count( &nCount);
        
        std::cout << ((nCount)?"Shell windows list:":"none ...") << std::endl; 

        for (int i=0; i<nCount; i++)
        {
            // Получаем очередное окно
            CComPtr<IDispatch> pDisp;
            spShWin->Item( CComVariant(i), &pDisp);
            CComQIPtr<IWebBrowser2> pIE( pDisp);
            if (pIE == NULL)
                throw "Unable to query Internet Explorer object";
            
            // Получаем URL закруженного документа (открытой папки)
            USES_CONVERSION;
            CComBSTR bsUrl;
            pIE->get_LocationURL( &bsUrl);               
            LPTSTR lpstrUrl = W2T(bsUrl);

            // Пробуем получить html-документ
            CComPtr<IDispatch> pDispDoc;
            pIE->get_Document( &pDispDoc);
            CComQIPtr<IHTMLDocument2> pHtmlDoc( pDispDoc);

            // Если документ удается получить, значит это окно Internet Explorer'а
            if (pHtmlDoc)
            {
                std::cout << "  Internet Explorer: " << lpstrUrl << std::endl;
                // Ради примера, меняем цвет фона на синий
                pHtmlDoc->put_bgColor( CComVariant( L"blue"));
            } 
            // иначе это просто Explorer
            else
            {
                std::cout << "  Window Explorer: " << lpstrUrl << std::endl;
                // Закроем окно
                pIE->Quit();
            }               
        }

    } 
    catch(char* lpstrErr) {
        std::cout << lpstrErr << std::endl;
    } 
    catch(...) {
        // Unknown error...
        std::cout << "Unknown error..." << std::endl;
    } 

    CoUninitialize();
    return;
}

События DShellWindowsEvents

Кроме этого, объект ShellWindows поддерживает событийный интерфейс DShellWindowsEvents, подключившись к которому можно своевременно получать уведомления обо всех изменениях в жизни окон Explorer'а. Этот интерфейс содержит всего два метода WindowRegistered и WindowRevoked, которые вызываются оболочкой соответственно при создании и закрытии очередного окна эксплорера. Вопросы подключения к событиям достаточно подробно рассмотрены в различных источниках (в том числе и на нашем сайте), поэтому не будем останавливаться на них отдельно. Пример реализации похожего примера с поддержкой событий DShellWindowsEvents можно найти здесь.


Любой из материалов, опубликованных на этом сервере, не может быть воспроизведен в какой бы то ни было форме и какими бы то ни было средствами без письменного разрешения владельцев авторских прав.
    Сообщений 4    Оценка 133 [+1/-0]         Оценить