⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 atlshellext.h

📁 remote debug and compile tools
💻 H
📖 第 1 页 / 共 4 页
字号:
      ATLTRACENOTIMPL(_T("IShellPropSheetExt::ReplacePage"));
   }

   // IShellExtInit

   STDMETHOD(Initialize)(LPCITEMIDLIST /*pidlFolder*/, IDataObject *lpDataObject, HKEY /*hkeyProgID*/) 
   {
      ATLASSERT(lpDataObject);
      STGMEDIUM medium;
      FORMATETC fe = {CF_HDROP, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
      if( SUCCEEDED(lpDataObject->GetData(&fe, &medium)) ) {
         // Get the file name from the CF_HDROP.
         UINT uCount = ::DragQueryFile((HDROP)medium.hGlobal, (UINT)-1, NULL, 0);
         if(uCount>0) ::DragQueryFile((HDROP)medium.hGlobal, 0, m_szFileName, sizeof(m_szFileName)/sizeof(TCHAR));
         ::ReleaseStgMedium(&medium);
      }
      return S_OK;
   }

   // Callbacks

   static UINT CALLBACK PropSheetPageProc(HWND /*hwnd*/, UINT uMsg, LPPROPSHEETPAGE ppsp)
   {
      switch( uMsg ) {
      case PSPCB_CREATE:
         return 1; // Allow dialog creation
      case PSPCB_RELEASE:
         T *pT = (T *)ppsp->lParam;
         ATLASSERT(pT);
         pT->Release();
         break;
      }
      return 0;
   }

   void SetModified(BOOL bChanged=TRUE)
   {
      ATLASSERT(::IsWindow(m_hWnd));
      ATLASSERT(GetParent()!=NULL);
      ::SendMessage(GetParent(), bChanged ? PSM_CHANGED : PSM_UNCHANGED, (WPARAM)m_hWnd, 0L);
   }

   static int CALLBACK PageDlgProc(HWND hWnd, UINT uMessage, WPARAM wParam, LPARAM lParam)
   {    
      T *pT = (T *)::GetWindowLong(hWnd, GWL_USERDATA);
      LRESULT lRes = 0;
      if( uMessage==WM_INITDIALOG ) {
         pT = (T *)((LPPROPSHEETPAGE)lParam)->lParam;
         ::SetWindowLong(hWnd, GWL_USERDATA, (LONG)pT);
         // Set the window handle
         pT->m_hWnd = hWnd;
         lRes = 1;
      }
      if( pT==NULL ) {
         // The first message is WM_SETFONT, not WM_INITDIALOG...
         return FALSE;
      }
      MSG msg = { pT->m_hWnd, uMessage, wParam, lParam, 0, { 0, 0 } };
      const MSG *pOldMsg = pT->m_pCurrentMsg;
      pT->m_pCurrentMsg = &msg;
      // pass to the message map to process
      BOOL bRet = pT->ProcessWindowMessage(pT->m_hWnd, uMessage, wParam, lParam, lRes, 0);
      // restore saved value for the current message
      ATLASSERT(pT->m_pCurrentMsg == &msg);
      pT->m_pCurrentMsg = pOldMsg;
      // set result if message was handled
      if(bRet) {
         switch (uMessage) {
         case WM_COMPAREITEM:
         case WM_VKEYTOITEM:
         case WM_CHARTOITEM:
         case WM_INITDIALOG:
         case WM_QUERYDRAGICON:
         case WM_CTLCOLORMSGBOX:
         case WM_CTLCOLOREDIT:
         case WM_CTLCOLORLISTBOX:
         case WM_CTLCOLORBTN:
         case WM_CTLCOLORDLG:
         case WM_CTLCOLORSCROLLBAR:
         case WM_CTLCOLORSTATIC:
            return lRes;
         }
         ::SetWindowLong(pT->m_hWnd, DWL_MSGRESULT, lRes);
         return TRUE;
      }
      if( uMessage==WM_NCDESTROY ) {
         // clear out window handle
         pT->m_hWnd = NULL;
      }
      return FALSE;
   }
};


