Ejemplo n.º 1
1
bool CDeskBand::FindPaths()
{
    m_currentDirectory.clear();
    m_selectedItems.clear();
    m_bFilesSelected = false;
    m_bFolderSelected = false;

    if (m_pSite == NULL)
        return false;
    IServiceProvider * pServiceProvider;
    if (SUCCEEDED(m_pSite->QueryInterface(IID_IServiceProvider, (LPVOID*)&pServiceProvider)))
    {
        IShellBrowser * pShellBrowser;
        if (SUCCEEDED(pServiceProvider->QueryService(SID_SShellBrowser, IID_IShellBrowser, (LPVOID*)&pShellBrowser)))
        {
            IShellView * pShellView;
            if (SUCCEEDED(pShellBrowser->QueryActiveShellView(&pShellView)))
            {
                IFolderView * pFolderView;
                if (SUCCEEDED(pShellView->QueryInterface(IID_IFolderView, (LPVOID*)&pFolderView)))
                {
                    // hooray! we got the IFolderView interface!
                    // that means the explorer is active and well :)

                    // but we also need the IShellFolder interface because
                    // we need its GetCurFolder() method
                    IPersistFolder2 * pPersistFolder;
                    if (SUCCEEDED(pFolderView->GetFolder(IID_IPersistFolder2, (LPVOID*)&pPersistFolder)))
                    {
                        LPITEMIDLIST folderpidl;
                        if (SUCCEEDED(pPersistFolder->GetCurFolder(&folderpidl)))
                        {
                            // we have the current folder
                            TCHAR buf[MAX_PATH] = {0};
                            // find the path of the folder
                            if (SHGetPathFromIDList(folderpidl, buf))
                            {
                                m_currentDirectory = buf;
                            }
                            // if m_currentDirectory is empty here, that means
                            // the current directory is a virtual path

                            IShellFolder * pShellFolder;
                            if (SUCCEEDED(pPersistFolder->QueryInterface(IID_IShellFolder, (LPVOID*)&pShellFolder)))
                            {
                                // if there was a new folder created but not found to set into editing mode,
                                // we try here to do that
                                if (!m_newfolderPidls.empty())
                                {
                                    int nCount2 = 0;
                                    IShellFolder * pShellFolder;
                                    if (SUCCEEDED(pPersistFolder->QueryInterface(IID_IShellFolder, (LPVOID*)&pShellFolder)))
                                    {
                                        if (SUCCEEDED(pFolderView->ItemCount(SVGIO_ALLVIEW, &nCount2)))
                                        {
                                            for (int i=0; i<nCount2; ++i)
                                            {
                                                LPITEMIDLIST pidl;
                                                pFolderView->Item(i, &pidl);
                                                bool bFound = false;
                                                for (std::vector<LPITEMIDLIST>::iterator it = m_newfolderPidls.begin(); it != m_newfolderPidls.end(); ++it)
                                                {
                                                    HRESULT hr = pShellFolder->CompareIDs(0, pidl, *it);
                                                    if (HRESULT_CODE(hr) == 0)
                                                    {
                                                        // this item was there before, so it's not the new folder
                                                        CoTaskMemFree(*it);
                                                        m_newfolderPidls.erase(it);
                                                        bFound = true;
                                                        break;
                                                    }
                                                }
                                                if (!bFound)
                                                {
                                                    pShellView->SelectItem(pidl, SVSI_EDIT);
                                                }
                                                CoTaskMemFree(pidl);
                                            }
                                        }
                                        if ((nCount2)||(m_newfolderTimeoutCounter-- <= 0))
                                        {
                                            m_newfolderTimeoutCounter = 0;
                                            for (std::vector<LPITEMIDLIST>::iterator it = m_newfolderPidls.begin(); it != m_newfolderPidls.end(); ++it)
                                            {
                                                CoTaskMemFree(*it);
                                            }
                                            m_newfolderPidls.clear();
                                        }
                                        pShellFolder->Release();
                                    }

                                }
                                // find all selected items
                                IEnumIDList * pEnum;
                                if (SUCCEEDED(pFolderView->Items(SVGIO_SELECTION, IID_IEnumIDList, (LPVOID*)&pEnum)))
                                {
                                    LPITEMIDLIST pidl;
                                    WCHAR buf[MAX_PATH] = {0};
                                    ULONG fetched = 0;
                                    ULONG attribs = 0;
                                    do
                                    {
                                        pidl = NULL;
                                        if (SUCCEEDED(pEnum->Next(1, &pidl, &fetched)))
                                        {
                                            if (fetched)
                                            {
                                                // the pidl we get here is relative!
                                                attribs = SFGAO_FILESYSTEM|SFGAO_FOLDER;
                                                if (SUCCEEDED(pShellFolder->GetAttributesOf(1, (LPCITEMIDLIST*)&pidl, &attribs)))
                                                {
                                                    if (attribs & SFGAO_FILESYSTEM)
                                                    {
                                                        // create an absolute pidl with the pidl we got above
                                                        LPITEMIDLIST abspidl = CPidl::Append(folderpidl, pidl);
                                                        if (abspidl)
                                                        {
                                                            if (SHGetPathFromIDList(abspidl, buf))
                                                            {
                                                                m_selectedItems[std::wstring(buf)] = attribs;
                                                                if (m_currentDirectory.empty())
                                                                {
                                                                    // remove the last part of the path of the selected item
                                                                    WCHAR * pSlash = _tcsrchr(buf, '\\');
                                                                    if (pSlash)
                                                                        *pSlash = 0;
                                                                    m_currentDirectory = std::wstring(buf);
                                                                }
                                                            }
                                                            CoTaskMemFree(abspidl);
                                                        }
                                                        if (attribs & SFGAO_FOLDER)
                                                            m_bFolderSelected = true;
                                                        else
                                                            m_bFilesSelected = true;
                                                    }
                                                }
                                            }
                                            CoTaskMemFree(pidl);
                                        }
                                    } while(fetched);
                                    pEnum->Release();
                                }
                                pShellFolder->Release();
                            }
                            CoTaskMemFree(folderpidl);
                        }
                        pPersistFolder->Release();
                    }
                    pFolderView->Release();
                }
                pShellView->Release();
            }
            pShellBrowser->Release();
        }
        pServiceProvider->Release();
    }
    return ((!m_currentDirectory.empty()) || (!m_selectedItems.empty()));
}
Ejemplo n.º 2
0
/*
 * Class:     sun_awt_shell_Win32ShellFolder2
 * Method:    getAttributes0
 * Signature: (JJI)J
 */
JNIEXPORT jint JNICALL Java_sun_awt_shell_Win32ShellFolder2_getAttributes0
    (JNIEnv* env, jclass cls, jlong jpParentIShellFolder, jlong jpIDL, jint attrsMask)
{
    IShellFolder* pParentIShellFolder = (IShellFolder*)jpParentIShellFolder;
    if (pParentIShellFolder == NULL) {
        return 0;
    }
    LPCITEMIDLIST pIDL = (LPCITEMIDLIST)jpIDL;
    if (pIDL == NULL) {
        return 0;
    }
    ULONG attrs = attrsMask;
    HRESULT res = pParentIShellFolder->GetAttributesOf(1, &pIDL, &attrs);
    return attrs;
}
Ejemplo n.º 3
0
 /*
  * Class:     sun_awt_shell_Win32ShellFolder
  * Method:    hasAttribute
  * Signature: (JJI)Z
  */
 JNIEXPORT jboolean JNICALL Java_sun_awt_shell_Win32ShellFolder_hasAttribute__JJI
 (JNIEnv* env, jobject folder, jlong parentIShellFolder, jlong relativePIDL,
  jint dwAttribute)
 {
     IShellFolder* pParent = (IShellFolder*)parentIShellFolder;
     if (pParent == NULL) {
         return false;
     }
     LPITEMIDLIST pidl = (LPITEMIDLIST)relativePIDL;
     if (pidl == NULL) {
         return false;
     }
     ULONG attrib = (ULONG)dwAttribute;
     pParent->GetAttributesOf(1, const_cast<LPCITEMIDLIST*>(&pidl), &attrib);
     return ((dwAttribute & attrib) != 0);
 }
