Ejemplo n.º 1
0
void GetExplorerWindows(std::vector<PairHwndPath>& windows, BOOL needPaths) {
    IShellWindows *psw;
    if(SUCCEEDED(CoCreateInstance(CLSID_ShellWindows, NULL, CLSCTX_ALL, IID_IShellWindows, (void**)&psw))) {
        VARIANT v;
        V_VT(&v) = VT_I4;
        IDispatch* pdisp;
        for(V_I4(&v) = 0; psw->Item(v, &pdisp) == S_OK; V_I4(&v)++) {
            IWebBrowserApp *pwba;
            if(SUCCEEDED(pdisp->QueryInterface(IID_IWebBrowserApp, (void**)&pwba))) {
                PairHwndPath pair;
                if(SUCCEEDED(pwba->get_HWND((LONG_PTR*)&pair.hwnd))) {
                    IServiceProvider *psp;
                    if(needPaths && SUCCEEDED(pwba->QueryInterface(IID_IServiceProvider, (void**)&psp))) {
                        IShellBrowser *psb;
                        if(SUCCEEDED(psp->QueryService(SID_STopLevelBrowser, IID_IShellBrowser, (void**)&psb))) {
                            IShellView *psv;
                            if(SUCCEEDED(psb->QueryActiveShellView(&psv))) {
                                IFolderView *pfv;
                                if(SUCCEEDED(psv->QueryInterface(IID_IFolderView, (void**)&pfv))) {
                                    IPersistFolder2 *ppf2;
                                    if(SUCCEEDED(pfv->GetFolder(IID_IPersistFolder2, (void**)&ppf2))) {
                                        LPITEMIDLIST pidlFolder;
                                        if(SUCCEEDED(ppf2->GetCurFolder(&pidlFolder))) {
                                            if(!SHGetPathFromIDList(pidlFolder, pair.path)) {
                                                IShellFolder* psf;
                                                LPCITEMIDLIST pidlLast;
                                                if(SUCCEEDED(SHBindToParent(pidlFolder, IID_IShellFolder, (void**)&psf, &pidlLast))) {
                                                    STRRET strret;
                                                    if(SUCCEEDED(psf->GetDisplayNameOf(pidlLast, 0x8000, &strret))) {
                                                        StrRetToBuf(&strret, pidlLast, pair.path, MAX_PATH);
                                                    }
                                                    else {
                                                        pair.path[0] = 0;
                                                    }
                                                    psf->Release();
                                                }
                                            }
                                            CoTaskMemFree(pidlFolder);
                                        }
                                        ppf2->Release();
                                    }
                                    pfv->Release();
                                }
                                psv->Release();
                            }
                            psb->Release();
                        }
                        psp->Release();
                    }
                    windows.push_back(pair);
                }
                pwba->Release();
            }
            pdisp->Release();
        }
        psw->Release();
    }
}
Ejemplo n.º 2
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()));
}
Ejemplo n.º 3
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.º 4
0
bool CDeskBand::Filter(LPTSTR filter)
{
    bool bReturn = 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 :)
                    IShellFolderView * pShellFolderView;
                    if (SUCCEEDED(pShellView->QueryInterface(IID_IShellFolderView, (LPVOID*)&pShellFolderView)))
                    {
                        // the first thing we do is to deselect all already selected entries
                        pFolderView->SelectItem(NULL, SVSI_DESELECTOTHERS);

                        // but we also need the IShellFolder interface because
                        // we need its GetDisplayNameOf() method
                        IPersistFolder2 * pPersistFolder;
                        if (SUCCEEDED(pFolderView->GetFolder(IID_IPersistFolder2, (LPVOID*)&pPersistFolder)))
                        {
                            LPITEMIDLIST curFolder;
                            pPersistFolder->GetCurFolder(&curFolder);
                            if (ILIsEqual(m_currentFolder, curFolder))
                            {
                                CoTaskMemFree(curFolder);
                            }
                            else
                            {
                                CoTaskMemFree(m_currentFolder);
                                m_currentFolder = curFolder;
                                for (size_t i=0; i<m_noShows.size(); ++i)
                                {
                                    CoTaskMemFree(m_noShows[i]);
                                }
                                m_noShows.clear();
                            }
                            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

                                bool bUseRegex = (filter[0] == '\\');

                                try
                                {
                                    const std::tr1::wregex regCheck(&filter[1], std::tr1::regex_constants::icase | std::tr1::regex_constants::ECMAScript);
                                }
                                catch (std::exception)
                                {
                                    bUseRegex = false;
                                }

                                if (!bUseRegex)
                                {
                                    // force the filter to lowercase
                                    TCHAR * pString = filter;
                                    while (*pString)
                                    {
                                        *pString = _totlower(*pString);
                                        pString++;
                                    }
                                }

                                int nCount = 0;
                                if (SUCCEEDED(pFolderView->ItemCount(SVGIO_ALLVIEW, &nCount)))
                                {
                                    pShellFolderView->SetRedraw(FALSE);
                                    HWND listView = GetListView32(pShellView);
                                    LRESULT viewType = 0;
                                    if (listView)
                                    {
                                        // inserting items in the list view if the list view is set to
                                        // e.g., LV_VIEW_LIST is painfully slow. So save the current view
                                        // and set it to LV_VIEW_DETAILS (which is much faster for inserting)
                                        // and restore the view after we're done.
                                        viewType = SendMessage(listView, LVM_GETVIEW, 0, 0);
                                        SendMessage(listView, LVM_SETVIEW, LV_VIEW_DETAILS, 0);
                                    }
                                    std::vector<LPITEMIDLIST> noShows;
                                    for (int i=0; i<nCount; ++i)
                                    {
                                        LPITEMIDLIST pidl;
                                        if (SUCCEEDED(pFolderView->Item(i, &pidl)))
                                        {
                                            if (CheckDisplayName(pShellFolder, pidl, filter, bUseRegex))
                                            {
                                                // remove now shown items which are in the no-show list
                                                // this is necessary since we don't get a notification
                                                // if the shell refreshes its view
                                                for (std::vector<LPITEMIDLIST>::iterator it = m_noShows.begin(); it != m_noShows.end(); ++it )
                                                {
                                                    if (HRESULT_CODE(pShellFolder->CompareIDs(SHCIDS_CANONICALONLY, *it, pidl))==0)
                                                    {
                                                        m_noShows.erase(it);
                                                        break;
                                                    }
                                                }
                                                CoTaskMemFree(pidl);
                                            }
                                            else
                                            {
                                                UINT puItem = 0;
                                                if (pShellFolderView->RemoveObject(pidl, &puItem) == S_OK)
                                                {
                                                    i--;
                                                    nCount--;
                                                    noShows.push_back(pidl);
                                                }
                                            }
                                        }
                                    }
                                    // now add all those items again which were removed by a previous filter string
                                    // but don't match this new one
                                    //pShellFolderView->SetObjectCount(5000, SFVSOC_INVALIDATE_ALL|SFVSOC_NOSCROLL);
                                    for (size_t i=0; i<m_noShows.size(); ++i)
                                    {
                                        LPITEMIDLIST pidlNoShow = m_noShows[i];
                                        if (CheckDisplayName(pShellFolder, pidlNoShow, filter, bUseRegex))
                                        {
                                            m_noShows.erase(m_noShows.begin() + i);
                                            i--;
                                            UINT puItem = (UINT)i;
                                            pShellFolderView->AddObject(pidlNoShow, &puItem);
                                            CoTaskMemFree(pidlNoShow);
                                        }
                                    }
                                    for (size_t i=0; i<noShows.size(); ++i)
                                    {
                                        m_noShows.push_back(noShows[i]);
                                    }
                                    if (listView)
                                    {
                                        SendMessage(listView, LVM_SETVIEW, viewType, 0);
                                    }

                                    pShellFolderView->SetRedraw(TRUE);
                                }
                                pShellFolder->Release();
                            }
                            pPersistFolder->Release();
                        }
                        pShellFolderView->Release();
                    }
                    pFolderView->Release();
                }
                pShellView->Release();
            }
            pShellBrowser->Release();
        }
        pServiceProvider->Release();
    }
    return bReturn;
}