//////////////////////////////////////////////////////////////////////////////
// CExtractFileIcon

template< class T >
class ATL_NO_VTABLE CExtractFileIcon : 
   public CComObjectRootEx<CComSingleThreadModel>,
   public IExtractIcon
{
public:

BEGIN_COM_MAP(CExtractFileIcon)
   COM_INTERFACE_ENTRY_IID(IID_IExtractIcon,IExtractIcon)
END_COM_MAP()

public:
   CPidl m_pidl;

public:
   void Init(LPCITEMIDLIST pidl)
   {
      m_pidl.Copy(pidl);
   }

   // IExtractIcon

   STDMETHOD(GetIconLocation)(UINT uFlags, 
                              LPTSTR /*szIconFile*/, 
                              UINT /*cchMax*/, 
                              LPINT piIndex, 
                              LPUINT puFlags)
   {
      ATLASSERT(piIndex);
      ATLASSERT(puFlags);
      if( m_pidl.IsEmpty() ) return E_FAIL;
      LPCITEMIDLIST pidlLast = CPidl::PidlGetLastItem(m_pidl);
      T* pData = (T*) pidlLast;
      if( pData!=NULL ) {
         switch( pData->type ) {
         case 0:
            *piIndex = 0;
            *puFlags = GIL_NOTFILENAME;
            break;
         case 1:
            *piIndex = 1;
            *puFlags = GIL_NOTFILENAME;
            break;
         default:
            *piIndex = 0;
            *puFlags = GIL_SIMULATEDOC;
            break;
         }
      }
      return S_OK;
   }

   STDMETHOD(Extract)(LPCTSTR pszFile, 
                      UINT nIconIndex, 
                      HICON *phiconLarge, 
                      HICON *phiconSmall, 
                      UINT nIconSize)
   {
      ATLASSERT(phiconLarge);
      ATLASSERT(phiconSmall);
      if( m_pidl.IsEmpty() ) return E_FAIL;
      LPCITEMIDLIST pidlLast = CPidl::PidlGetLastItem(m_pidl);
      T *pData = (T *)pidlLast;
      if( pData!=NULL ) {
         switch( pData->type ) {
         case 0:
            {
               *phiconLarge = ImageList_GetIcon(_Module.m_ImageLists.m_hImageListLarge, 0, ILD_TRANSPARENT);
               *phiconSmall = ImageList_GetIcon(_Module.m_ImageLists.m_hImageListSmall, 0, ILD_TRANSPARENT);
            }
            break;
         case 1:
            {
               *phiconLarge = ImageList_GetIcon(_Module.m_ImageLists.m_hImageListLarge, 1, ILD_TRANSPARENT);
               *phiconSmall = ImageList_GetIcon(_Module.m_ImageLists.m_hImageListSmall, 1, ILD_TRANSPARENT);
            }
            break;
         case 2:
            {
               TCHAR szPath[MAX_PATH];
               TCHAR szExt[MAX_PATH];
               ::lstrcpy( szPath, pData->ffd.cFileName );
               LPTSTR psz = _tcsrchr(szPath, _T('.'));
               szExt[0] = _T('\0');
               if( psz!=NULL ) ::lstrcpy(szExt, psz);
               SHFILEINFO sfi = { 0 };
               HIMAGELIST hImageListLarge = (HIMAGELIST) ::SHGetFileInfo(szExt, 
                                             FILE_ATTRIBUTE_NORMAL,
                                             &sfi, sizeof(sfi), 
                                             SHGFI_USEFILEATTRIBUTES|SHGFI_ICON|SHGFI_SYSICONINDEX);
               if (hImageListLarge) *phiconLarge = ImageList_GetIcon(hImageListLarge, sfi.iIcon, ILD_TRANSPARENT);
               HIMAGELIST hImageListSmall = (HIMAGELIST) ::SHGetFileInfo(szExt, 
                                             FILE_ATTRIBUTE_NORMAL,
                                             &sfi, sizeof(sfi), 
                                             SHGFI_USEFILEATTRIBUTES|SHGFI_ICON|SHGFI_SMALLICON|SHGFI_SYSICONINDEX);
               if (hImageListSmall) *phiconSmall = ImageList_GetIcon(hImageListSmall, sfi.iIcon, ILD_TRANSPARENT);
            }
            break;
         }
      }
      return S_OK;
   }

};