Ejemplo n.º 4
0
HRESULT GetItemAttributes(LPCITEMIDLIST pidl,SFGAOF *pItemAttributes)
{
	if(pidl == NULL ||
		pItemAttributes == NULL)
	{
		return E_FAIL;
	}

	IShellFolder	*pShellFolder = NULL;
	LPITEMIDLIST	pidlRelative = NULL;
	HRESULT			hr;

	hr = SHBindToParent(pidl, IID_PPV_ARGS(&pShellFolder),
	(LPCITEMIDLIST *)&pidlRelative);

	if(SUCCEEDED(hr))
	{
		hr = pShellFolder->GetAttributesOf(1,(LPCITEMIDLIST *)&pidlRelative,pItemAttributes);

		pShellFolder->Release();
	}

	return hr;
}
Ejemplo n.º 5
0
void CDeskBand::Rename(HWND hwnd, const std::map<std::wstring, ULONG>& items)
{
    // fill the list of selected file/foldernames
    m_filelist.clear();
    if (items.size() > 1)
    {
        for (std::map<std::wstring, ULONG>::const_iterator it = items.begin(); it != items.end(); ++it)
        {
            size_t pos = it->first.find_last_of('\\');
            if (pos != std::wstring::npos)
            {
                m_filelist.insert(it->first.substr(pos+1));
            }
        }
    }
    else if (items.size() == 1)
    {
        for (std::map<std::wstring, ULONG>::const_iterator it = items.begin(); it != items.end(); ++it)
        {
            size_t pos = it->first.find_last_of('\\');
            if (pos != std::wstring::npos)
            {
                m_filelist.insert(it->first.substr(pos+1));
            }
        }
    }
    else
    {
        // no files or only one file were selected.
        // use all files and folders in the current folder instead
        IServiceProvider * pServiceProvider = NULL;
        if (SUCCEEDED(GetIServiceProvider(hwnd, &pServiceProvider)))
        {
            IShellBrowser * pShellBrowser;
            if (SUCCEEDED(pServiceProvider->QueryService(SID_SShellBrowser, IID_IShellBrowser, (LPVOID*)&pShellBrowser)))
            {
                IShellView * pShellView;
                if (SUCCEEDED(pShellBrowser->QueryActiveShellView(&pShellView)))
                {
                    IFolderView * pFolderView;
                    if (SUCCEEDED(pShellView->QueryInterface(IID_IFolderView, (LPVOID*)&pFolderView)))
                    {
                        // hooray! we got the IFolderView interface!
                        // that means the explorer is active and well :)

                        // but we also need the IShellFolder interface because
                        // we need its GetCurFolder() method
                        IPersistFolder2 * pPersistFolder;
                        if (SUCCEEDED(pFolderView->GetFolder(IID_IPersistFolder2, (LPVOID*)&pPersistFolder)))
                        {
                            LPITEMIDLIST folderpidl;
                            if (SUCCEEDED(pPersistFolder->GetCurFolder(&folderpidl)))
                            {
                                // we have the current folder
                                TCHAR buf[MAX_PATH] = {0};
                                // find the path of the folder
                                if (SHGetPathFromIDList(folderpidl, buf))
                                {
                                    m_currentDirectory = buf;
                                }
                                // if m_currentDirectory is empty here, that means
                                // the current directory is a virtual path

                                IShellFolder * pShellFolder;
                                if (SUCCEEDED(pPersistFolder->QueryInterface(IID_IShellFolder, (LPVOID*)&pShellFolder)))
                                {
                                    // find all selected items
                                    IEnumIDList * pEnum;
                                    if (SUCCEEDED(pFolderView->Items(SVGIO_ALLVIEW, IID_IEnumIDList, (LPVOID*)&pEnum)))
                                    {
                                        LPITEMIDLIST pidl;
                                        WCHAR buf[MAX_PATH] = {0};
                                        ULONG fetched = 0;
                                        ULONG attribs = 0;
                                        do
                                        {
                                            pidl = NULL;
                                            if (SUCCEEDED(pEnum->Next(1, &pidl, &fetched)))
                                            {
                                                if (fetched)
                                                {
                                                    // the pidl we get here is relative!
                                                    attribs = SFGAO_FILESYSTEM|SFGAO_FOLDER;
                                                    if (SUCCEEDED(pShellFolder->GetAttributesOf(1, (LPCITEMIDLIST*)&pidl, &attribs)))
                                                    {
                                                        if (attribs & SFGAO_FILESYSTEM)
                                                        {
                                                            // create an absolute pidl with the pidl we got above
                                                            LPITEMIDLIST abspidl = CPidl::Append(folderpidl, pidl);
                                                            if (abspidl)
                                                            {
                                                                if (SHGetPathFromIDList(abspidl, buf))
                                                                {
                                                                    std::wstring p = buf;
                                                                    size_t pos = p.find_last_of('\\');
                                                                    if (pos != std::wstring::npos)
                                                                    {
                                                                        m_filelist.insert(p.substr(pos+1));
                                                                    }
                                                                }
                                                                CoTaskMemFree(abspidl);
                                                            }
                                                        }
                                                    }
                                                }
                                                CoTaskMemFree(pidl);
                                            }
                                        } while(fetched);
                                        pEnum->Release();
                                    }
                                    pShellFolder->Release();
                                }
                                CoTaskMemFree(folderpidl);
                            }
                            pPersistFolder->Release();
                        }
                        pFolderView->Release();
                    }
                    pShellView->Release();
                }
                pShellBrowser->Release();
            }
            pServiceProvider->Release();
        }
    }

    // show the rename dialog
    m_bDialogShown = TRUE;
    CRenameDlg dlg(hwnd);
    dlg.SetFileList(m_filelist);
    if (dlg.DoModal(g_hInst, IDD_RENAMEDLG, hwnd, NULL) == IDOK)
    {
        try
        {
            const std::tr1::wregex regCheck(dlg.GetMatchString(), dlg.GetRegexFlags());
            NumberReplaceHandler handler(dlg.GetReplaceString());

            // start renaming the files
            IServiceProvider * pServiceProvider = NULL;
            if (SUCCEEDED(GetIServiceProvider(hwnd, &pServiceProvider)))
            {
                IShellBrowser * pShellBrowser;
                if (SUCCEEDED(pServiceProvider->QueryService(SID_SShellBrowser, IID_IShellBrowser, (LPVOID*)&pShellBrowser)))
                {
                    IShellView * pShellView;
                    if (SUCCEEDED(pShellBrowser->QueryActiveShellView(&pShellView)))
                    {
                        IFolderView * pFolderView;
                        if (SUCCEEDED(pShellView->QueryInterface(IID_IFolderView, (LPVOID*)&pFolderView)))
                        {
                            // hooray! we got the IFolderView interface!
                            // that means the explorer is active and well :)

                            // but we also need the IShellFolder interface because
                            // we need its GetDisplayNameOf() method
                            IPersistFolder2 * pPersistFolder;
                            if (SUCCEEDED(pFolderView->GetFolder(IID_IPersistFolder2, (LPVOID*)&pPersistFolder)))
                            {
                                IShellFolder * pShellFolder;
                                if (SUCCEEDED(pPersistFolder->QueryInterface(IID_IShellFolder, (LPVOID*)&pShellFolder)))
                                {
                                    // our next task is to enumerate all the
                                    // items in the folder view and select those
                                    // which match the text in the edit control

                                    int nCount = 0;
                                    if (SUCCEEDED(pFolderView->ItemCount(SVGIO_ALLVIEW, &nCount)))
                                    {
                                        for (int i=0; i<nCount; ++i)
                                        {
                                            LPITEMIDLIST pidl;
                                            if (SUCCEEDED(pFolderView->Item(i, &pidl)))
                                            {
                                                STRRET str;
                                                if (SUCCEEDED(pShellFolder->GetDisplayNameOf(pidl,
                                                    // SHGDN_FORPARSING needed to get the extensions even if they're not shown
                                                    SHGDN_INFOLDER|SHGDN_FORPARSING,
                                                    &str)))
                                                {
                                                    TCHAR dispname[MAX_PATH];
                                                    StrRetToBuf(&str, pidl, dispname, _countof(dispname));

                                                    std::wstring replaced;
                                                    try
                                                    {
                                                        std::wstring sDispName = dispname;
                                                        // check if the item is in the list of selected items
                                                        if (m_filelist.find(sDispName) != m_filelist.end())
                                                        {
                                                            replaced = std::tr1::regex_replace(sDispName, regCheck, dlg.GetReplaceString());
                                                            replaced = handler.ReplaceCounters(replaced);
                                                            if (replaced.compare(sDispName))
                                                            {
                                                                ITEMIDLIST * pidlrenamed;
                                                                pShellFolder->SetNameOf(NULL, pidl, replaced.c_str(), SHGDN_FORPARSING|SHGDN_INFOLDER, &pidlrenamed);
                                                                // if the rename was successful, select the renamed item
                                                                if (pidlrenamed)
                                                                    pFolderView->SelectItem(i, SVSI_CHECK|SVSI_SELECT);
                                                            }
                                                        }
                                                    }
                                                    catch (std::exception)
                                                    {
                                                    }
                                                }
                                                CoTaskMemFree(pidl);
                                            }
                                        }
                                    }
                                    pShellFolder->Release();
                                }
                                pPersistFolder->Release();
                            }
                            pFolderView->Release();
                        }
                        pShellView->Release();
                    }
                    pShellBrowser->Release();
                }
                pServiceProvider->Release();
            }
        }
        catch (std::exception)
        {
        }
    }
    m_bDialogShown = FALSE;
}
Ejemplo n.º 6
0
void FileDialog::FilterFiles(HWND hDlg)
{
   HWND parent = ::GetParent(hDlg);
   IShellFolder *ishell = NULL;
   LPMALLOC imalloc = NULL;
   HRESULT hr;
   
   // Get pointer to the ListView control
   HWND lv = ::GetDlgItem(::GetDlgItem(parent, lst2), 1);
   if (lv == NULL)
   {
      wxASSERT(lv != NULL);
      return;
   }
   
   // Get shell's memory allocation interface (must be Release()'d)
   hr = SHGetMalloc(&imalloc);
   if ((hr != NOERROR) || (imalloc == NULL))
   {
      wxASSERT((hr == NOERROR) && (imalloc != NULL));
      return;
   }
   
   // Init
   LVITEM lvi;
   wxZeroMemory(lvi);
   
   // Process all items
   int fltcnt = m_Filters.GetCount();
   int itmcnt = ::SendMessage(lv, LVM_GETITEMCOUNT, 0, 0);
   for (int itm = 0; itm < itmcnt; itm++)
   {
      // Retrieve the file IDL
      lvi.iItem = itm;
      lvi.mask = LVIF_PARAM;
      if (ListView_GetItem(lv, &lvi) != TRUE)
      {
         wxASSERT(FALSE);
         break;
      }
      LPCITEMIDLIST fidl = (LPCITEMIDLIST) lvi.lParam;
      
      // Retrieve the IShellFolder interface of the parent (must be Release()'d)
      if (ishell == NULL)
      {
         hr = SHBindToParent(fidl, IID_IShellFolder, (void **)&ishell, NULL);
         if (!SUCCEEDED(hr))
         {
            wxASSERT(SUCCEEDED(hr));
            break;
         }
      }
      
      // Get the attributes of the object
      DWORD attr = SFGAO_FOLDER | SFGAO_STREAM;
      hr = ishell->GetAttributesOf(1, &fidl, &attr);
      if (!SUCCEEDED(hr))
      {
         wxASSERT(SUCCEEDED(hr));
         break;
      }
      
      // Allow all folders (things like zip files get filtered below)
      if (attr == SFGAO_FOLDER)
      {
         continue;
      }
      
      // Retrieve the parsable name of the object (includes extension)
      STRRET str;
      hr = ishell->GetDisplayNameOf(fidl, SHGDN_INFOLDER | SHGDN_FORPARSING, &str);
      if (hr != NOERROR)
      {
         // For some objects, we get back an error of 80070057.  I'm assuming this
         // means there is no way to represent the name (like some sort of virtual name)
         // or I've not used the correct PIDL.  But, in either case, it "probably"
         // represents some sort of folder (at least in all cases I've seen), so we
         // simply allow it to display.
         continue;
      }
      
      // Convert result to wxString
      wxString filename;
      switch (str.uType)
      {
         case STRRET_WSTR:
            filename = str.pOleStr;
            imalloc->Free(str.pOleStr);
            break;
            
         case STRRET_OFFSET:
            filename = wxString(((char *)fidl) + str.uOffset, wxConvISO8859_1);
            break;
            
         case STRRET_CSTR:
            filename = wxString(str.cStr, wxConvISO8859_1);
            break;
      }
      
      // Attempt to match it to all of our filters
      bool match = false;
      for (int flt = 0; flt < fltcnt; flt++)
      {
         if (wxMatchWild(m_Filters[flt], filename, false))
         {
            match = true;
            break;
         }
      }
      
      // Remove it from the display if it didn't match any of the filters.
      if (!match)
      {
         ListView_DeleteItem(lv, itm);
         itm--;
         itmcnt--;
      }
   }
   
done:
   
   // Release the interface
   if (ishell)
   {
      ishell->Release();
   }
   
   // Release the interface
   if (imalloc)
   {
      imalloc->Release();
   }
}
Ejemplo n.º 7
0
const FileItemList& FileItem::getChildren()
{
  // Is the file-item a folder?
  if (IS_FOLDER(this) &&
      // if the children list is empty, or the file-system version
      // change (it's like to say: the current this->children list
      // is outdated)...
      (this->children.empty() ||
       current_file_system_version > this->version)) {
    FileItemList::iterator it;
    FileItem* child;

    // we have to mark current items as deprecated
    for (it=this->children.begin();
         it!=this->children.end(); ++it) {
      child = static_cast<FileItem*>(*it);
      child->removed = true;
    }

    //PRINTF("FS: Loading files for %p (%s)\n", fileitem, fileitem->displayname);
#ifdef USE_PIDLS
    {
      IShellFolder* pFolder = NULL;

      if (this == rootitem)
        pFolder = shl_idesktop;
      else
        shl_idesktop->BindToObject(this->fullpidl,
                                   NULL,
                                   IID_IShellFolder,
                                   (LPVOID *)&pFolder);

      if (pFolder != NULL) {
        IEnumIDList *pEnum = NULL;
        ULONG c, fetched;

        /* get the interface to enumerate subitems */
        pFolder->EnumObjects(win_get_window(),
                             SHCONTF_FOLDERS | SHCONTF_NONFOLDERS, &pEnum);

        if (pEnum != NULL) {
          LPITEMIDLIST itempidl[256];
          SFGAOF attribs[256];

          /* enumerate the items in the folder */
          while (pEnum->Next(256, itempidl, &fetched) == S_OK && fetched > 0) {
            /* request the SFGAO_FOLDER attribute to know what of the
               item is a folder */
            for (c=0; c<fetched; ++c) {
              attribs[c] = SFGAO_FOLDER;
              pFolder->GetAttributesOf(1, (LPCITEMIDLIST *)itempidl, attribs+c);
            }

            /* generate the FileItems */
            for (c=0; c<fetched; ++c) {
              LPITEMIDLIST fullpidl = concat_pidl(this->fullpidl,
                                                  itempidl[c]);

              child = get_fileitem_by_fullpidl(fullpidl, false);
              if (!child) {
                child = new FileItem(this);

                child->pidl = itempidl[c];
                child->fullpidl = fullpidl;
                child->attrib = attribs[c];

                update_by_pidl(child);
                put_fileitem(child);
              }
              else {
                ASSERT(child->parent == this);
                free_pidl(fullpidl);
                free_pidl(itempidl[c]);
              }

              this->insertChildSorted(child);
            }
          }

          pEnum->Release();
        }

        if (pFolder != shl_idesktop)
          pFolder->Release();
      }
    }
#else
    {
      char buf[MAX_PATH], path[MAX_PATH], tmp[32];

      ustrcpy(path, this->filename.c_str());
      put_backslash(path);

      replace_filename(buf,
                       path,
                       uconvert_ascii("*.*", tmp),
                       sizeof(buf));

#ifdef WORKAROUND_64BITS_SUPPORT
      // we cannot use the for_each_file's 'param' to wrap a 64-bits pointer
      for_each_child_callback_param = this;
      for_each_file(buf, FA_TO_SHOW, for_each_child_callback, 0);
#else
      for_each_file(buf, FA_TO_SHOW,
                    for_each_child_callback,
                    (int)this);
#endif
  }
#endif

    // check old file-items (maybe removed directories or file-items)
    for (it=this->children.begin();
         it!=this->children.end(); ) {
      child = static_cast<FileItem*>(*it);
      if (child->removed) {
        it = this->children.erase(it);

        fileitems_map->erase(fileitems_map->find(child->keyname));
        delete child;
      }
      else
        ++it;
    }

    // now this file-item is updated
    this->version = current_file_system_version;
  }

  return this->children;
}
Ejemplo n.º 8
0
void FileDialog::FilterFiles(HWND hDlg, bool refresh)
{
   HWND parent = ::GetParent(hDlg);
   IShellFolder *ishell = NULL;
   IShellBrowser *ishellbrowser = NULL;  // Does not have to be released
   IShellView *ishellview = NULL;
   IFolderView *ifolderview = NULL;
   LPMALLOC imalloc = NULL;
   HRESULT hr;
   
   // Get pointer to the ListView control
   HWND lv = ::GetDlgItem(::GetDlgItem(parent, lst2), 1);
   if (lv == NULL)
   {
      wxASSERT(lv != NULL);
      return;
   }
   
   // Get shell's memory allocation interface (must be Release()'d)
   hr = SHGetMalloc(&imalloc);
   if ((hr != NOERROR) || (imalloc == NULL))
   {
      wxASSERT((hr == NOERROR) && (imalloc != NULL));
      return;
   }

   // Get IShellBrowser interface for current dialog
   ishellbrowser = (IShellBrowser*)::SendMessage(parent, WM_GETISHELLBROWSER, 0, 0);
   if (ishellbrowser)
   {
      // Get IShellBrowser interface for returned browser
      if (ishellbrowser->QueryActiveShellView(&ishellview) == S_OK)
      {
         // Get the IFolderView interface...available on XP or greater
         ishellview->QueryInterface(IID_IFolderView, (void **)&ifolderview);
      }
   }

   // Init
   LVITEM lvi;
   wxZeroMemory(lvi);

   // Process all items
   int fltcnt = (int) m_Filters.GetCount();
   int itmcnt = ::SendMessage(lv, LVM_GETITEMCOUNT, 0, 0);
   for (int itm = 0; itm < itmcnt; itm++)
   {
      // Retrieve the file IDL
      lvi.iItem = itm;
      lvi.mask = LVIF_PARAM;
      if (ListView_GetItem(lv, &lvi) != TRUE)
      {
         wxASSERT(FALSE);
         break;
      }

      LPCITEMIDLIST fidl = (LPCITEMIDLIST) lvi.lParam;

      // On Vista, lParam no longer contains the pidl so retrieve it via the
      // IFolderView interface.  This interface is only available on XP or higher
      // so if that limitation isn't workable, use IShellView::GetItemObject() to
      // retrieve items.
      if (fidl == NULL && ifolderview != NULL)
      {
         ifolderview->Item(itm, (LPITEMIDLIST *) &fidl);
      }

      if (fidl == NULL)
      {
         wxASSERT(fidl != NULL);
         break;
      }

      // Retrieve the IShellFolder interface of the parent (must be Release()'d)
      if (ishell == NULL)
      {
         hr = SHBindToParentLocal(fidl, IID_IShellFolder, (void **)&ishell, NULL);
         if (!SUCCEEDED(hr))
         {
            wxASSERT(SUCCEEDED(hr));
            break;
         }
      }
      
      // Get the attributes of the object
      DWORD attr = SFGAO_FOLDER | SFGAO_BROWSABLE;
      hr = ishell->GetAttributesOf(1, &fidl, &attr);
      if (!SUCCEEDED(hr))
      {
         wxASSERT(SUCCEEDED(hr));
         break;
      }
      
      // Allow all folders (things like zip files get filtered below)
      if ((attr & (SFGAO_FOLDER)) && !(attr & SFGAO_BROWSABLE))
      {
         continue;
      }
      
      // Retrieve the parsable name of the object (includes extension)
      STRRET str;
      hr = ishell->GetDisplayNameOf(fidl, SHGDN_INFOLDER | SHGDN_FORPARSING, &str);
      if (hr != NOERROR)
      {
         // For some objects, we get back an error of 80070057.  I'm assuming this
         // means there is no way to represent the name (like some sort of virtual name)
         // or I've not used the correct PIDL.  But, in either case, it "probably"
         // represents some sort of folder (at least in all cases I've seen), so we
         // simply allow it to display.
         continue;
      }
      
      // Convert result to wxString
      wxString filename;
      switch (str.uType)
      {
         case STRRET_WSTR:
            filename = str.pOleStr;
            imalloc->Free(str.pOleStr);
            break;
            
         case STRRET_OFFSET:
            filename = wxString(((char *)fidl) + str.uOffset, wxConvISO8859_1);
            break;
            
         case STRRET_CSTR:
            filename = wxString(str.cStr, wxConvISO8859_1);
            break;
      }
      
      // Convert the filename to lowercase (and remember to write filters in lowercase!)
      filename = filename.Lower();

      // Attempt to match it to all of our filters
      bool match = false;
      for (int flt = 0; flt < fltcnt; flt++)
      {
         if (wxMatchWild(m_Filters[flt], filename, false))
         {
            match = true;
            break;
         }
      }
      
      // Remove it from the display if it didn't match any of the filters.
      if (!match)
      {
         ListView_DeleteItem(lv, itm);
         itm--;
         itmcnt--;
      }
   }

   // On Vista and maybe XP, we seem to need to refresh the view after
   // changing the filters.  But, only refresh for type changes and not
   // selection changes since it causes additional selection change
   // events to occur.
   if (ishellview && refresh)
   {
      ishellview->Refresh();
   }

   // Release the interface
   if (ifolderview)
   {
      ifolderview->Release();
   }

   // Release the interface
   if (ishellview)
   {
      ishellview->Release();
   }

   // Release the interface
   if (ishell)
   {
      ishell->Release();
   }
   
   // Release the interface
   if (imalloc)
   {
      imalloc->Release();
   }
}
Ejemplo n.º 9
0
void CShellBrowser::BrowseVirtualFolder(LPITEMIDLIST pidlDirectory)
{
	IShellFolder	*pShellFolder = NULL;
	IEnumIDList		*pEnumIDList = NULL;
	LPITEMIDLIST	rgelt = NULL;
	STRRET			str;
	SHCONTF			EnumFlags;
	TCHAR			szFileName[MAX_PATH];
	ULONG			uFetched;
	HRESULT			hr;

	DetermineFolderVirtual(pidlDirectory);

	hr = BindToIdl(pidlDirectory, IID_PPV_ARGS(&pShellFolder));

	if(SUCCEEDED(hr))
	{
		m_pidlDirectory = ILClone(pidlDirectory);

		EnumFlags = SHCONTF_FOLDERS|SHCONTF_NONFOLDERS;

		if(m_bShowHidden)
			EnumFlags |= SHCONTF_INCLUDEHIDDEN;

		hr = pShellFolder->EnumObjects(m_hOwner,EnumFlags,&pEnumIDList);

		if(SUCCEEDED(hr) && pEnumIDList != NULL)
		{
			uFetched = 1;
			while(pEnumIDList->Next(1,&rgelt,&uFetched) == S_OK && (uFetched == 1))
			{
				ULONG uAttributes = SFGAO_FOLDER;

				pShellFolder->GetAttributesOf(1,(LPCITEMIDLIST *)&rgelt,&uAttributes);

				/* If this is a virtual folder, only use SHGDN_INFOLDER. If this is
				a real folder, combine SHGDN_INFOLDER with SHGDN_FORPARSING. This is
				so that items in real folders can still be shown with extensions, even
				if the global, Explorer option is disabled.
				Also use only SHGDN_INFOLDER if this item is a folder. This is to ensure
				that specific folders in Windows 7 (those under C:\Users\Username) appear
				correctly. */
				if(m_bVirtualFolder || (uAttributes & SFGAO_FOLDER))
					hr = pShellFolder->GetDisplayNameOf(rgelt,SHGDN_INFOLDER,&str);
				else
					hr = pShellFolder->GetDisplayNameOf(rgelt,SHGDN_INFOLDER|SHGDN_FORPARSING,&str);

				if(SUCCEEDED(hr))
				{
					StrRetToBuf(&str,rgelt,szFileName,MAX_PATH);

					AddItemInternal(pidlDirectory,rgelt,szFileName,-1,FALSE);
				}

				CoTaskMemFree((LPVOID)rgelt);
			}

			pEnumIDList->Release();
		}

		pShellFolder->Release();
	}
}
void CMyTreeView::AddItemInternal(HTREEITEM hParent,const TCHAR *szFullFileName)
{
	IShellFolder	*pShellFolder = NULL;
	LPITEMIDLIST	pidlComplete = NULL;
	LPITEMIDLIST	pidlRelative = NULL;
	HTREEITEM		hItem;
	TVITEMEX		tvItem;
	TVINSERTSTRUCT	tvis;
	SHFILEINFO		shfi;
	SFGAOF			Attributes;
	TCHAR			szDisplayName[MAX_PATH];
	HRESULT			hr;
	BOOL			res;
	int				iItemId;
	int				nChildren = 0;

	hr = GetIdlFromParsingName(szFullFileName,&pidlComplete);

	if(!SUCCEEDED(hr))
		return;

	tvItem.mask		= TVIF_CHILDREN | TVIF_STATE;
	tvItem.hItem	= hParent;
	res = TreeView_GetItem(m_hTreeView,&tvItem);

	if(res)
	{
		/* If the parent node is currently collapsed,
		simply indicate that it has children (i.e. a
		plus sign will be shown next to the parent node). */
		if((tvItem.cChildren == 0) ||
			((tvItem.state & TVIS_EXPANDED) != TVIS_EXPANDED))
		{
			tvItem.mask			= TVIF_CHILDREN;
			tvItem.hItem		= hParent;
			tvItem.cChildren	= 1;
			TreeView_SetItem(m_hTreeView,&tvItem);
		}
		else
		{
			SHGetFileInfo(szFullFileName,NULL,&shfi,
				sizeof(shfi),SHGFI_SYSICONINDEX);

			hr = SHBindToParent(pidlComplete, IID_PPV_ARGS(&pShellFolder), (LPCITEMIDLIST *)&pidlRelative);

			if(SUCCEEDED(hr))
			{
				Attributes = SFGAO_HASSUBFOLDER;

				/* Only retrieve the attributes for this item. */
				hr = pShellFolder->GetAttributesOf(1,
					(LPCITEMIDLIST *)&pidlRelative,&Attributes);

				if(SUCCEEDED(hr))
				{
					if((Attributes & SFGAO_HASSUBFOLDER) != SFGAO_HASSUBFOLDER)
						nChildren = 0;
					else
						nChildren = 1;

					iItemId = GenerateUniqueItemId();

					m_pItemInfo[iItemId].pidl = ILClone(pidlComplete);
					m_pItemInfo[iItemId].pridl = ILClone(pidlRelative);

					GetDisplayName(szFullFileName,szDisplayName,SIZEOF_ARRAY(szDisplayName),SHGDN_NORMAL);

					tvItem.mask				= TVIF_TEXT|TVIF_IMAGE|TVIF_SELECTEDIMAGE|TVIF_PARAM|TVIF_CHILDREN;
					tvItem.pszText			= szDisplayName;
					tvItem.iImage			= shfi.iIcon;
					tvItem.iSelectedImage	= shfi.iIcon;
					tvItem.lParam			= (LPARAM)iItemId;
					tvItem.cChildren		= nChildren;

					if(hParent != NULL)
					{
						tvis.hParent			= hParent;
						tvis.hInsertAfter		= DetermineItemSortedPosition(hParent,szFullFileName);
						tvis.itemex				= tvItem;

						hItem = TreeView_InsertItem(m_hTreeView,&tvis);
					}
				}

				pShellFolder->Release();
			}
		}
	}

	CoTaskMemFree(pidlComplete);
}
Ejemplo n.º 11
0
//***************************************************************************************
void CBCGPShellList::DoDefault (int iItem)
{
	LVITEM lvItem;
	
	ZeroMemory(&lvItem, sizeof(lvItem));
	lvItem.mask = LVIF_PARAM;
	lvItem.iItem = iItem;
	
	if (!GetItem (&lvItem))
	{
		return;
	}

	LPBCGCBITEMINFO	pInfo = (LPBCGCBITEMINFO) lvItem.lParam;
	if (pInfo == NULL || pInfo->pParentFolder == NULL || pInfo->pidlRel == NULL)
	{
		ASSERT (FALSE);
		return;
	}

	IShellFolder *psfFolder = pInfo->pParentFolder;
	if (psfFolder == NULL)
	{
		SHGetDesktopFolder (&psfFolder);
	}
	else
	{
		psfFolder->AddRef ();
	}
	
	if (psfFolder == NULL)
	{
		return;
	}

	//-----------------------------------------------------
	// If specified element is a folder, try to display it:
	//-----------------------------------------------------
	ULONG ulAttrs = SFGAO_FOLDER;
	psfFolder->GetAttributesOf (1, 
		(const struct _ITEMIDLIST **) &pInfo->pidlRel, &ulAttrs);

	if (ulAttrs & SFGAO_FOLDER)
	{
		DisplayFolder (pInfo);
	}
	else
	{
		//-------------------------------
		// Invoke a default menu command:
		//-------------------------------
		IContextMenu *pcm;
		HRESULT hr = psfFolder->GetUIObjectOf (GetSafeHwnd (),
			1, 
			(LPCITEMIDLIST*)&pInfo->pidlRel, 
			IID_IContextMenu, 
			NULL, 
			(LPVOID*)&pcm);
		
		if (SUCCEEDED (hr))
		{
			HMENU hPopup = CreatePopupMenu ();

			if (hPopup != NULL)
			{
				hr = pcm->QueryContextMenu (hPopup, 0, 1, 0x7fff, 
											CMF_DEFAULTONLY | CMF_EXPLORE);
				
				if (SUCCEEDED (hr))
				{
					UINT idCmd = ::GetMenuDefaultItem (hPopup, FALSE, 0);
					if (idCmd != 0 && idCmd != (UINT)-1)
					{
						CMINVOKECOMMANDINFO cmi;
						cmi.cbSize = sizeof (CMINVOKECOMMANDINFO);
						cmi.fMask = 0;
						cmi.hwnd = GetParent()->GetSafeHwnd ();
						cmi.lpVerb = (LPCSTR)(INT_PTR)(idCmd - 1);
						cmi.lpParameters = NULL;
						cmi.lpDirectory = NULL;
						cmi.nShow = SW_SHOWNORMAL;
						cmi.dwHotKey = 0;
						cmi.hIcon = NULL;

						hr = pcm->InvokeCommand (&cmi);

						if (SUCCEEDED (hr) && GetParent () != NULL)
						{
							GetParent ()->SendMessage (BCGPM_ON_AFTER_SHELL_COMMAND,
								(WPARAM) idCmd);
						}
					}
				}
			}
			
			pcm->Release ();
		}
	}
	
	psfFolder->Release ();
}