예제 #1
0
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()));
}
예제 #2
0
파일: Rename.cpp 프로젝트: SpivEgin/stexbar
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;
}