//////////////////////////////////////////////////////////////////////////////
// CContextMenuImpl

template <class T>
struct _ATL_CTXMENU_ENTRY
{
  UINT id;
  UINT desc;
  void (__stdcall T::*pfn)(); // method to invoke
};

#define BEGIN_CONTEXTMENU_MAP(theClass) \
   static const _ATL_CTXMENU_ENTRY<theClass>* _GetCtxMap()\
   {\
      typedef theClass _atl_event_classtype;\
      static const _ATL_CTXMENU_ENTRY<_atl_event_classtype> _ctxmap[] = {

#define CONTEXTMENU_HANDLER(id, desc, func) \
    {id, desc, (void (__stdcall _atl_event_classtype::*)())func},\

#define END_CONTEXTMENU_MAP() {0,0,NULL}}; return _ctxmap;}


template <class T>
class ATL_NO_VTABLE CShellContextMenu : 
   public IContextMenu,
   public IShellExtInit
{
public:
   CRegKey m_regClass;
   CSimpleArray<CComBSTR> m_arrFiles;

// IShellExtInit
public:
   STDMETHOD(Initialize)(LPCITEMIDLIST pidlFolder,
                         IDataObject *lpDataObj, 
                         HKEY hkeyProgID)
   {
      ATLTRACE(_T("CShellContextMenu::Initialize\n"));
      // Get file class
      m_regClass.Open(hkeyProgID,NULL);
      // Get files
      if( lpDataObj ) {
         CComPtr<IDataObject> spDataObj(lpDataObj);
         STGMEDIUM medium;
         FORMATETC fe = { CF_HDROP, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
         if( SUCCEEDED(spDataObj->GetData(&fe, &medium)) ) {
            // Get the filenames from the CF_HDROP.
            UINT uCount = ::DragQueryFile((HDROP)medium.hGlobal, (UINT)-1, NULL, 0);
            for( UINT i=0; i<uCount; i++ ) {
               TCHAR szFileName[MAX_PATH];    
               ::DragQueryFile((HDROP)medium.hGlobal, i, szFileName, sizeof(szFileName)/sizeof(TCHAR));
               m_arrFiles.Add(CComBSTR(szFileName));
            }
            ::ReleaseStgMedium(&medium);
         }
      }    
      return S_OK;
    }

// IContextMenu
public:
   STDMETHOD(QueryContextMenu)(HMENU hMenu,
                               UINT iIndexMenu,
                               UINT idCmdFirst,
                               UINT idCmdLast,
                               UINT uFlags)
   {
      ATLTRACE(_T("CShellContextMenu::QueryContextMenu\n"));
      const _ATL_CTXMENU_ENTRY<T>* pMap = T::_GetCtxMap();
      UINT i=0;
      while( pMap->pfn!=NULL ) {  
        if( pMap->id==0 ) {
          ::InsertMenu(hMenu, iIndexMenu++, MF_SEPARATOR | MF_STRING | MF_BYPOSITION, 0, _T(""));
        }
        else {
          TCHAR szText[128];
          ::LoadString(_Module.GetResourceInstance(), pMap->id, szText, sizeof(szText)/sizeof(TCHAR));
          ::InsertMenu(hMenu, iIndexMenu++, MF_STRING | MF_BYPOSITION, idCmdFirst + i, szText);
        }
        i++;
        pMap++;
      }
      T *pT = static_cast<T*>(this);
      pT->UpdateMenu(hMenu, idCmdFirst);
      return MAKE_HRESULT(SEVERITY_SUCCESS, 0, i + 1);
   }

   STDMETHOD(InvokeCommand)(LPCMINVOKECOMMANDINFO lpcmi)
   {
      ATLTRACE(_T("CShellContextMenu::InvokeCommand\n"));
      if( HIWORD(lpcmi->lpVerb) ) return NOERROR; // The command is being sent via a verb
      UINT idxCmd = LOWORD(lpcmi->lpVerb);
      const _ATL_CTXMENU_ENTRY<T>* pMap = T::_GetCtxMap();
      UINT i=0;
      while( pMap->pfn!=NULL ) {
         if( i==idxCmd ) {
            T *pT = static_cast<T*>(this);
            CComStdCallThunk<T> thunk;
            thunk.Init(pMap->pfn, pT);
            VARIANT vRes;
            ::VariantInit(&vRes);
            return DispCallFunc(
               &thunk,
               0,
               CC_STDCALL,
               VT_EMPTY, // this is how DispCallFunc() represents void
               0,
               NULL,
               NULL,
               &vRes);
         }
         pMap++;
         i++;
      }
      return E_INVALIDARG;
   }

   STDMETHOD(GetCommandString)(UINT idCmd, UINT uFlags, LPUINT, LPSTR pszName, UINT cchMax)
   {
      ATLTRACE(_T("CContextMenu::GetCommandString\n"));
      switch( uFlags ) {
      case GCS_HELPTEXTA:
      case GCS_HELPTEXTW:
         {
            const _ATL_CTXMENU_ENTRY<T>* pMap = T::_GetCtxMap();
            UINT i=0;
            while( pMap->pfn!=NULL ) {
              if( i==idCmd ) {
                if( uFlags==GCS_HELPTEXTA ) {
                   ::LoadStringA(_Module.GetResourceInstance(), pMap->desc, pszName, cchMax);
                }
                else {
                   // BUG: LoadStringW() is not supported on Win95
                   ::LoadStringW(_Module.GetResourceInstance(), pMap->desc, (LPWSTR)pszName, cchMax);
                } 
                return S_OK;
              }
              pMap++;
              i++;
            }
         }
         return E_FAIL;
      case GCS_VERBA:
      case GCS_VERBW:
         return E_FAIL;
      case GCS_VALIDATE:
         return NOERROR;
      default:
         return E_NOTIMPL;
      }
   }

   void UpdateMenu(HMENU hMenu, UINT iCmdFirst) { };

};

#endif // __ATLCOM_H__


//////////////////////////////////////////////////////////////////////////////
// ::SHGetPathFromIDList() wrapper

class CShellPidlPath
{
public:
   CShellPidlPath(LPCITEMIDLIST pidl)
   {
      ATLASSERT(pidl);     
      if( ::SHGetPathFromIDList(pidl, m_szPath)==FALSE ) m_szPath[0]=_T('\0');
   }
   operator LPCTSTR() const { return m_szPath; };
   TCHAR m_szPath[MAX_PATH];
};


//////////////////////////////////////////////////////////////////////////////
// Shell Helper Functions

inline LPITEMIDLIST ShellGetFileNamePidl(LPOLESTR pstrFileName)
{
   LPSHELLFOLDER pDesktopFolder;
   if( FAILED(::SHGetDesktopFolder(&pDesktopFolder)) ) return NULL;
   LPITEMIDLIST pidl;
   ULONG dwEaten;
   ULONG dwAttribs;
   if( FAILED( pDesktopFolder->ParseDisplayName(NULL, NULL, pstrFileName, &dwEaten, &pidl, &dwAttribs) ) ) {
      pidl = NULL;
   }
   pDesktopFolder->Release();
   return pidl; 
}

#endif // __ATLSHELLEXT_H__

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -