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

Добавление страниц свойств

Если Initialize() возвращает S_OK, проводник запрашивает новый интерфейс - IShellPropSheetExt. IShellPropSheetExt совсем прост, с единственным методом, требующим реализации. Чтобы добавить IShellPropSheetExt к нашему классу, откройте FileTimeShlExt.h и добавьте выделенные строки:

class ATL_NO_VTABLE CFileTimeShlExt :

public CComObjectRootEx<CComSingleThreadModel>,

public CComCoClass<CFileTimeShlExt, &CLSID_FileTimeShlExt>,

public IDispatchImpl<IFileTimeShlExt, &IID_IFileTimeShlExt, &LIBID_FILETIMELib>,

public IShellExtInit,

public IShellPropSheetExt

{

BEGIN_COM_MAP(CFileTimeShlExt)

COM_INTERFACE_ENTRY(IFileTimeShlExt)

COM_INTERFACE_ENTRY(IDispatch)

COM_INTERFACE_ENTRY(IShellExtInit)

COM_INTERFACE_ENTRY(IShellPropSheetExt)

END_COM_MAP()

public:

// IShellPropSheetExt

STDMETHOD(AddPages)(LPFNADDPROPSHEETPAGE, LPARAM);

STDMETHOD(ReplacePage)(UINT, LPFNADDPROPSHEETPAGE, LPARAM) { return E_NOTIMPL; }

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

Параметры функции AddPages() - указатель на функцию и LPARAM используются только оболочкой. lpfnAddPageProc указывает на функцию оболочки, которую мы вызываем, чтобы добавить вкладки. LPARAM - загадочная величина, но она важна только для оболочки. Мы ничего с ней не делаем, просто передаем ее обратно в функцию lpfnAddPageProc.

HRESULT CFileTimeShlExt::AddPages (

LPFNADDPROPSHEETPAGE lpfnAddPageProc,

LPARAM lParam )

{

PROPSHEETPAGE psp;

HPROPSHEETPAGE hPage;

TCHAR szPageTitle [MAX_PATH];

string_list::const_iterator it, itEnd;

for ( it = m_lsFiles.begin(), itEnd = m_lsFiles.end();

it != itEnd;

it++ )

{

// 'it' - указатель на следующее имя файла. Создаем копию строки,

// которой будет владеть страница

LPCTSTR szFile = _tcsdup ( it->c_str() );

В первую очередь мы должны создать копию имени файла. Причину я объясню ниже.

Следующий шаг - создать строку, наименование для нашей закладки. Строка будет именем файла без расширения. К тому же, строка будет обрезана, если содержит более 24 символов. Это произвольный предел. 24 мне просто приглянулось. Должен же быть какой-то предел, чтобы имя файла не вышло за пределы закладки.

// Удаляем путь и расширение из имени файла - это будет заголовок страницы.

// Укорачиваем имя до 24 символов.

lstrcpy ( szPageTitle, it->c_str() );

PathStripPath ( szPageTitle );

PathRemoveExtension ( szPageTitle );

szPageTitle[24] = '\0';

Т.к. мы используем непосредственно SDK, для создания страницы свойств придется испачкать ручки структурой PROPSHEETPAGE. Вот установки для параметров структуры:

psp.dwSize = sizeof(PROPSHEETPAGE);

psp.dwFlags = PSP_USEREFPARENT | PSP_USETITLE | PSP_DEFAULT |

PSP_USEICONID | PSP_USECALLBACK;

psp.hInstance = _Module.GetModuleInstance();

psp.pszTemplate = MAKEINTRESOURCE(IDD_FILETIME_PROPPAGE);

psp.pszIcon = MAKEINTRESOURCE(IDI_ICON);

psp.pszTitle = szPageTitle;

psp.pfnDlgProc = PropPageDlgProc;

psp.lParam = (LPARAM) szFile;

psp.pfnCallback = PropPageCallbackProc;

psp.pcRefParent = (UINT*) &_Module.m_nLockCnt;

Теперь несколько деталей, на которые нужно обратить внимание, чтобы расширение работало корректно:

  • pszIcon устанавливает ID ресурса иконки 16x16, которая будет отображаться на закладке. Наличие иконки не обязательно, конечно, но я добавил, чтобы наша закладка выделялась.

  • pfnDlgProc содержит адрес оконной процедуры нашей вкладки.

  • lParam получает значение переменной szFile - копии имени файла, с которым связана наша вкладка.

  • pfnCallback - адрес функции обратного вызова, которая вызывается, когда закладка создается и когда уничтожается. Роль этой функции я объясню позже.

  • pcRefParent - адрес переменной-члена, унаследованной от CComModule. Эта переменная является счетчиком ссылок на DLL. Оболочка увеличивает этот счетчик, когда набор свойств отображен, чтобы держать DLL в памяти, пока набор открыт. Счетчик уменьшится после того, как набор свойств будет уничтожен.

Установив параметры этой структуры, мы обращаемся к API, для создания страницы свойств.

hPage = CreatePropertySheetPage ( &psp );

Если все отлично, мы вызываем callback функцию оболочки, которая добавляет вновь созданную страницу к набору свойств. Функция возвращает BOOL индикатор успеха или неудачи. Если это неудача, мы уничтожаем страницу.

if ( NULL != hPage )

{

// Вызываем callback функцию оболочки, чтобы добавить страницу к набору свойств

if ( !lpfnAddPageProc ( hPage, lParam ))

{

DestroyPropertySheetPage ( hPage );

}

}

} // end for

return S_OK;

}

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