Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ОСиСП - методички / OS&SP_Lab_2.6(shell).doc
Скачиваний:
95
Добавлен:
18.05.2015
Размер:
1.12 Mб
Скачать

Пример 3 «Использование разделяемой с оболочкой памяти»

В этом примере рассмотрим другой тип расширений - использование памяти, разделяемую с оболочкой и как использовать MFC вместе с ATL.

Расширение QueryInfo

Active Desktop имеет одну новую особенность - когда вы перемещаете указатель мыши над объектом, появляется всплывающая подсказка - тултип, описывающая этот объект. Например, перемещение мыши над объектом "Мой компьютер" вызовет появление тултипа:

Другие объекты, такие как "Сетевое окружение" и "Панель управления", имеют аналогичные тултипы. Используя расширение QueryInfo мы можем внести свою собственную информацию в строку описания для объектов оболочки.

Замечание по поводу имени расширения - "QueryInfo". Это название придумано мною. Я так назвал расширение после применения интерфейса IQueryInfo. Это не официальное название. Я смотрел MSDN за октябрь 1999 года и не смог найти даже ссылку на этот тип расширений. Однако это расширение определенно предусмотрено, так как Microsoft Office использует их для своих типов файлов:

WinZip версии 8 также использует расширение QueryInfo для сжатых файлов:

Самая лучшая документация, которую я нашел - это статья Dino Esposito "Enhance Your User's Experience with New Infotip and Icon Overlay Shell Extensions" в журнале MSDN за март 2000 года.

В примере 3 расширение реализует быстрый просмотр текстовых файлов. Оно будет отображать в тултипе первую строку файла и его размер. Информация будет появляться во время перемещения курсора над TXT-файлами.

Использование AppWizard

Запустите AppWizard и создайте новый ATL COM проект. Назовем его TxtInfo. Поскольку в этот раз мы собираемся использовать MFC, нужно проверить переключатель Support MFC, он должен быть включен. Затем щелкните Finish. Чтобы добавить COM объект к DLL, перейдите в дерево просмотра классов, ClassView, щелкните правой кнопкой на пункте TxtInfo classes и укажите New ATL Object.

В мастере ATL объектов, на первой панели уже указан Simple Object, поэтому просто щелкните Next. Во второй панели, в поле редактирования Short Name введите краткое имя TxtInfoShlExt и щелкните OK. (Остальные поля заполняются автоматически.) Мы создали класс CTxtInfoShlExt, который содержит основной код для реализации объекта COM. Добавим свой код к этому классу.

Если вы внимательно посмотрите на дерево ClassView, то увидите, что появился новый класс, CTxtInfoApp, производный от CWinApp. Присутствие этого класса и глобальной переменной theApp делает библиотеку MFC доступной для нас, как будто мы пишем нормальную MFC DLL.

Интерфейс инициализации

Раньше, для предыдущих расширений, мы реализовывали интерфейс IShellExtInit, чтобы проводник мог инициализировать наши объекты. Для некоторых объектов оболочки используется другой инициализационный интерфейс - IPersistFile, и QueryInfo - одно из них. Чем отличаются эти интерфейсы? Если вы помните, IShellExtInit::Initialize() получает указатель на IDataObject, с помощью которого можно перечислить все выбранные файлы. IPersistFile используется для тех расширений, которые оперируют только одним файлом. Так как курсор в определенный момент времени может находиться только в области одного объекта, QueryInfo использует для инициализации IPersistFile.

Первым делом добавим IPersistFile в список интерфейсов, которые реализуются CTxtInfoShlExt. Откройте файл TxtInfoShlExt.h и добавьте выделенные строки:

#include <comdef.h>

#include <shlobj.h>

class ATL_NO_VTABLE CTxtInfoShlExt :

public CComObjectRootEx<CComSingleThreadModel>,

public CComCoClass<CTxtInfoShlExt, &CLSID_TxtInfoShlExt>,

public IDispatchImpl<ITxtInfoShlExt, &IID_ITxtInfoShlExt, &LIBID_TXTINFOLib>,

public IPersistFile

{

BEGIN_COM_MAP(CTxtInfoShlExt)

COM_INTERFACE_ENTRY(ITxtInfoShlExt)

COM_INTERFACE_ENTRY(IDispatch)

COM_INTERFACE_ENTRY(IPersistFile)

END_COM_MAP()

Нам также понадобится переменная для сохранения имени файла, которое передаст нам проводник:

protected:

// ITxtInfoShlExt

CString m_sFilename;

Обратите внимание, что мы можем использовать объекты MFC везде, где нам захочется.

В документации на IPersistFile описано много методов, но к счастью нам достаточно реализовать только Load(). Вот прототипы методов IPersistFile:

public:

// IPersistFile

STDMETHOD(GetClassID)(LPCLSID) { return E_NOTIMPL; }

STDMETHOD(IsDirty)() { return E_NOTIMPL; }

STDMETHOD(Load)(LPCOLESTR, DWORD);

STDMETHOD(Save)(LPCOLESTR, BOOL) { return E_NOTIMPL; }

STDMETHOD(SaveCompleted)(LPCOLESTR) { return E_NOTIMPL; }

STDMETHOD(GetCurFile)(LPOLESTR*) { return E_NOTIMPL; }

Все методы, кроме Load() возвращают E_NOTIMPL в знак того, что они не реализованы.

Скрашивает ситуацию также то, что в действительности метод Load() очень прост. Он сохраняет имя файла, переданное ему проводником. Это как раз тот файл, в области которого находится курсор.

HRESULT CTxtInfoShlExt::Load ( LPCOLESTR wszFilename, DWORD dwMode )

{

AFX_MANAGE_STATE(AfxGetStaticModuleState()); // init MFC

// Let CString convert the filename to ANSI if necessary.

m_sFilename = wszFilename;

return S_OK;

}

Первая строка в начале функции необходима для корректной работы DLL. Поскольку наша DLL будет загружена не-MFC приложением, каждая экспортируемая функция, использующая MFC, должна инициализировать MFC вручную. Если вы не включите эту строку, многие MFC-функции (в основном функции, работающие с ресурсами) прекратят свою работу.

Имя файла сохраняется в m_sFilename для дальнейшего использования. Заметьте, какие я имею преимущества с оператором присваивания CString по конвертированию строки в ANSI, если DLL собирается как ANSI.

Соседние файлы в папке ОСиСП - методички