2012-03-27 38 views
0

我有一個c + +外殼擴展DLL。 初始化方法被調用兩次,如果我點擊瀏覽器窗口左窗格樹視圖文件夾。但是,如果我單擊瀏覽器窗口右窗格上的任何文件夾,則會調用Initialize方法一次。Windows 7 - 外殼擴展dll初始化在瀏覽器左窗格上調用兩次的方法

問題是我新添加的菜單項在上下文菜單中顯示兩次,如果我點擊左窗格樹視圖。

我在想,它是一個窗口功能嗎? 我評論過我的所有的實現和測試與下面的代碼:

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輸出爲:

初始化

QueryContextMenu

初始化

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方法將不會被調用。

+0

我假設你正在談論一個上下文菜單外殼擴展。如果是這樣,它肯定不是一個正確的Windows功能。你可以發佈一些代碼嗎? – Flot2011 2012-03-27 21:14:45

+0

初始化(LPCITEMIDLIST pidlFolder,LPDATAOBJECT pDO,HKEY/* hkeyProgID * /)。我正在用這種方法做我的菜單人口。我在這個函數中添加了日誌消息,它看起來像初始化方法調用兩次。 – kanden 2012-03-27 21:22:03

+0

您可以發佈代碼而不僅是簽名嗎?否則,它只是一個猜謎遊戲。 – Flot2011 2012-03-27 21:24:35

回答

0

我發佈了一個來自我的真實程序的工作示例(爲清楚起見省略了應用程序特定代碼)。請嘗試。

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); 
    } 
+0

感謝Flot2011,我會盡力實現你的代碼 – kanden 2012-03-27 22:25:06

+0

我已經實現了你的代碼,Initialize方法被調用兩次。但QueryContextMenu從未調用過 – kanden 2012-03-27 22:40:13

+0

這個問題只發生在Windows 7中 – kanden 2012-03-28 15:50:28