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

Создание текста для тултипа

После вызова Load() проводник вызывает QueryInterface() для получения другого интерфейса, IQueryInfo. Это приятный, простой интерфейс из двух методов, из которых в действительности используется только один. Снова откройте TxtInfoShlExt.h и добавьте выделенные строки:

class ATL_NO_VTABLE CTxtInfoShlExt :

public CComObjectRootEx<CComSingleThreadModel>,

public CComCoClass<CTxtInfoShlExt, &CLSID_TxtInfoShlExt>,

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

public IPersistFile,

public IQueryInfo

{

BEGIN_COM_MAP(CTxtInfoShlExt)

COM_INTERFACE_ENTRY(ITxtInfoShlExt)

COM_INTERFACE_ENTRY(IDispatch)

COM_INTERFACE_ENTRY(IPersistFile)

COM_INTERFACE_ENTRY(IQueryInfo)

END_COM_MAP()

Затем добавьте прототипы для методов IQueryInfo:

// IQueryInfo

STDMETHOD(GetInfoFlags)(DWORD*) { return E_NOTIMPL; }

STDMETHOD(GetInfoTip)(DWORD, LPWSTR*);

Метод GetInfoFlags() в данный момент не используется, поэтому мы возвращаем E_NOTIMPL. Метод GetInfoTip() передаст проводнику текст для отображения в тултипе. Начало несколько скучное:

HRESULT CTxtInfoShlExt::GetInfoTip (

DWORD dwFlags,

LPWSTR* ppwszTip )

{

AFX_MANAGE_STATE(AfxGetStaticModuleState()); // init MFC

LPMALLOC pMalloc;

CStdioFile file;

DWORD dwFileSize;

CString sFirstLine;

BOOL bReadLine;

CString sTooltip;

USES_CONVERSION;

Сначала мы вызываем AFX_MANAGE_STATE для инициализации MFC. Это нужно сделать в первую очередь, еще до объявления переменых, т.к. конструкторы будут вызывать MFC-функции.

dwFlags в данный момент не используется. ppwszTip - указатель на LPWSTR (указатель на строку UNICODE), который изначально будет указывать на буфер, который мы должны распределить. В первую очередь мы попытаемся открыть файл для чтения. Имя файла мы знаем, так как сохранили его в Load().

if ( !file.Open ( m_sFilename , CFile::modeRead | CFile::shareDenyWrite ))

return E_FAIL;

Теперь нам необходим указатель на интерфейс IMalloc, чтобы распределить буфер в разделяемой памяти оболочки. Этот указатель мы можем получить вызвав функцию SHGetMalloc():

if ( FAILED( SHGetMalloc ( &pMalloc )))

return E_FAIL;

Более подробно о IMalloc я расскажу позже. Дальше нам надо получить размер файла и первую строку:

// Get the size of the file.

dwFileSize = file.GetLength();

// Read in the first line from the file.

bReadLine = file.ReadString ( sFirstLine );

Если к файлу был получен доступ, и он не пустой, bReadLine примет значение TRUE. На следующем шаге мы создаем первую часть строки описания, которая отобразит размер файла:

sTooltip.Format ( _T("File size: %lu"), dwFileSize );

Теперь, если мы смогли прочитать первую строку файла, добавляем ее к строке описания:

if ( bReadLine )

{

sTooltip += _T("\n");

sTooltip += sFirstLine;

}

После того, как мы создадим строку описания, нужно поместить ее в буфер. Для этого используем IMalloc. Указатель, возвращаемый SHGetMalloc() - это копия интерфейса оболочки IMalloc. Вся память, которую мы выделяем с помощью этого интерфейса, находится в пространстве процесса оболочки, поэтому проводник имеет к ней доступ. Более того, оболочка может сама ее освободить. Так что мы размещаем буфер и забываем об этом. Оболочка сама освободит память сразу после окончания ее использования.

Мы должны помнить, что строка, которую мы передаем оболочке должна быть в UNICODE. Вот почему в выражении Alloc() (см. код ниже) есть умножение на sizeof(wchar_t). При выделении памяти просто для lstrlen(sToolTip) будет выделена только половина требуемого количества памяти.

*ppwszTip = (LPWSTR) pMalloc->Alloc ( (1 + lstrlen(sTooltip)) * sizeof(wchar_t) );

if ( NULL == *ppwszTip )

{

pMalloc->Release();

return E_OUTOFMEMORY;

}

// Use the Unicode string copy function to put the tooltip text in the buffer.

wcscpy ( *ppwszTip, T2COLE((LPCTSTR) sTooltip) );

И, наконец, нужно освободить интерфейс IMalloc, полученный ранее.

pMalloc->Release();

return S_OK;

}

Вот и все! Проводник берет строку в *ppwszTip и отображает ее в тултипе.

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