2013-02-10 85 views
0

你好,我试图在外壳扩展中的上下文菜单中获得级联窗口。我在.dll扩展的上下文菜单中添加了两个子菜单,,但想要创建一个级联子菜单(我喜欢打开第一个菜单,并在点击某个菜单后想打开下一个子菜单)。C++的上下文菜单外壳扩展中的级联子菜单

如何从此代码获取级联子菜单,我在哪里犯错?

// OpenWithCtxMenuExt.cpp : Implementation of COpenWithCtxMenuExt 

#include "stdafx.h" 
#include "OpenWithExt.h" 
#include "OpenWithCtxMenuExt.h" 

#pragma comment(lib,"shlwapi") 

///////////////////////////////////////////////////////////////////////////// 
// COpenWithCtxMenuExt 

HRESULT COpenWithCtxMenuExt::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))) 
     { 
     // Nope! Return an "invalid argument" error back to Explorer. 
     return E_INVALIDARG; 
     } 

    // Get a pointer to the actual data. 
    hDrop = (HDROP) GlobalLock (stg.hGlobal); 

    // Make sure it worked. 
    if (NULL == hDrop) 
     return E_INVALIDARG; 

    // Sanity check - make sure there is at least one filename. 
UINT uNumFiles = DragQueryFile (hDrop, 0xFFFFFFFF, NULL, 0); 

    if (0 == uNumFiles) 
     { 
     GlobalUnlock (stg.hGlobal); 
     ReleaseStgMedium (&stg); 
     return E_INVALIDARG; 
     } 

HRESULT hr = S_OK; 

    // Get the name of the first file and store it in our member variable m_szFile. 
    if (0 == DragQueryFile (hDrop, 0, m_szSelectedFile, MAX_PATH)) 
     hr = E_INVALIDARG; 
    else 
     { 
     // Quote the name if it contains spaces (needed so the cmd line is built properly) 
     PathQuoteSpaces (m_szSelectedFile); 
     } 

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

    return hr; 
} 

HRESULT COpenWithCtxMenuExt::QueryContextMenu (HMENU hmenu, UINT uMenuIndex, 
               UINT uidFirstCmd, UINT uidLastCmd, 
               UINT uFlags) 
{ 
    // If the flags include CMF_DEFAULTONLY then we shouldn't do anything. 
    if (uFlags & CMF_DEFAULTONLY) 
     return MAKE_HRESULT (SEVERITY_SUCCESS, FACILITY_NULL, 0); 

    // First, create and populate a submenu. 
HMENU hSubmenu = CreatePopupMenu(); 
HMENU hSubmenu1 = CreatePopupMenu(); 
UINT uID = uidFirstCmd; 

    InsertMenu (hSubmenu, 0, MF_BYPOSITION, uID++, _T("&Notepad")); 
    InsertMenu (hSubmenu, 1, MF_BYPOSITION, uID++, _T("&Internet Explorer")); 
    InsertMenu (hSubmenu, 2, MF_BYPOSITION, uID++, _T("&Mspaint")); 
    InsertMenu (hSubmenu, 3, MF_BYPOSITION, uID++, _T("&Pop")); 

// provjeriti uID da se ne zbraja 
    InsertMenu (hSubmenu1, 0, MF_BYPOSITION, uID++, _T("&Notepad")); 
    InsertMenu (hSubmenu1, 1, MF_BYPOSITION, uID++, _T("&Mspaint")); 


    // Insert the submenu into the ctx menu provided by Explorer. 
MENUITEMINFO mii = { sizeof(MENUITEMINFO) }; 

    mii.fMask = MIIM_SUBMENU | /*MIIM_STRING*/ 0x00000040 | MIIM_ID; 
    mii.wID = uID++; 
    mii.hSubMenu = hSubmenu; 
    mii.dwTypeData = _T("C&P Open With"); 

    InsertMenuItem (hmenu, uMenuIndex, TRUE, &mii); 

     // Insert the submenu into the ctx menu provided by Explorer. 
MENUITEMINFO mii1 = { sizeof(MENUITEMINFO) }; 

    mii1.fMask = MIIM_SUBMENU | /*MIIM_STRING*/ 0x00000040 | MIIM_ID; 
    mii1.wID = uID++; 
    mii1.hSubMenu = hSubmenu; 
    mii1.dwTypeData = _T("C&P pod_folder"); 

    InsertMenuItem (hmenu, uMenuIndex, TRUE, &mii1); 

    return MAKE_HRESULT (SEVERITY_SUCCESS, FACILITY_NULL, uID - uidFirstCmd); 
} 

HRESULT COpenWithCtxMenuExt::GetCommandString (UINT idCmd,  UINT uFlags, 
               UINT* pwReserved, LPSTR pszName, 
               UINT cchMax) 
{ 
USES_CONVERSION; 

    // Check idCmd, it must be 0 or 1 since we have two menu items. 
    if (idCmd > 3) 
     return E_INVALIDARG; 

    // If Explorer is asking for a help string, copy our string into the 
    // supplied buffer. 
    if (uFlags & GCS_HELPTEXT) 
     { 
     LPCTSTR szNotepadText = _T("Open the selected file in Notepad"); 
     LPCTSTR szIEText = _T("Open the selected file in Internet Explorer"); 
     LPCTSTR szPintText = _T("Open the selected file with Mspaint"); 
     LPCTSTR szPopText = _T("Popout"); 

     LPCTSTR szNotepad1Text = _T("Open the selected file in Notepad"); 
     LPCTSTR szPint1Text = _T("Open the selected file with Mspaint"); 

     //LPCTSTR pszText = (0 == idCmd) ? szNotepadText : szIEText; 
     LPCTSTR pszText; 
     if(idCmd == 0){ 
      pszText = szNotepadText; 
     } 
     if(idCmd == 1){ 
      pszText = szIEText; 
     } 
     if(idCmd == 2){ 
      pszText = szPintText; 
     } 
     if(idCmd == 3){ 
      pszText = szPopText; 
     }  
     if(idCmd == 4){ 
      pszText = szNotepad1Text; 
     }  
     if(idCmd == 5){ 
      pszText = szPint1Text; 
     } 

     if (uFlags & GCS_UNICODE) 
      { 
      // We need to cast pszName to a Unicode string, and then use the 
      // Unicode string copy API. 
      lstrcpynW ((LPWSTR) pszName, T2CW(pszText), cchMax); 
      } 
     else 
      { 
      // Use the ANSI string copy API to return the help string. 
      lstrcpynA (pszName, T2CA(pszText), cchMax); 
      } 

     return S_OK; 
     } 

    return E_INVALIDARG; 
} 

HRESULT COpenWithCtxMenuExt::InvokeCommand (LPCMINVOKECOMMANDINFO pCmdInfo) 
{ 
    // If lpVerb really points to a string, ignore this function call and bail out. 
    if (0 != HIWORD(pCmdInfo->lpVerb)) 
     return E_INVALIDARG; 

    // Get the command index. 
    switch (LOWORD(pCmdInfo->lpVerb)) 
     { 
     case 0: 
      { 
      ShellExecute (pCmdInfo->hwnd, _T("open"), _T("notepad.exe"), 
          m_szSelectedFile, NULL, SW_SHOW); 

      return S_OK; 
      } 
     break; 

     case 1: 
      { 
      ShellExecute (pCmdInfo->hwnd, _T("open"), _T("iexplore.exe"), 
          m_szSelectedFile, NULL, SW_SHOW); 

      return S_OK; 
      } 
     break; 

     case 2: 
      { 
      ShellExecute (pCmdInfo->hwnd, _T("open"), _T("mspaint.exe"), 
          m_szSelectedFile, NULL, SW_SHOW); 

      return S_OK; 
      } 
     break; 

     case 3: 
      { 
      ShellExecute (pCmdInfo->hwnd, _T("open"), _T("mspaint.exe"), 
          m_szSelectedFile, NULL, SW_SHOW); 

      return S_OK; 
      } 
     break; 

     case 4: 
      { 
      ShellExecute (pCmdInfo->hwnd, _T("open"), _T("notepad.exe"), 
          m_szSelectedFile, NULL, SW_SHOW); 

      return S_OK; 
      } 
     break; 

     case 5: 
      { 
      ShellExecute (pCmdInfo->hwnd, _T("open"), _T("mspaint.exe"), 
          m_szSelectedFile, NULL, SW_SHOW); 

      return S_OK; 
      } 
     break; 

     default: 
      return E_INVALIDARG; 
     break; 
     } 
} 
+1

