示例#1
0
/**
 * Install a shortcut for the virtual folder in the Windows Start Menu.
 * This method knows when we're installing under WOW64 so creating a shortcut will allow
 * the user to access the virtual folder, even when using a 32bit DLL under 64bit Windows.
 */
HRESULT UpdateStartMenuLink(LPCWSTR pstrDisplayName, LPCWSTR pstrDescription, KNOWNFOLDERID FolderId, BOOL bRegister)
{
   HRESULT Hr = S_OK;
   // Get folder for installation...
   CPidl pidlFolderPath;
   CCoTaskString strFolderPath;
   HR( pidlFolderPath.CreateFromKnownFolder(FolderId) );
   HR( pidlFolderPath.GetName(SIGDN_DESKTOPABSOLUTEPARSING, &strFolderPath) );
   // Create shortcut link...
   CComPtr<IShellLink> spLink;
   HR( spLink.CoCreateInstance(CLSID_ShellLink) );
   BOOL bIsWOW64 = FALSE; ::IsWow64Process(::GetCurrentProcess(), &bIsWOW64);
   CComBSTR bstrPath = bIsWOW64 ? L"%windir%\\syswow64\\explorer.exe" : L"%windir%\\explorer.exe";
   CComBSTR bstrIcon = bIsWOW64 ? L"%windir%\\syswow64\\shell32.dll" : L"%SystemRoot%\\system32\\shell32.dll";
   int iIconIndex = _ShellModule.GetConfigBool(VFS_HAVE_VIRTUAL_FILES) ? SIID_DRIVEFIXED : SIID_FOLDER;
   WCHAR wszArgs[MAX_PATH + 80] = { 0 };
   ::wnsprintf(wszArgs, lengthof(wszArgs) - 1, L"/separate,%s%s%s::%s", bIsWOW64 ? L"/select," : L"", static_cast<LPCWSTR>(strFolderPath), strFolderPath.IsEmpty() ? L"" : L"\\", static_cast<LPCWSTR>(CComBSTR(CLSID_ShellFolder)));
   spLink->SetPath(bstrPath);
   spLink->SetArguments(wszArgs);
   spLink->SetIconLocation(bstrIcon, iIconIndex);
   spLink->SetDescription(pstrDescription);
   // Write the link file to the Windows Start Menu...
   CComQIPtr<IPersistFile> spPersist = spLink;
   if( spPersist == NULL ) return E_UNEXPECTED;
   CCoTaskString strLinkPath;
   HR( ::SHGetKnownFolderPath(FOLDERID_StartMenu, 0, NULL, &strLinkPath) );
   WCHAR wszLinkFilename[MAX_PATH] = { 0 };
   ::wnsprintf(wszLinkFilename, lengthof(wszLinkFilename) - 1, L"%s\\%s.lnk", static_cast<LPCWSTR>(strLinkPath), pstrDisplayName);
   if( bRegister ) Hr = spPersist->Save(wszLinkFilename, TRUE);
   else ::DeleteFileW(wszLinkFilename);
   return Hr;
}
示例#2
0
    void OnItemExpanding(EShellTreeItem& tItem)
    {
        //LPNMTREEVIEW pnmtv = (LPNMTREEVIEW) pnmh;

#ifdef __ATLCTRLX_H__
        CWaitCursor cursor;
#endif

        // 展开过就去掉“没展开”属性
        tItem.remove_attribute("not-expand-ever");
        // 删掉占位的那个项目
        EShellTreeItem tiFake = tItem.find_first("option");
        if (tiFake.is_valid())
        {
            tiFake.destroy();
        }

        // 遍历目录下的子文件夹
        PSHELLITEMINFO pFolderItem = reinterpret_cast<PSHELLITEMINFO>(tItem.GetData());
        CComPtr<IShellFolder> spFolder;
        if( pFolderItem->pidlNode != NULL ) 
        {
            if( FAILED(pFolderItem->spFolder->BindToObject(pFolderItem->pidlNode,
                NULL, IID_IShellFolder, (LPVOID*)&spFolder)) ) 
                return ;
        }
        else 
        {
            spFolder = pFolderItem->spFolder;
        }

        // Add children
        CComPtr<IEnumIDList> spEnum;
        DWORD dwEnumFlags = SHCONTF_FOLDERS;
        if( (m_dwShellStyle & SCT_EX_SHOWHIDDEN) != 0 ) 
            dwEnumFlags |= SHCONTF_INCLUDEHIDDEN;
        if( SUCCEEDED(spFolder->EnumObjects(NULL, dwEnumFlags, &spEnum)) ) 
        {
            CPidl pidl;
            DWORD  dwFetched;
            while( (spEnum->Next(1, &pidl, &dwFetched) == S_OK) && (dwFetched > 0) ) 
            {
                // Get attributes and filter some items
                DWORD dwAttribs = SFGAO_DISPLAYATTRMASK | SFGAO_HASSUBFOLDER;
                if( !_FilterItem(spFolder, pidl, dwAttribs) ) 
                {
                    _InsertItem(spFolder, pFolderItem->pidlFull, pidl, dwAttribs, tItem);
                }
                pidl.Delete();
            }
        }
    }
