Nuta
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować się zalogować lub zmienić katalog.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
IContextMenu jest najbardziej wydajnym, ale także najbardziej skomplikowanym interfejsem do zaimplementowania. Zdecydowanie zalecamy zaimplementowanie czasownika przy użyciu jednej ze statycznych metod czasownika. Aby uzyskać więcej informacji, zobacz Wybieranie statycznej lub dynamicznej metody menu skrótów. IContextMenu ma trzy metody, GetCommandString, InvokeCommandi QueryContextMenu, które zostały szczegółowo omówione tutaj.
Co musisz wiedzieć
Technologie
- C++
Warunki wstępne
- Czasownik statyczny
- Menu skrótów
Instrukcje
IContextMenu::GetCommandString — Metoda
Metoda programu obsługi IContextMenu::GetCommandString jest używana do zwracania nazwy kanonicznej czasownika. Ta metoda jest opcjonalna. W systemie Windows XP i starszych wersjach systemu Windows, gdy Eksplorator Windows ma pasek stanu, ta metoda służy do pobierania tekstu pomocy wyświetlanego na pasku stanu dla elementu menu.
Parametr idCmd przechowuje przesunięcie identyfikatora polecenia zdefiniowanego podczas wywołania IContextMenu::QueryContextMenu. Jeśli zażądano ciągu pomocy, uFlags zostanie ustawione na wartość GCS_HELPTEXTW. Skopiuj ciąg pomocy do buforu pszName, rzutując go na PWSTR. Ciąg czasowników jest żądany przez ustawienie uFlags na GCS_VERBW. Skopiuj odpowiedni ciąg do pszName, tak jak w przypadku ciągu pomocy. Flagi GCS_VALIDATEA i GCS_VALIDATEW nie są używane przez programy obsługi menu skrótów.
Poniższy przykład przedstawia prostą implementację GetCommandString, która odpowiada przykładowi QueryContextMenu podanemu w sekcji metody IContextMenu::QueryContextMenu tego tematu. Ponieważ program obsługi dodaje tylko jeden element menu, istnieje tylko jeden zestaw ciągów, które można zwrócić. Metoda sprawdza, czy idCmd jest prawidłowa, a jeśli tak, zwraca żądany ciąg.
FunkcjastringCchCopysłuży do kopiowania żądanego ciągu do pszName, aby upewnić się, że skopiowany ciąg nie przekracza rozmiaru buforu określonego przez cchName. W tym przykładzie zaimplementowano obsługę tylko wartości Unicode uFlags, ponieważ tylko te zostały użyte w Eksploratorze Windows od systemu 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;
}
IContextMenu::InvokeCommand — Metoda
Ta metoda jest wywoływana, gdy użytkownik kliknie element menu, aby poinformować program obsługi o uruchomieniu skojarzonego polecenia. Parametr pici wskazuje strukturę zawierającą informacje wymagane do uruchomienia polecenia.
Mimo że pici jest deklarowane w Shlobj.h jako struktura CMINVOKECOMMANDINFO, w praktyce często wskazuje na strukturę CMINVOKECOMMANDINFOEX. Ta struktura jest rozszerzoną wersją CMINVOKECOMMANDINFO i ma kilka dodatkowych elementów, które umożliwiają przekazywanie ciągów Unicode.
Sprawdź cbSize element pici, aby stwierdzić, która struktura została przekazana. Jeśli jest to struktura CMINVOKECOMMANDINFOEX, a element członkowski maski ma ustawioną flagę CMIC_MASK_UNICODE, zrzutuj pici do CMINVOKECOMMANDINFOEX. Dzięki temu aplikacja może korzystać z danych Unicode zawartych w ostatnich pięciu elementach struktury.
Człon lpVerb lub lpVerbW służy do identyfikowania polecenia do wykonania. Polecenia są identyfikowane na jeden z następujących dwóch sposobów:
- Według ciągu czasownika polecenia
- Według przesunięcia identyfikatora polecenia
Aby rozróżnić te dwa przypadki, sprawdź wyraz o wysokiej kolejności lpVerb dla przypadku ANSI lub lpVerbW przypadku Unicode. Jeśli słowo wyższego rzędu jest niezerowe, lpVerb lub lpVerbW przechowuje ciąg czasownika. Jeśli wyraz o wysokiej kolejności ma wartość zero, przesunięcie polecenia znajduje się w wyrazie o niskiej kolejności lpVerb.
W poniższym przykładzie pokazano prostą implementację IContextMenu::InvokeCommand, która odpowiada przykładom IContextMenu::QueryContextMenu oraz IContextMenu::GetCommandString podanych przed i po tej sekcji. Metoda najpierw określa, która struktura jest przekazywana. Następnie określa, czy polecenie jest identyfikowane przez przesunięcie, czy czasownik. Jeśli lpVerb lub lpVerbW przechowuje prawidłowy czasownik lub przesunięcie, metoda wyświetla okno dialogowe.
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;
}
IContextMenu::QueryContextMenu — Metoda
Powłoka wywołuje IContextMenu::QueryContextMenu, aby włączyć obsługę menu kontekstowego i dodać jego elementy do menu. Przechodzi w dojściu HMENU w parametrze hmenu. Parametr indexMenu jest ustawiony na indeks, który ma być używany dla pierwszego elementu menu, który ma zostać dodany.
Wszystkie elementy menu dodane przez program obsługi muszą mieć identyfikatory, które znajdują się pomiędzy wartościami parametrów idCmdFirst i idCmdLast. Zazwyczaj pierwszy identyfikator polecenia jest ustawiony na idCmdFirst, który jest zwiększany o jeden (1) dla każdego dodatkowego polecenia. Ta praktyka pomaga uniknąć przekroczenia idCmdLast i maksymalizuje liczbę dostępnych identyfikatorów, jeśli Shell wywołuje więcej niż jeden program obsługi.
Przesunięcie polecenia identyfikatora elementu jest różnicą między identyfikatorem a wartością w idCmdFirst. Zapisz przesunięcie każdego elementu, który obsługujący dodaje do menu skrótów, ponieważ powłoka może użyć przesunięcia, aby zidentyfikować element, jeśli następnie wywołuje metodę IContextMenu::GetCommandString lub IContextMenu::InvokeCommand.
Należy również przypisać czasownik do każdego dodanego polecenia. Czasownik to ciąg znaków, którego można użyć zamiast offsetu, aby zidentyfikować polecenie, gdy wywoływana jest InvokeCommand. Jest również używany przez takie funkcje, jak ShellExecuteEx do wykonywania poleceń menu skrótów.
Istnieją trzy flagi, które można przekazać za pośrednictwem parametru uFlags, które są istotne dla obsług menu skrótów. Zostały one opisane w poniższej tabeli.
| Flaga | Opis |
|---|---|
| CMF_DEFAULTONLY | Użytkownik wybrał domyślne polecenie, zwykle klikając dwukrotnie obiekt. IContextMenu::QueryContextMenu powinna zwrócić kontrolkę do powłoki bez modyfikowania menu. |
| CMF_NODEFAULT | Żaden element w menu nie powinien być elementem domyślnym. Metoda powinna dodać polecenia do menu. |
| CMF_NORMAL | Menu skrótów będzie wyświetlane normalnie. Metoda powinna dodać polecenia do menu. |
Użyj InsertMenu lub InsertMenuItem, aby dodać elementy menu do listy. Następnie zwróć wartość typu HRESULT z poziomem istotności ustawionym na SEVERITY_SUCCESS. Ustaw wartość kodu na przesunięcie od największego przypisanego identyfikatora polecenia, plus jeden (1). Załóżmy na przykład, że idCmdFirst jest ustawiona na 5 i dodajesz trzy elementy do menu z identyfikatorami poleceń 5, 7 i 8. Wartość zwracana powinna być MAKE_HRESULT(SEVERITY_SUCCESS, 0, 8 + 1).
Poniższy przykład przedstawia prostą implementację QueryContextMenu, która wstawia jedno polecenie. Przesunięcie identyfikatora w poleceniu to IDM_DISPLAY, który jest ustawiony na zero. Zmienne m_pszVerb i m_pwszVerb to zmienne prywatne, które są używane do przechowywania skojarzonego ciągu czasownika niezależnego od języka zarówno w formatach ANSI, jak i 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));}
Uwagi
Aby zapoznać się z innymi zadaniami implementacji czasowników, zobacz Tworzenie programów obsługi menu skrótów.