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

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

Запустите AppWizard и создайте новый ATL COM проект. Назовем его FileTime. Сохраните все начальные установки AppWizard и щелкните Finish. Чтобы добавить COM объект к DLL, перейдите в дерево просмотра классов, ClassView, щелкните правой кнопкой на пункте FileTime classes и укажите New ATL Object.

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

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

Поскольку обработчик набора свойств оперирует всеми выделенными файлами сразу, в качестве интерфейса инициализации используется IShellExtInit. Нам необходимо добавить IShellExtInit к списку интерфейсов, которые реализует CFileTimeShlExt. Инструкция, как это сделать, содержится в части IV. Классу также необходим список строк, в котором будут храниться имена выделенных файлов.

typedef std::list<std::basic_string<TCHAR> > string_list;

protected:

// IFileTimeShlExt

string_list m_lsFiles;

Метод Initialize() делает тоже, что и в части II - читает имена выделенных файлов и сохраняет их в списке строк. Вот начало функции:

HRESULT CFileTimeShlExt::Initialize (

LPCITEMIDLIST pidlFolder,

LPDATAOBJECT pDataObj,

HKEY hProgID )

{

TCHAR szFile [MAX_PATH];

UINT uNumFiles;

HDROP hdrop;

FORMATETC etc = { CF_HDROP, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };

STGMEDIUM stg;

INITCOMMONCONTROLSEX iccex = { sizeof(INITCOMMONCONTROLSEX), ICC_DATE_CLASSES };

// Инициализация общих элементов управления

InitCommonControlsEx ( &iccex );

Мы инициализируем общие элементы управления, потому что наша вкладка будет использовать элемент управления для выбора даты и времени (date/time picker (DTP)). Далее мы выполняем всю черновую работу с помощью интерфейса IDataObject и получаем дескриптор HDROP для перечисления выделенных файлов.

// Читаем список пунктов из объекта данных. Они сохранены в форме HDROP,

// поэтому, просто получаем HDROP и используем drag 'n' drop API

if ( FAILED( pDataObj->GetData ( &etc, &stg )))

return E_INVALIDARG;

// Получаем HDROP

hdrop = (HDROP) GlobalLock ( stg.hGlobal );

if ( NULL == hdrop )

{

ReleaseStgMedium ( &stg );

return E_INVALIDARG;

}

// Определяем, сколько файлов участвует в операции

uNumFiles = DragQueryFile ( hdrop, 0xFFFFFFFF, NULL, 0 );

Далее следует цикл, который перечисляет выделенные файлы. Расширение оперирует только файлами, любые директории, которые нам попадаются мы игнорируем.

for ( UINT uFile = 0; uFile < uNumFiles; uFile++ )

{

// Получаем следующее имя файла

if ( 0 == DragQueryFile ( hdrop, uFile, szFile, MAX_PATH ))

continue;

// Пропускаем каталоги. Мы могли бы использовать дескрипторы каталогов, т.к. у них

// есть время и дата создания, но в этом примере я предпочитаю этого не делать

if ( PathIsDirectory ( szFile ))

continue;

// Добавляем имя файла к нашему списку

m_lsFiles.push_back ( szFile );

} // end for

// Освобождаем ресурсы

GlobalUnlock ( stg.hGlobal );

ReleaseStgMedium ( &stg );

Вот что здесь нового: существует предел числа страниц, которые может иметь набор свойств. Он определен как константа MAXPROPPAGES в prsht.h. Каждый файл получает свою собственную страницу, и, если наш список содержит больше файлов, чем MAXPROPPAGES, остальные придется исключить, так как MAXPROPPAGES это предел. (Хотя, если MAXPROPPAGES=100, то набор свойств все равно не сможет показать все множество вкладок, максимум - 34).

// Проверим, сколько файлов было отмечено, если больше чем

// MAXPROPPAGES, укоротим список

if ( m_lsFiles.size() > MAXPROPPAGES )

{

m_lsFiles.resize ( MAXPROPPAGES );

}

// Если мы нашли какие-нибудь файлы, пригодные для работы, вернем S_OK.

// В противном случае вернем E_FAIL

return ( m_lsFiles.size() > 0 ) ? S_OK : E_FAIL;

}

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