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

Добавление пунктов к меню

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

Вот как будут выглядеть пункты, которые мы добавим к контекстному меню. Однин для регистрации файлов, другой - для из разрегистрации.

Начало реализации QueryContextMenu() аналогично описанному в первой части. Мы проверяем uFlags и немедленно делаем возврат, если обнаружим флаг CMF_DEFAULTONLY.

HRESULT CDLLRegShlExt::QueryContextMenu (

HMENU hmenu,

UINT uMenuIndex,

UINT uidFirstCmd,

UINT uidLastCmd,

UINT uFlags )

{

UINT uCmdID = uidFirstCmd;

// If the flags include CMF_DEFAULTONLY then we shouldn't do anything.

if ( uFlags & CMF_DEFAULTONLY )

{

return MAKE_HRESULT ( SEVERITY_SUCCESS, FACILITY_NULL, 0 );

}

Затем мы добавляем пункт меню "Register servers". Далее кое-что новенькое. Мы установим картинку для этого пункта. Таким образом, перед нашим пунктом меню будет появляться пиктограмма, также как это делает WinZip.

// Add our register/unregister items.

InsertMenu ( hmenu, uMenuIndex, MF_STRING | MF_BYPOSITION, uCmdID++,

_T("Register server(s)") );

// Set the bitmap for the register item.

if ( NULL != m_hRegBmp )

{

SetMenuItemBitmaps ( hmenu, uMenuIndex, MF_BYPOSITION, m_hRegBmp, NULL );

}

uMenuIndex++;

Функция API SetMenuItemBitmaps() приводит в действие механизм отображения картинки перед пунктом меню "Register servers". Заметьте, что uCmdID инкрементируется для следующего вызова InsertMenu(). И в конце этого шага также наращивается uMenuIndex, так что второй пункт меню появится вслед за первым.

Далее следует добавление второго пункта меню. Код реализации идентичен коду для первого пункта.

InsertMenu ( hmenu, uMenuIndex, MF_STRING | MF_BYPOSITION, uCmdID++,

_T("Unregister server(s)") );

// Set the bitmap for the unregister item.

if ( NULL != m_hUnregBmp )

{

SetMenuItemBitmaps ( hmenu, uMenuIndex, MF_BYPOSITION, m_hUnregBmp, NULL );

}

В конце мы сообщаем проводнику, сколько пунктов меню мы добавили:

return MAKE_HRESULT ( SEVERITY_SUCCESS, FACILITY_NULL, 2 );

Подсказка в строке состояния и "действие"

Для отображения подсказки и извлечения "действия" из добавленных команд проводнику потребуется вызвать метод GetCommandString(). Создаваемое нами расширение отличается тем, что добавляет два пункта к меню. Поэтому, чтобы определить какой из пунктов меню был выделен, нам потребуется исследовать параметр uCmdID:

#include <atlconv.h>

HRESULT CDLLRegShlExt::GetCommandString (

UINT uCmdID,

UINT uFlags,

UINT* puReserved,

LPSTR szName,

UINT cchMax )

{

LPCTSTR szPrompt;

USES_CONVERSION;

if ( uFlags & GCS_HELPTEXT )

{

switch ( uCmdID )

{

case 0:

szPrompt = _T("Register all selected COM servers");

break;

case 1:

szPrompt = _T("Unregister all selected COM servers");

break;

default:

return E_INVALIDARG;

break;

}

Если uCmdID равен 0, то выделен первый пункт (регистрация), если 1, то второй (разрегистрация). После этого мы определяем строку подсказки, копируем ее в установленный буфер, конвертируя в UNICODE, если это необходимо.

// Copy the help text into the supplied buffer. If the shell wants

// a Unicode string, we need to case szName to an LPCWSTR.

if ( uFlags & GCS_UNICODE )

{

lstrcpynW ( (LPWSTR) szName, T2CW(szPrompt), cchMax );

}

else

{

lstrcpynA ( szName, T2CA(szPrompt), cchMax );

}

}

Я также написал для этого расширения код, который извлекает "действие". Однако, при тестировании на Windows 98 проводник никогда не пытался вызвать GetCommandString(), чтобы извлечь "действие". Я даже написал пробную программу, которая вызывала ShellExecute() для DLL и пыталась использовать "действие". Но ничего не работало. Я не знаю, отличается ли чем-то поведение в Windows NT. По этой причине я опустил реализацию кода извлечения "действия", но вы можете попробовать реализовать его самостоятельно, если вам интересно.

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