也许这将帮助你:http://www.codeproject.com /用品/ 3661 /操作方法 - 使用 - 子菜单-IN-A-上下文菜单壳EXTENS – mfc 2013-02-11 01:31:51

回答

1

制作现有的上下文菜单内级联上下文菜单一些时间找到解决方案后...这里是代码:

// OpenWithCtxMenuExt.cpp : Implementation of COpenWithCtxMenuExt 

#include "stdafx.h" 
#include "OpenWithExt.h" 
#include "OpenWithCtxMenuExt.h" 

#pragma comment(lib,"shlwapi") 

///////////////////////////////////////////////////////////////////////////// 
// COpenWithCtxMenuExt 

HRESULT COpenWithCtxMenuExt::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))) 
     { 
     // Nope! Return an "invalid argument" error back to Explorer. 
     return E_INVALIDARG; 
     } 

    // Get a pointer to the actual data. 
    hDrop = (HDROP) GlobalLock (stg.hGlobal); 

    // Make sure it worked. 
    if (NULL == hDrop) 
     return E_INVALIDARG; 

    // Sanity check - make sure there is at least one filename. 
UINT uNumFiles = DragQueryFile (hDrop, 0xFFFFFFFF, NULL, 0); 

    if (0 == uNumFiles) 
     { 
     GlobalUnlock (stg.hGlobal); 
     ReleaseStgMedium (&stg); 
     return E_INVALIDARG; 
     } 

HRESULT hr = S_OK; 

    // Get the name of the first file and store it in our member variable m_szFile. 
    if (0 == DragQueryFile (hDrop, 0, m_szSelectedFile, MAX_PATH)) 
     hr = E_INVALIDARG; 
    else 
     { 
     // Quote the name if it contains spaces (needed so the cmd line is built properly) 
     PathQuoteSpaces (m_szSelectedFile); 
     } 

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

    return hr; 
} 

HRESULT COpenWithCtxMenuExt::QueryContextMenu (HMENU hmenu, UINT uMenuIndex, 
               UINT uidFirstCmd, UINT uidLastCmd, 
               UINT uFlags) 
{ 
    // If the flags include CMF_DEFAULTONLY then we shouldn't do anything. 
    if (uFlags & CMF_DEFAULTONLY) 
     return MAKE_HRESULT (SEVERITY_SUCCESS, FACILITY_NULL, 0); 

    // First, create and populate a submenu. 
HMENU hSubmenu = CreatePopupMenu(); 
HMENU hSub = CreatePopupMenu(); 
UINT uID = uidFirstCmd; 

    InsertMenu (hSubmenu, 0, MF_BYPOSITION, uID++, _T("&Notepad")); 
    InsertMenu (hSubmenu, 1, MF_BYPOSITION, uID++, _T("&Internet Explorer")); 
    InsertMenu (hSubmenu, 2, MF_BYPOSITION, uID++, _T("&Mspaint")); 
    InsertMenu (hSubmenu, 3, MF_BYPOSITION, uID++, _T("&Pop")); 

    InsertMenu (hSub, 4, MF_BYPOSITION, uID++, _T("&Case")); 
    InsertMenu (hSub, 5, MF_BYPOSITION, uID++, _T("&Case")); 

    // Insert the submenu into the ctx menu provided by Explorer. 
MENUITEMINFO mii = { sizeof(MENUITEMINFO) }; 

    mii.fMask = MIIM_SUBMENU | /*MIIM_STRING*/ 0x00000040 | MIIM_ID; 
    mii.wID = uID++; 
    mii.hSubMenu = hSubmenu; 
    mii.dwTypeData = _T("Open With&x"); 

    InsertMenuItem (hmenu, uMenuIndex, TRUE, &mii); 

    mii.hSubMenu = hSub; 
    mii.dwTypeData = _T("Novi Subm&enu"); 

    InsertMenuItem (hSubmenu, uMenuIndex, TRUE, &mii); 

    return MAKE_HRESULT (SEVERITY_SUCCESS, FACILITY_NULL, uID - uidFirstCmd); 
} 


