Nota
O acesso a esta página requer autorização. Pode tentar iniciar sessão ou alterar os diretórios.
O acesso a esta página requer autorização. Pode tentar alterar os diretórios.
IContextMenu é a interface mais poderosa, mas também a mais complicada de implementar. É altamente recomendável que você implemente um verbo usando um dos métodos de verbo estático. Para obter mais informações, consulte Escolhendo um método de menu de atalho estático ou dinâmico. IContextMenu tem três métodos, GetCommandString, InvokeCommande QueryContextMenu, que são discutidos aqui em detalhes.
O que precisa de saber
Tecnologias
- C++
Pré-requisitos
- Verbo estático
- Menu de atalho
Instruções
Método IContextMenu::GetCommandString
O manipulador IContextMenu::GetCommandString método é usado para retornar o nome canônico para um verbo. Este método é opcional. No Windows XP e versões anteriores do Windows, quando o Windows Explorer tem uma barra de status, esse método é usado para recuperar o texto de ajuda que é exibido na barra de status para um item de menu.
O parâmetro idCmd contém o deslocamento do identificador do comando que foi definido quando IContextMenu::QueryContextMenu foi chamado . Se uma cadeia de caracteres de ajuda for solicitada, uFlags será definido como GCS_HELPTEXTW. Copie a cadeia de caracteres de ajuda para o buffer pszName, convertendo-a em um PWSTR. A string do verbo é solicitada ao definir uFlags como GCS_VERBW. Copie a cadeia de caracteres apropriada para pszName, assim como acontece com a cadeia de caracteres de ajuda. Os sinalizadores GCS_VALIDATEA e GCS_VALIDATEW não são usados por manipuladores de menu de atalho.
O exemplo a seguir mostra uma implementação simples de GetCommandString que corresponde a um exemplo de QueryContextMenu fornecido na seção Método IContextMenu::QueryContextMenu deste tópico. Como o manipulador adiciona apenas um item de menu, há apenas um conjunto de cadeias de caracteres que podem ser retornadas. O método testa se idCmd é válido e, se for, retorna a cadeia de caracteres solicitada.
A função StringCchCopy é usada para copiar a cadeia de caracteres solicitada para pszName para garantir que a cadeia de caracteres copiada não exceda o tamanho do buffer especificado por cchName. Este exemplo implementa suporte somente para os valores Unicode de uFlags, porque somente esses foram usados no Windows Explorer desde o Windows 2000.
IFACEMETHODIMP CMenuExtension::GetCommandString(UINT idCommand,
UINT uFlags,
UINT *pReserved,
PSTR pszName,
UINT cchName)
{
HRESULT hr = E_INVALIDARG;
if (idCommand == IDM_DISPLAY)
{
switch (uFlags)
{
case GCS_HELPTEXTW:
// Only useful for pre-Vista versions of Windows that
// have a Status bar.
hr = StringCchCopyW(reinterpret_cast<PWSTR>(pszName),
cchName,
L"Display File Name");
break;
case GCS_VERBW:
// GCS_VERBW is an optional feature that enables a caller
// to discover the canonical name for the verb that is passed in
// through idCommand.
hr = StringCchCopyW(reinterpret_cast<PWSTR>(pszName),
cchName,
L"DisplayFileName");
break;
}
}
return hr;
}
Método IContextMenu::InvokeCommand
Esse método é chamado quando um usuário clica em um item de menu para dizer ao manipulador para executar o comando associado. O parâmetro pici aponta para uma estrutura que contém as informações necessárias para executar o comando.
Embora pici seja declarado em Shlobj.h como uma estrutura CMINVOKECOMMANDINFO, na prática ele geralmente aponta para uma estrutura CMINVOKECOMMANDINFOEX. Essa estrutura é uma versão estendida do CMINVOKECOMMANDINFO e tem vários membros adicionais que tornam possível passar cadeias de caracteres Unicode.
Verifique o membro cbSize de pici para determinar qual estrutura foi passada. Se for um estrutura de CMINVOKECOMMANDINFOEX e o membro fMask tiver o CMIC_MASK_UNICODE sinalizador definido, lance pici para CMINVOKECOMMANDINFOEX. Isso permite que seu aplicativo use as informações Unicode contidas nos últimos cinco membros da estrutura.
O membro da estrutura lpVerb ou o membro lpVerbW é usado para identificar o comando a ser executado. Os comandos são identificados de uma das seguintes maneiras:
- Pela string do verbo do comando
- Pelo deslocamento do identificador do comando
Para distinguir entre esses dois casos, verifique a palavra de ordem alta de lpVerb para o caso ANSI ou lpVerbW para o caso Unicode. Se a palavra de ordem superior for diferente de zero, lpVerb ou lpVerbW contém uma cadeia de caracteres de verbo. Se a palavra de ordem alta for zero, o deslocamento do comando estará na palavra de ordem baixa de lpVerb.
O exemplo a seguir mostra uma implementação simples de IContextMenu::InvokeCommand que corresponde ao IContextMenu::QueryContextMenu e IContextMenu::GetCommandString exemplos fornecidos antes e depois desta seção. Primeiro, o método determina qual estrutura está a ser passada. Em seguida, determina se o comando é identificado pelo seu deslocamento ou pelo seu verbo. Se lpVerb ou lpVerbW contiver um verbo válido ou um valor de offset, o método exibirá uma caixa de mensagem.
STDMETHODIMP CShellExtension::InvokeCommand(LPCMINVOKECOMMANDINFO lpcmi)
{
BOOL fEx = FALSE;
BOOL fUnicode = FALSE;
if(lpcmi->cbSize == sizeof(CMINVOKECOMMANDINFOEX))
{
fEx = TRUE;
if((lpcmi->fMask & CMIC_MASK_UNICODE))
{
fUnicode = TRUE;
}
}
if( !fUnicode && HIWORD(lpcmi->lpVerb))
{
if(StrCmpIA(lpcmi->lpVerb, m_pszVerb))
{
return E_FAIL;
}
}
else if( fUnicode && HIWORD(((CMINVOKECOMMANDINFOEX *) lpcmi)->lpVerbW))
{
if(StrCmpIW(((CMINVOKECOMMANDINFOEX *)lpcmi)->lpVerbW, m_pwszVerb))
{
return E_FAIL;
}
}
else if(LOWORD(lpcmi->lpVerb) != IDM_DISPLAY)
{
return E_FAIL;
}
else
{
MessageBox(lpcmi->hwnd,
"The File Name",
"File Name",
MB_OK|MB_ICONINFORMATION);
}
return S_OK;
}
Método IContextMenu::QueryContextMenu
O Shell chama IContextMenu::QueryContextMenu para habilitar o manipulador de menu de atalho para adicionar seus itens de menu ao menu. Ele introduz o identificador HMENU no parâmetro hmenu. O parâmetro indexMenu é definido como o índice a ser usado para o primeiro item de menu a ser adicionado.
Todos os itens de menu adicionados pelo manipulador devem ter identificadores que estejam entre os valores nos parâmetros idCmdFirst e idCmdLast. Normalmente, o primeiro identificador de comando é definido como idCmdFirst, que é incrementado em um (1) para cada comando adicional. Essa prática ajuda a evitar exceder idCmdLast e maximiza o número de identificadores disponíveis caso o Shell chame mais de um controlador.
O deslocamento de comando de um identificador de item é a diferença entre esse identificador e o valor em idCmdFirst. Armazene o deslocamento de cada item que seu manipulador adiciona ao menu de atalho, porque o Shell pode usar o deslocamento para identificar o item se, posteriormente, chamar IContextMenu::GetCommandString ou IContextMenu::InvokeCommand.
Você também deve atribuir um verbo a cada comando adicionado. Um verbo é uma cadeia de caracteres que pode ser usada em vez do deslocamento para identificar o comando quando InvokeCommand é chamado. Ele também é usado por funções como ShellExecuteEx para executar comandos de menu de atalho.
Há três sinalizadores que podem ser passados através do parâmetro uFlags que são relevantes para manipuladores de menu de atalho. Eles são descritos na tabela a seguir.
Bandeira | Descrição |
---|---|
CMF_DEFAULTONLY | O usuário selecionou o comando padrão, geralmente clicando duas vezes no objeto. IContextMenu::QueryContextMenu deve retornar o controle para o Shell sem modificar o menu. |
CMF_NODEFAULT | Nenhum item no menu deve ser o item padrão. O método deve adicionar seus comandos ao menu. |
CMF_NORMAL | O menu de atalho será exibido normalmente. O método deve adicionar seus comandos ao menu. |
Use InsertMenu ou InsertMenuItem para adicionar itens de menu à lista. Em seguida, retorne um valor HRESULT com a gravidade definida como SEVERITY_SUCCESS. Defina o valor do código como o deslocamento do maior identificador de comando atribuído, mais um (1). Por exemplo, suponha que idCmdFirst está definido como 5 e você adiciona três itens ao menu com identificadores de comando de 5, 7 e 8. O valor de retorno deve ser MAKE_HRESULT(SEVERITY_SUCCESS, 0, 8 + 1).
O exemplo a seguir mostra uma implementação simples de QueryContextMenu que insere um único comando. O deslocamento do identificador para o comando é IDM_DISPLAY, que está definido como zero. As variáveis m_pszVerb e m_pwszVerb são variáveis privadas que são usadas para armazenar a cadeia de caracteres de verbo independente de idioma associada nos formatos ANSI e Unicode.
#define IDM_DISPLAY 0
STDMETHODIMP CMenuExtension::QueryContextMenu(HMENU hMenu,
UINT indexMenu,
UINT idCmdFirst,
UINT idCmdLast,
UINT uFlags)
{
HRESULT hr;
if(!(CMF_DEFAULTONLY & uFlags))
{
InsertMenu(hMenu,
indexMenu,
MF_STRING | MF_BYPOSITION,
idCmdFirst + IDM_DISPLAY,
"&Display File Name");
hr = StringCbCopyA(m_pszVerb, sizeof(m_pszVerb), "display");
hr = StringCbCopyW(m_pwszVerb, sizeof(m_pwszVerb), L"display");
return MAKE_HRESULT(SEVERITY_SUCCESS, 0, USHORT(IDM_DISPLAY + 1));
}
return MAKE_HRESULT(SEVERITY_SUCCESS, 0, USHORT(0));}
Comentários
Para outras tarefas de implementação de verbos, consulte Criando manipuladores de menu de atalho.