Демонстрационное приложение - 6 KB
Начиная с версии 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; } |
Кроме этого, объект ShellWindows поддерживает событийный интерфейс DShellWindowsEvents, подключившись к которому можно своевременно получать уведомления обо всех изменениях в жизни окон Explorer'а. Этот интерфейс содержит всего два метода WindowRegistered и WindowRevoked, которые вызываются оболочкой соответственно при создании и закрытии очередного окна эксплорера. Вопросы подключения к событиям достаточно подробно рассмотрены в различных источниках (в том числе и на нашем сайте), поэтому не будем останавливаться на них отдельно. Пример реализации похожего примера с поддержкой событий DShellWindowsEvents можно найти здесь.