例子:
STDMETHODIMP CShellExt::Initialize(LPCITEMIDLIST pIDFolder,
                                   LPDATAOBJECT pDataObj,
                                   HKEY hRegKey)
{   AFX_MANAGE_STATE(AfxGetStaticModuleState( ));   ODS("CShellExtFld::Initialize()\r\n");   // this can be called more than once
   if (m_pDataObj)
   m_pDataObj->Release();   // duplicate the object pointer and registry handle
   if (pDataObj)
   {
   m_pDataObj = pDataObj;
   pDataObj->AddRef();
   } 
   else
   {
   return E_FAIL;
   }   return GetSelectedFiles(pIDFolder, m_pDataObj, m_csaPaths);
}
STDMETHODIMP GetSelectedFiles(LPCITEMIDLIST pIDFolder,
                                   LPDATAOBJECT &pDataObj,
                                   CStringArray &csaPaths)
{
   // get these paths into a CStringArray
   csaPaths.RemoveAll();   // fetch all of the file names we're supposed to operate on
   if (pDataObj) 
   {
   pDataObj->AddRef();    STGMEDIUM medium;
   FORMATETC fe = { CF_HDROP, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
   HRESULT hr = pDataObj->GetData (&fe, &medium);
   if (FAILED (hr))
   {
   return E_FAIL;
   }    // buffer to receive filenames
   char path[MAX_PATH];    // how many are there?
   UINT fileCount = DragQueryFile((HDROP)medium.hGlobal, 0xFFFFFFFF,
   path, MAX_PATH);    if (fileCount>0)
   {
   // avoid wasting mem when this thing gets filled in
   csaPaths.SetSize(fileCount);    // stash the paths in our CStringArray
   for (UINT i=0;i<fileCount;i++) 
         {
   // clear old path
   memset(path, 0, MAX_PATH);
   // fetch new path
   if (DragQueryFile((HDROP)medium.hGlobal, i, path, MAX_PATH)) 
            {
           csaPaths.SetAt(i, path);
      }
      }         csaPaths.FreeExtra();
      }      // free our path memory - we have the info in our CStringArray
      ReleaseStgMedium(&medium);
   }   return NOERROR;
}m_csaPaths array may contain both files and folders.