ContextMenu.h
上传用户:hy_wanghao
上传日期:2007-01-08
资源大小:279k
文件大小:8k
源码类别:

Shell编程

开发平台:

Visual C++

  1. #if !defined(AFX_CONTEXTMENU_H__20010107_3BB7_5346_1433_0080AD509054__INCLUDED_)
  2. #define AFX_CONTEXTMENU_H__20010107_3BB7_5346_1433_0080AD509054__INCLUDED_
  3. #pragma once
  4. #include "PropDlg.h"
  5. //////////////////////////////////////////////////////////////////////////////
  6. // CContextMenu
  7. // The IContextMenu implementation for folders in the 
  8. // Explorer's Folder tree.
  9. //
  10. // COM-wise this is not an easy class to manage - mainly because it would
  11. // be much more efficient if we could reuse code in the CView class. But
  12. // we have no way to get to the view.
  13. // Because of this, we only support a limited number of menu commands.
  14. class ATL_NO_VTABLE CContextMenu : 
  15.    public CComObjectRootEx<CComSingleThreadModel>,
  16.    public IContextMenu
  17. {
  18. public:
  19. DECLARE_NOT_AGGREGATABLE(CContextMenu)
  20. DECLARE_PROTECT_FINAL_CONSTRUCT()
  21. BEGIN_COM_MAP(CContextMenu)
  22.    COM_INTERFACE_ENTRY_IID(IID_IContextMenu,IContextMenu)
  23. END_COM_MAP()
  24. // Attributes
  25. public:
  26.    CFolder *m_pFolder;
  27.    HWND m_hWnd;
  28.    CPidl m_pidl;
  29.    typedef enum {
  30.       IDM_OPEN = 0,
  31.       IDM_PROPERTIES,
  32.       IDM_DELETE,
  33.       IDM_LAST
  34.    } MENUITEMS;
  35. // CDropTarget
  36. public:
  37.    HRESULT FinalConstruct()
  38.    {
  39.       m_pFolder = NULL;
  40.       return S_OK;
  41.    }
  42.    void FinalRelease()
  43.    {
  44.       if( m_pFolder!=NULL ) m_pFolder->Release();
  45.    }
  46.    HRESULT _Init(CFolder *pFolder, HWND hWnd, LPCITEMIDLIST pidl)
  47.    {
  48.       ATLASSERT(pFolder);
  49.       m_pFolder = pFolder;
  50.       m_pFolder->AddRef();
  51.       m_pidl.Copy(pidl);
  52.       m_hWnd = hWnd;
  53.       return S_OK;
  54.    }
  55. // IContextMenu
  56. public:
  57.    STDMETHOD(QueryContextMenu)(HMENU hMenu,
  58.                                UINT iIndexMenu,
  59.                                UINT idCmdFirst,
  60.                                UINT idCmdLast,
  61.                                UINT /*uFlags*/)
  62.    {
  63.       ATLTRACE(_T("CContextMenu::QueryContextMenun"));
  64.       ATLASSERT(idCmdLast>idCmdFirst+IDM_LAST);
  65.       CResString<64> sText;
  66.       idCmdLast;
  67.       
  68.       // Open
  69.       sText.LoadString(IDS_OPEN);
  70.       ::InsertMenu(hMenu, iIndexMenu++, MF_STRING | MF_BYPOSITION, idCmdFirst + IDM_OPEN, sText);
  71.       // Delete
  72.       sText.LoadString(IDS_DELETE);
  73.       ::InsertMenu(hMenu, iIndexMenu++, MF_STRING | MF_BYPOSITION, idCmdFirst + IDM_DELETE, sText);
  74.       // -
  75.       ::InsertMenu(hMenu, iIndexMenu++, MF_SEPARATOR | MF_STRING | MF_BYPOSITION, 0, _T(""));
  76.       // Properties
  77.       sText.LoadString(IDS_PROPERTIES);
  78.       ::InsertMenu(hMenu, iIndexMenu++, MF_STRING | MF_BYPOSITION, idCmdFirst + IDM_PROPERTIES, sText);
  79.       
  80.       ::SetMenuDefaultItem(hMenu, 0, TRUE);
  81.       return MAKE_HRESULT(SEVERITY_SUCCESS, 0, IDM_LAST);
  82.    }
  83.    STDMETHOD(InvokeCommand)(LPCMINVOKECOMMANDINFO pcmi)
  84.    {
  85.       ATLTRACE(_T("CContextMenu::InvokeCommandn"));
  86.       ATLASSERT(m_pFolder);
  87.       ATLASSERT(m_pidl);
  88.       USES_CONVERSION;
  89.       // The command is sent via a verb
  90.       if( HIWORD(pcmi->lpVerb) ) {
  91.          LPCMINVOKECOMMANDINFOEX pcmix = NULL;
  92.          if( pcmi->cbSize>=sizeof(CMINVOKECOMMANDINFOEX)-sizeof(POINT) )  pcmix = (LPCMINVOKECOMMANDINFOEX)pcmi;
  93.          LPCSTR pstr = pcmi->lpVerb;
  94.          // If it's an UNICODE string, convert it to ANSI now
  95.          if( (pcmix!=NULL) && 
  96.              ((pcmix->fMask & CMIC_MASK_UNICODE)!=0) && 
  97.              (pcmix->lpVerbW!=NULL) ) {
  98.             pstr = W2CA(pcmix->lpVerbW);
  99.          }
  100.          // Any known string?
  101.          if( strcmp(pstr, "open")==0 ) pcmi->lpVerb = (LPCSTR)IDM_OPEN;
  102.          else if( strcmp(pstr, "properties")==0 ) pcmi->lpVerb = (LPCSTR)IDM_PROPERTIES;
  103.          else if( strcmp(pstr, "delete")==0 ) pcmi->lpVerb = (LPCSTR)IDM_DELETE;
  104.          else return E_INVALIDARG;
  105.       }
  106.       // Check that it's a valid command
  107.       if( LOWORD(pcmi->lpVerb)>IDM_LAST ) return E_INVALIDARG;
  108.       
  109.       // Process our command
  110.       switch( LOWORD(pcmi->lpVerb) ) {
  111.       case IDM_OPEN:
  112.          {
  113.             CPidl pidl;
  114.             pidl.Copy( m_pFolder->m_pidl );
  115.             pidl.Concatenate( m_pFolder->m_pidlPath );
  116.             pidl.Concatenate( m_pidl );
  117.             SHELLEXECUTEINFO sei = { 0 };
  118.             sei.cbSize = sizeof(sei);
  119.             sei.fMask = SEE_MASK_IDLIST | SEE_MASK_CLASSNAME;
  120.             sei.lpIDList = pidl;
  121.             sei.lpClass = TEXT("folder");
  122.             sei.hwnd = pcmi->hwnd;
  123.             sei.nShow = SW_SHOWNORMAL;
  124.             sei.lpVerb = NULL; TEXT("explore");
  125.             BOOL bRes = ::ShellExecuteEx(&sei);
  126.             bRes = bRes;
  127. /*
  128.             CPidl pidl;
  129.             pidl.Copy( m_pFolder->m_pidl );
  130.             pidl.Concatenate( m_pFolder->m_pidlPath );
  131.             SHELLEXECUTEINFO sei = { 0 };
  132.             sei.cbSize = sizeof(sei);
  133.             sei.fMask = SEE_MASK_IDLIST;
  134.             sei.lpIDList = pidl;
  135.             sei.hwnd = pcmi->hwnd;
  136.             sei.nShow = SW_SHOWNORMAL;
  137.             sei.lpVerb = TEXT("explore");
  138.             ::ShellExecuteEx(&sei);
  139. */
  140. /*
  141.             CPidl pidl;
  142.             pidl.Copy( m_pFolder->m_pidl );
  143.             pidl.Concatenate( m_pFolder->m_pidlPath );
  144.             m_pShellBrowser->BrowseObject(pidl, SBSP_DEFBROWSER | SBSP_ABSOLUTE);
  145. */
  146.          }
  147.          break;
  148.       case IDM_PROPERTIES:
  149.          {
  150.             CPropertiesDlg dlg;
  151.             HRESULT Hr;
  152.             HR( dlg._Init(m_pFolder, m_pidl) );
  153.             dlg.DoModal();
  154.             m_pFolder->_SendViewMessage(m_hWnd, WM_COMMAND, ID_VIEW_REFRESH);
  155.          }
  156.          break;
  157.       case IDM_DELETE:
  158.          {
  159.             if( m_pidl==NULL ) return E_INVALIDARG; // Not for ADF file itself      
  160.             // Confirm first, then delete
  161.             LPCITEMIDLIST pidl = m_pidl;
  162.             DWORD dwFlags = 0;
  163.             if( m_pFolder->_ConfirmDelete(&pidl, 1, &dwFlags)==IDYES ) {
  164.                HRESULT Hr;
  165.                HR( m_pFolder->_DeleteFiles(&pidl, 1) );
  166.                m_pFolder->_SendViewMessage(m_hWnd, WM_COMMAND, ID_VIEW_REFRESH);
  167.             }
  168.          }
  169.          break;
  170.       default:
  171.          ::MessageBeep((UINT)-1);
  172.          return E_INVALIDARG;
  173.       }
  174.       return S_OK;
  175.    }
  176.    STDMETHOD(GetCommandString)(UINT idCmd, UINT uFlags, LPUINT, LPSTR pszName, UINT cchMax)
  177.    {
  178.       ATLTRACE(_T("CContextMenu::GetCommandStringn"));
  179.       HRESULT hr = E_NOTIMPL;
  180.       switch( uFlags ) {
  181.       case GCS_VERBA:
  182.       case GCS_VERBW:         
  183.          {
  184.             LPCSTR pstr;
  185.             if( idCmd==IDM_OPEN ) pstr="open";
  186.             else if( idCmd==IDM_DELETE ) pstr="delete";
  187.             else if( idCmd==IDM_PROPERTIES ) pstr="properties";
  188.             else return E_INVALIDARG;
  189.             ATLASSERT(strlen(pstr)*sizeof(WCHAR)<=cchMax);
  190.             USES_CONVERSION;
  191.             if( uFlags & GCS_UNICODE ) wcscpy((LPWSTR)pszName, A2CW(pstr)); else strcpy(pszName, pstr);
  192.             return NOERROR;
  193.          }
  194.          break;
  195.       case GCS_HELPTEXTA:
  196.       case GCS_HELPTEXTW:
  197.          {
  198.             UINT idRes = (UINT)-1;
  199.             switch( idCmd ) {
  200.             case IDM_OPEN: idRes = ID_FILE_OPEN; break;
  201.             case IDM_DELETE: idRes = ID_EDIT_DELETE; break;
  202.             case IDM_PROPERTIES: idRes = ID_EDIT_PROPERTIES; break;
  203.             }
  204.             if( idRes==-1 ) return E_FAIL;
  205.             if( uFlags==GCS_HELPTEXTA ) {
  206.                ::LoadStringA(_Module.GetResourceInstance(), idRes, pszName, cchMax);
  207.             }
  208.             else {
  209.                // BUG: ::LoadStringW() fails on Win95
  210.                ::LoadStringW(_Module.GetResourceInstance(), idRes, (LPWSTR)pszName, cchMax);
  211.             }            
  212.             return NOERROR;
  213.          }
  214.          break;      
  215.       case GCS_VALIDATE:
  216.          hr = NOERROR;
  217.          break;      
  218.       }
  219.       return hr;
  220.    }
  221. };
  222. #endif // !defined(AFX_CONTEXTMENU_H__20010107_3BB7_5346_1433_0080AD509054__INCLUDED_)