Megosztás:


Az IContextMenu felület implementálása

IContextMenu a leghatékonyabb, de egyben a legbonyolultabb felület is. Javasoljuk, hogy a statikus igemódszerek egyikével implementáljon egy igét. További információ: Statikus vagy dinamikus gyorsmenü módszer kiválasztása. IContextMenu három metódussal rendelkezik: GetCommandString, InvokeCommandés QueryContextMenu, amelyekről itt olvashat részletesen.

Amit tudnia kell

Technológiák

  • C++

Előfeltételek

  • Statikus ige
  • Gyorsmenü

Előírás

IContextMenu::GetCommandString metódus

A kezelő IContextMenu::GetCommandString metódust használják arra, hogy visszaadja az ige kanonikus nevét. Ez a módszer nem kötelező. A Windows XP és a Windows korábbi verzióiban, amikor a Windows Intéző állapotsort használ, ez a módszer a menüelem Állapotsávjában megjelenő súgószöveg lekérésére szolgál.

Az idCmd paraméter tartalmazza az IContextMenu::QueryContextMenu meghívásakor definiált parancs azonosító eltolását. Ha egy súgósztringet kérnek, a uFlags az GCS_HELPTEXTWértékre lesz beállítva. Másolja a súgó sztringet a pszName pufferbe, alakítva azt egy PWSTR-típussá. Az ige sztring a uFlagsGCS_VERBWbeállításával kérhető le. Másolja a megfelelő karaktersorozatot a pszNamehelyére, ugyanúgy, mint a segítség karaktersorozatában. A helyi menükezelők nem használják a GCS_VALIDATEA és GCS_VALIDATEW jelzőket.

Az alábbi példa a GetCommandString egyszerű implementációját mutatja be, amely a QueryContextMenu példa alapján készült, a IContextMenu::QueryContextMenu metódus szakaszában található példának megfelelően. Mivel a kezelő csak egy menüelemet ad hozzá, csak egy sztringkészlet adható vissza. A metódus ellenőrzi, hogy idCmd érvényes-e, és ha igen, a kért sztringet adja vissza.

A StringCchCopy függvénnyel a kért karaktersorozatot átmásolhatja a pszName változóba, hogy a másolt karaktersorozat ne lépje túl a cchNameáltal meghatározott puffer méretét. Ez a példa csak az uFlagsUnicode-értékeit támogatja, mivel a Windows Intézőben a Windows 2000 óta csak azokat használják.

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 metódusa

Ezt a metódust akkor hívja meg a rendszer, ha egy felhasználó egy menüelemre kattint, hogy a kezelő a társított parancs futtatására utasítsa. A pici paraméter egy olyan struktúrára mutat, amely tartalmazza a parancs futtatásához szükséges információkat.

Bár pici a Shlobj.h-ban CMINVOKECOMMANDINFO szerkezetként van deklarálva, a gyakorlatban gyakran egy CMINVOKECOMMANDINFOEX struktúrára mutat. Ez a struktúra a CMINVOKECOMMANDINFO bővített verziója, és számos további taggal rendelkezik, amelyek lehetővé teszik Unicode-sztringek átadását.

Ellenőrizze a cbSize tagot a pici struktúrában annak megállapításához, hogy melyik struktúrát adták át. Ha ez egy CMINVOKECOMMANDINFOEX struktúra, és a fMask tagban be van állítva a CMIC_MASK_UNICODE jelző, akkor a pici legyen CMINVOKECOMMANDINFOEX. Ez lehetővé teszi, hogy az alkalmazás a struktúra utolsó öt tagjában található Unicode-információkat használja.

A struktúra lpVerb vagy lpVerbW tagjával azonosítja a végrehajtandó parancsot. A parancsok az alábbi két módszer egyikével azonosíthatók:

  • A parancs igesztringje alapján
  • A parancs azonosító eltolása alapján

A két eset megkülönböztetéséhez ellenőrizze a lpVerb magas szintű szósorát az ANSI-esetnél, vagy lpVerbW a Unicode-esethez. Ha a magasrendű szó nem nulla, akkor lpVerb vagy lpVerbW egy igét tartalmaz. Ha a magasrendű szó nulla, a parancseltolás az lpVerbalacsonyrendű szavában található.

Az alábbi példa a IContextMenu::InvokeCommand egyszerű implementációját mutatja be, amely megfelel a IContextMenu::QueryContextMenu és IContextMenu::GetCommandString a szakasz előtt és után megadott példáknak. A metódus először meghatározza, hogy melyik struktúrát adja át a rendszer. Ezután meghatározza, hogy a parancsot az eltolás vagy az ige azonosítja-e. Ha lpVerb vagy lpVerbW érvényes igét vagy eltolást tartalmaz, a metódus megjelenít egy üzenetmezőt.

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 metódus

A Shell meghívja a IContextMenu::QueryContextMenu-t, hogy a helyi menükezelő hozzáadhassa a saját elemeit a menühöz. Az HMENU fogantyú a hmenu paraméterben halad át. Az indexMenu paraméter a hozzáadni kívánt első menüelemhez használandó indexre van állítva.

A kezelő által hozzáadott menüelemeknek olyan azonosítókkal kell rendelkezniük, amelyek az idCmdFirst és idCmdLast paraméter értékei közé esnek. Az első parancsazonosító általában idCmdFirstértékre van állítva, amely minden további parancshoz egy -1-gyel növekszik. Ez a gyakorlat segít elkerülni idCmdLast túllépését, és maximalizálja az elérhető azonosítók számát, ha a Shell több kezelőt hív meg.

Az elemazonosító parancs eltolása az azonosító és az idCmdFirstértéke közötti különbség. Tárolja a kezelő által a helyi menübe felvett egyes elemek eltolását, mert előfordulhat, hogy a Rendszerhéj az eltolással azonosítja az elemet, ha később meghívja IContextMenu::GetCommandString vagy IContextMenu::InvokeCommand.

Emellett minden egyes hozzáadott parancshoz hozzá kell rendelnie egy igét. Az ige olyan sztring, amely az eltolás helyett használható a parancs azonosítására InvokeCommand meghívásakor. Olyan függvények is használják, mint a ShellExecuteEx a helyi menüparancsok végrehajtásához.

Három jelölő adható át az uFlags paraméteren keresztül, amelyek relevánsak a helyi menükezelők számára. Ezeket a következő táblázatban ismertetjük.

Zászló Leírás
CMF_DEFAULTONLY A felhasználó az alapértelmezett parancsot választotta ki, általában az objektumra duplán kattintva. IContextMenu::QueryContextMenu a menü módosítása nélkül vissza kell adnia a vezérlést a rendszerhéjnak.
CMF_NODEFAULT A menü egyik eleme sem lehet az alapértelmezett elem. A metódusnak hozzá kell adnia a parancsait a menühöz.
CMF_NORMAL A parancsikon menü normál módon jelenik meg. A metódusnak hozzá kell adnia a parancsait a menühöz.

 

InsertMenu vagy InsertMenuItem használatával adhat hozzá menüelemeket a listához. Ezután adjon vissza egy HRESULT értéket, a súlyosságot SEVERITY_SUCCESS-ra állítva. Állítsa a kód értékét a legnagyobb hozzárendelt parancsazonosító eltolására, plusz egy (1) értékre. Tegyük fel például, hogy idCmdFirst értéke 5, és három elemet ad hozzá a menühöz az 5, 7 és 8 parancsazonosítóval. A visszatérési értéknek MAKE_HRESULT(SEVERITY_SUCCESS, 0, 8 + 1) kell lennie.

Az alábbi példa a QueryContextMenu egyszerű implementációját mutatja be, amely egyetlen parancsot szúr be. Az IDM_DISPLAY parancs azonosító eltolása nulla értékre van állítva. A m_pszVerb és m_pwszVerb változók olyan privát változók, amelyek a társított nyelvfüggetlen igesztringet ANSI- és Unicode-formátumban is tárolják.

#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));}

Megjegyzések

Más igemegvalósítási feladatokért lásd: Helyi menükezelők létrehozása.