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

Отображение всплывающей подсказки в строке состояния.

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

#include <atlconv.h> // for ATL string conversion macros

STDMETHODIMP CBmpCtxMenuExt::GetCommandString (

UINT uCmd, UINT uFlags, UINT* puReserved,

LPSTR pszName, UINT cchMax )

{

static LPCTSTR szHelpString = _T("Select this thumbnail to view the entire picture.");

USES_CONVERSION;

// Check idCmd, it must be 0 since we have only one menu item.

if ( 0 != uCmd )

return E_INVALIDARG;

// If Explorer is asking for a help string, copy our string into the

// supplied buffer.

if ( uFlags & GCS_HELPTEXT )

{

if ( uFlags & GCS_UNICODE )

{

// We need to cast pszName to a Unicode string, and then use the

// Unicode string copy API.

lstrcpynW ( (LPWSTR) pszName, T2CW(szHelpString), cchMax );

}

else

{

// Use the ANSI string copy API to return the help string.

lstrcpynA ( pszName, T2CA(szHelpString), cchMax );

}

}

return S_OK;

}

Выполнение выбора пользователя.

Последний метод в IContextMenu - это InvokeCommand(). Этот метод будет вызван, если пользователь щелкнет на пункте меню, добавленном нами. Расширение вызовет ShellExecute(), чтобы открыть картинку в Paint (или другой программе, ассоциированной с BMP-файлами).

STDMETHODIMP CBmpCtxMenuExt::InvokeCommand ( LPCMINVOKECOMMANDINFO pInfo )

{

// If lpVerb really points to a string, ignore this function call and bail out.

if ( 0 != HIWORD( pInfo->lpVerb ))

return E_INVALIDARG;

// The command ID must be 0 since we only have one menu item.

if ( 0 != LOWORD( pInfo->lpVerb ))

return E_INVALIDARG;

// Open the bitmap in the default paint program.

ShellExecute ( pInfo->hwnd, _T("open"), m_szFile, NULL, NULL, SW_SHOWNORMAL );

return S_OK;

}

Рисование пункта меню.

Итак, держу пари, вы заскучали к этому времени со всеми этими кодами, которые вы видели и раньше. Пора приступить к новым и интересным штучкам! Два дополнительных метода IContextMenu2 и IContextMenu3 приведены ниже. Они просто вызывают единственную вспомогательную функцию, которая, в свою очередь, вызывает обработчик сообщений. Я разработал этот метод чтобы избежать двух разных версий обработчиков сообщений (по одному для IContextMenu2 и IContextMenu3). В HandleMenuMsg2() есть одна странность, связанная с параметром LRESULT, которую я объясню в комментариях.

STDMETHODIMP CBmpCtxMenuExt::HandleMenuMsg ( UINT uMsg, WPARAM wParam, LPARAM lParam )

{

AFX_MANAGE_STATE(AfxGetStaticModuleState());

// res - подставная переменная типа LRESULT. Она не используется

// (IContextMenu2::HandleMenuMsg() не предоставляет способа

// возвращать результат), но она здесь для того, чтобы

// код в MenuMessageHandler() мог быть одинаковым

// независимо от того, через какой интерфейс

// был получен вызов (IContextMenu2 или 3).

LRESULT res;

return MenuMessageHandler ( uMsg, wParam, lParam, &res );

}

STDMETHODIMP CBmpCtxMenuExt::HandleMenuMsg2 ( UINT uMsg, WPARAM wParam, LPARAM lParam,

LRESULT* pResult )

{

AFX_MANAGE_STATE(AfxGetStaticModuleState());

// Для сообщений, которые не имеют возвращаемых значений,

// pResult есть NULL. Это очень плохо со стороны MS, поскольку это

// вынуждает нас проверять корректность pResult перед использованием.

// Вы могли бы подумать, что указатель

// к возвращаемому значению всегда должен бы быть действительным,

// но нет. Если он NULL, я создаю подставную переменную,

// поэтому код в MenuMessageHandler() всегда будет иметь

// действительный указатель pResult .

if ( NULL == pResult )

{

LRESULT res;

return MenuMessageHandler ( uMsg, wParam, lParam, &res );

}

else

{

return MenuMessageHandler ( uMsg, wParam, lParam, pResult );

}

}

MenuMessageHandler() просто пересылает WM_MEASUREITEM и WM_DROWITEM отдельным функциям-обработчикам сообщений.

STDMETHODIMP CBmpCtxMenuExt::MenuMessageHandler ( UINT uMsg, WPARAM wParam,

LPARAM lParam, LRESULT* pResult )

{

switch ( uMsg )

{

case WM_MEASUREITEM:

return OnMeasureItem ( (MEASUREITEMSTRUCT*) lParam, pResult );

break;

case WM_DRAWITEM:

return OnDrawItem ( (DRAWITEMSTRUCT*) lParam, pResult );

break;

}

return S_OK;

}

Как я отмечал раньше, документация говорит, что оболочка должна позволять нашему расширению оперировать с WM_INITMENUPOPUP и WM_MENUCHAR. Но за все время моих опытов я никогда не видел, чтобы эти сообщения приходили.

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