示例#3
0
/**
 * Serialize data to a SHITEMID item.
 * This is a helper function designed to ease the process of serializing internal
 * item structures to a Simple PIDL structure.
 */
PCITEMID_CHILD CNseBaseItem::GenerateITEMID(LPVOID pData, SIZE_T cbData)
{
   // NOTE: This method assumes that pData points to a structure
   //       which derives (or has same layout) as the SHITEMID
   //       structure (= a basic PIDL).
   // TODO: Type-safety?
   ATLASSERT(pData);
   ATLASSERT(cbData>=sizeof(SHITEMID));
   LPSHITEMID pSHID = reinterpret_cast<LPSHITEMID>(pData);
   pSHID->cb = (USHORT) cbData;
   CPidl pidl;
   pidl.Create(pSHID);
   return (PCITEMID_CHILD) pidl.Detach();
}
示例#4
0
/**
 * Show file properties.
 * Launches the default File Properties window for the selected item.
 * This method can only handle 1 item and will only show properties
 * for the first item in the passed selection.
 */
HRESULT CNseBaseItem::_DoShowProperties(VFS_MENUCOMMAND& Cmd)
{
   // Get first item or view from selection
   CComPtr<IShellItem> spItem;
   if( Cmd.pShellItems != NULL ) Cmd.pShellItems->GetItemAt(0, &spItem);
   else ::SHCreateItemFromIDList(m_pFolder->m_pidlMonitor, IID_PPV_ARGS(&spItem));
   if( spItem == NULL ) return E_FAIL;
   CPidl pidl;
   HR( pidl.CreateFromObject(spItem) );
   // Show properties for this item
   SHELLEXECUTEINFO sei = { 0 };
   sei.cbSize = sizeof(sei);
   sei.hwnd = Cmd.hWnd;
   sei.fMask = SEE_MASK_INVOKEIDLIST;
   sei.lpVerb = _T("properties");
   sei.lpIDList = pidl;
   sei.nShow = SW_SHOW;
   ::ShellExecuteEx(&sei);
   // We handled this operation successfully for all items in selection
   return NSE_S_ALL_DONE;
}
示例#5
0
inline BOOL AtlGetShellPidl(LPCITEMIDLIST pidl, IShellFolder** ppFolder, LPITEMIDLIST* pidlRel)
{
    ATLASSERT(pidl);
    ATLASSERT(ppFolder);
    ATLASSERT(pidlRel);

    *ppFolder = NULL;
    *pidlRel = NULL;

    // Get the desktop folder as a starting point
    CComPtr<IShellFolder> spFolder;
    if( FAILED( ::SHGetDesktopFolder(&spFolder) ) ) return FALSE;

    CPidl pidlMain;
    pidlMain.Copy(pidl);

    // Traverse each PIDL item and create a new IShellFolder for each of
    // them. Eventually we get to the last IShellFolder object and is left
    // with a simple (as opposed to complex) PIDL.
    int nCount = pidlMain.GetCount();
    while( --nCount > 0 ) {
        // Get the next PIDL entry
        CPidl pidlNext;
        pidlNext.Attach( pidlMain.CopyFirstItem() );
        if( pidlNext.IsEmpty() ) return FALSE;
        // Bind to the folder specified in the new item ID list.
        CComPtr<IShellFolder> spNextFolder;
        if( FAILED( spFolder->BindToObject(pidlNext, NULL, IID_IShellFolder, (LPVOID*) &spNextFolder)) ) return FALSE;
        spFolder = spNextFolder;
        // Strip first PIDL entry and copy remaining
        CPidl temp;
        temp.Copy( pidlMain.GetNextItem() );
        pidlMain.Attach(temp.Detach());
    }

    *ppFolder = spFolder.Detach();
    *pidlRel = pidlMain.Detach();
    return TRUE;
};
示例#6
0
HRESULT CDataObject::_CollectFiles(IShellFolder* pShellFolder, PCIDLIST_RELATIVE pidlFolder, LPCWSTR pstrFolder, CPidl& pidls)
{
   ATLASSERT(pShellFolder);
   UINT nCount = pidls.GetItemCount();
   for( UINT i = 0; i < nCount; i++ ) 
   {
      CPidl pidlItem = pidls.GetItem(i);

      WIN32_FIND_DATA wfd = { 0 };
      HRESULT Hr = ::SHGetDataFromIDList(pShellFolder, pidlItem.GetItem(0), SHGDFIL_FINDDATA, &wfd, sizeof(wfd));
      if( FAILED(Hr) ) return Hr;

      FILEDESCRIPTOR fd = { 0 };
      fd.dwFlags = (DWORD)(FD_FILESIZE | FD_ATTRIBUTES | FD_UNICODE);
      if( _ShellModule.GetConfigBool(VFS_CAN_PROGRESSUI) ) fd.dwFlags |= FD_PROGRESSUI;
      wcscpy_s(fd.cFileName, lengthof(fd.cFileName), pstrFolder);
      wcscat_s(fd.cFileName, lengthof(fd.cFileName), wfd.cFileName);
      fd.nFileSizeLow = wfd.nFileSizeLow;
      if( IsFileTimeValid(wfd.ftCreationTime) ) fd.ftCreationTime = wfd.ftCreationTime, fd.dwFlags |= FD_CREATETIME;
      if( IsFileTimeValid(wfd.ftLastWriteTime) ) fd.ftLastWriteTime = wfd.ftLastWriteTime, fd.dwFlags |= FD_WRITESTIME;
      if( IsFileTimeValid(wfd.ftLastAccessTime) ) fd.ftLastAccessTime = wfd.ftLastAccessTime, fd.dwFlags |= FD_ACCESSTIME;
      fd.dwFileAttributes = wfd.dwFileAttributes;

      // Setup item info into <sizel>
      NSEFILEPIDLDATA * pNseInfo = (NSEFILEPIDLDATA *)pidlItem.GetItem(0);
      if (pNseInfo && pNseInfo->magic == TARFILE_MAGIC_ID && pNseInfo->cb == sizeof(NSEFILEPIDLDATA)){
            fd.sizel.cx = pNseInfo->wfd.dwId.category; fd.sizel.cy = pNseInfo->wfd.dwId.id;
      }      

	  // Setup parent info into <pointl>
      if (m_spFolder && m_spFolder->m_spFolderItem){
            VFS_FIND_DATA vfd = m_spFolder->m_spFolderItem->GetFindData();
            fd.pointl.x = vfd.dwId.category; fd.pointl.y = vfd.dwId.id;
      }      

      if( !m_aFiles.Add(fd) ) return E_OUTOFMEMORY;

      // Recurse into sub-folders...
      // HarryWu, 2014.7.21
      // it is high-cost and terrible, and not need for non-http mode.
      if( FALSE && IsBitSet(wfd.dwFileAttributes, FILE_ATTRIBUTE_DIRECTORY) )
      {
         CComPtr<IShellFolder> spSubFolder;
         HR( pShellFolder->BindToObject(pidlItem, NULL, IID_PPV_ARGS(&spSubFolder)) );
         CComPtr<IEnumIDList> spEnum;
         HR( spSubFolder->EnumObjects(m_hwndOwner, SHCONTF_FOLDERS | SHCONTF_NONFOLDERS | SHCONTF_STORAGE, &spEnum) );
         ULONG uFetched = 0;
         CPidl pidlSubItems;
         PITEMID_CHILD pidlChild = NULL;
         while( spEnum->Next(1, &pidlChild, &uFetched), uFetched > 0 ) {
            pidlSubItems.Append(pidlChild);
            ::CoTaskMemFree(pidlChild);
            uFetched = 0;
         }
         WCHAR wszSubFolder[MAX_PATH] = { 0 };
         ::wnsprintf(wszSubFolder, lengthof(wszSubFolder) - 1, L"%s%s\\", pstrFolder, wfd.cFileName);
         CPidl pidlSubFolder = pidlFolder + pidlItem;
         HR( _CollectFiles(spSubFolder, pidlSubFolder, wszSubFolder, pidlSubItems) );
      }
   }
   return S_OK;
}