c ++ - Windows 7 - Shell Extension dll Initialiser metode kaldes to gange på explorer venstre rude

Indlæg af Hanne Mølgaard Plasc

Problem



Jeg har en c ++ shell extension dll. Metoden Initialiser kaldes to gange, hvis jeg klikker på explorer-vinduet i venstre paneletræsvisning. Men hvis jeg klikker på nogen mapper i explorervinduets højre rude, kaldes Initialize-metoden en gang.


Problemet er, at mine nyligt tilføjede menupunkter viser to gange i kontekstmenuen, hvis jeg klikker på den venstre rudevisning.


Jeg undrer mig over, er det en vinduesfunktionalitet?
Jeg har kommenteret hele min implementering og testet med nedenstående kode:


IFACEMETHODIMP CMyContextMenu::QueryContextMenu(HMENU hmenu, UINT /*uIndex*/, UINT    cmdFirst, UINT /*uidCmdLast*/, UINT /*uFlags*/ )
{
UINT cmdId = uidCmdFirst;
OutputDebugString(L"QueryContextMenu");

    return MAKE\_HRESULT ( SEVERITY\_SUCCESS, FACILITY\_NULL,  cmdId  - mdFirst );
}


IFACEMETHODIMP CMyContextMenu::Initialize(LPCITEMIDLIST pidlFolder, LPDATAOBJECT  pDO, HKEY /*hkeyProgID*/)
{
OutputDebugString(L"Initialize");
return S\_OK;
}


Når jeg klikker på venstre rude, er DebugViewr-udgangen:


Initialiser


QueryContextMenu


Initialiser


QueryContextMenu


NoRemove Directory
{
    NoRemove Background
    {
        NoRemove ShellEx
        {
            NoRemove ContextMenuHandlers
            {
                ForceRemove myContext = s '{AE843198-3C5D-4EA6-B74F-7A41FC91D7FF}'
            }
        }
    }
}

NoRemove Directory
{
    NoRemove ShellEx
    {
        NoRemove ContextMenuHandlers
        {
            ForceRemove myContext = s '{AE843198-3C5D-4EA6-B74F-7A41FC91D7FF}'
        }
    }
}


Ovenstående registerindgang forårsager dette problem i Win 7. Hvis jeg fjerner 'NoRemove Background', vil kontekstmenuen blive vist en gang i trævisningen. Men hvis jeg klikker på mappe tomt område Initialiser metode vil ikke blive påkaldt.

Bedste reference


Jeg sender et arbejdseksempel fra mit rigtige program (en applikationsspecifik kode udelades for klarhed). Prøv det.


STDMETHODIMP CShlExtExample::Initialize (
LPCITEMIDLIST pidlFolder, LPDATAOBJECT pDataObj, HKEY hProgID )
{
 FORMATETC fmt = { CF\_HDROP, NULL, DVASPECT\_CONTENT, -1, TYMED\_HGLOBAL };
 STGMEDIUM stg = { TYMED\_HGLOBAL };
 HDROP     hDrop;

   // Look for CF\_HDROP data in the data object.
   if ( FAILED( pDataObj->GetData ( &fmt, &stg ) ))
   {
       // Return an "invalid argument" error.
       return E\_INVALIDARG;
   }

   // Get a pointer to the actual data.
   hDrop = (HDROP) GlobalLock ( stg.hGlobal ); 
   if ( NULL == hDrop )
       return E\_INVALIDARG;

   // Make sure there is at least one file to show menu for.
   UINT uNumFiles = DragQueryFile ( hDrop, 0xFFFFFFFF, NULL, 0 );
   HRESULT hr = S\_OK;  
   if ( 0 == uNumFiles )
   {
       GlobalUnlock ( stg.hGlobal );
       ReleaseStgMedium ( &stg );
       return E\_INVALIDARG;
   }

   // Application specific code.

   GlobalUnlock ( stg.hGlobal );
   ReleaseStgMedium ( &stg );

   return hr;


}


   STDMETHODIMP CShlExtExample::QueryContextMenu (
   HMENU hmenu, UINT uMenuIndex, UINT uidFirstCmd,
   UINT uidLastCmd, UINT uFlags )
   {
     // If the flags include CMF\_DEFAULTONLY then do nothing.
     if ( uFlags & CMF\_DEFAULTONLY )
         return MAKE\_HRESULT ( SEVERITY\_SUCCESS, FACILITY\_NULL, 0 );

   InsertMenu ( hmenu, uMenuIndex, MF\_BYPOSITION, uidFirstCmd, \_T("Test Item") );

   return MAKE\_HRESULT ( SEVERITY\_SUCCESS, FACILITY\_NULL, 1 );
   }