Windows 7 - Shell Extension dll Initialize, вызываемый дважды на левой панели проводника. - PullRequest
0 голосов
/ 27 марта 2012

У меня есть расширение DLL оболочки c ++. Метод Initialize вызывается дважды, если я щелкаю в окне обозревателя левой панели просмотра дерева папок. Но если я щелкну любую папку на правой панели окна проводника, метод Initialize вызывается один раз.

Проблема в том, что мои недавно добавленные пункты меню отображаются дважды в контекстном меню, если я нажимаю на представление дерева левой панели.

Мне интересно, это функциональность окна? Я прокомментировал всю мою реализацию и протестировал с помощью приведенного ниже кода:

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

Когда я нажимаю на левую панель, вывод DebugViewr:

Initialize

QueryContextMenu

Initialize

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}'
        }
    }
}

Приведенная выше запись реестра вызывает эту проблему в Win 7. Если я удалю «NoRemove Background», контекстное меню будет отображаться один раз в виде дерева. Но если я нажму на пустую область папки, метод Initialize вызываться не будет.

1 Ответ

0 голосов
/ 28 марта 2012

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

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