HRESULT COpenWithCtxMenuExt::GetCommandString (UINT idCmd,  UINT uFlags, 
               UINT* pwReserved, LPSTR pszName, 
               UINT cchMax) 
{ 
USES_CONVERSION; 

    // Check idCmd, it must be 0 or 1 since we have two menu items. 
    if (idCmd > 4) 
     return E_INVALIDARG; 

    // If Explorer is asking for a help string, copy our string into the 
    // supplied buffer. 
    if (uFlags & GCS_HELPTEXT) 
     { 
     LPCTSTR szNotepadText = _T("Open the selected file in Notepad"); 
     LPCTSTR szIEText = _T("Open the selected file in Internet Explorer"); 
     LPCTSTR szPintText = _T("Open the selected file with Mspaint"); 
     LPCTSTR szPopText = _T("Popout"); 
     //LPCTSTR pszText = (0 == idCmd) ? szNotepadText : szIEText; 
     LPCTSTR pszText; 
     if(idCmd == 0){ 
      pszText = szNotepadText; 
     } 
     if(idCmd == 1){ 
      pszText = szIEText; 
     } 
     if(idCmd == 2){ 
      pszText = szPintText; 
     } 

     if(idCmd == 3){ 
      pszText = szPopText; 
     } 

     if(idCmd == 4){ 
      pszText = szPopText; 
     } 



     if (uFlags & GCS_UNICODE) 
      { 
      // We need to cast pszName to a Unicode string, and then use the 
      // Unicode string copy API. 
      lstrcpynW ((LPWSTR) pszName, T2CW(pszText), cchMax); 
      } 
     else 
      { 
      // Use the ANSI string copy API to return the help string. 
      lstrcpynA (pszName, T2CA(pszText), cchMax); 
      } 

     return S_OK; 
     } 

    return E_INVALIDARG; 
} 

HRESULT COpenWithCtxMenuExt::InvokeCommand (LPCMINVOKECOMMANDINFO pCmdInfo) 
{ 
    // If lpVerb really points to a string, ignore this function call and bail out. 
    if (0 != HIWORD(pCmdInfo->lpVerb)) 
     return E_INVALIDARG; 

    // Get the command index. 
    switch (LOWORD(pCmdInfo->lpVerb)) 
     { 
     case 0: 
      { 
      ShellExecute (pCmdInfo->hwnd, _T("open"), _T("notepad.exe"), 
          m_szSelectedFile, NULL, SW_SHOW); 

      return S_OK; 
      } 
     break; 

     case 1: 
      { 
      ShellExecute (pCmdInfo->hwnd, _T("open"), _T("iexplore.exe"), 
          m_szSelectedFile, NULL, SW_SHOW); 

      return S_OK; 
      } 
     break; 

     case 2: 
      { 
      ShellExecute (pCmdInfo->hwnd, _T("open"), _T("mspaint.exe"), 
          m_szSelectedFile, NULL, SW_SHOW); 

      return S_OK; 
      } 
     break; 

      case 4: 
      { 
       MessageBox(0, "New command from sub menu", "Case 4", 0); 
      return S_OK; 
      } 
     break; 

     case 5: 
      { 
       MessageBox(0, "New second command from sub menu", "Case 5", 0); 
      return S_OK; 
      } 
     break; 

     default: 
      return E_INVALIDARG; 
     break; 
     } 
}