HRESULT CFShellUtil::GetItemIdName( LPCITEMIDLIST pItemIdList, LPTSTR pFriendlyName, UINT cchBuf, DWORD dwFlags, IShellFolder* pSF ) { HRESULT hr = S_OK; STRRET strRet = {0}; IShellFolder* pShellFolder = pSF; if ( pShellFolder == NULL ) { COM_VERIFY(SHGetDesktopFolder( &pShellFolder )); if ( !pShellFolder ) { return hr; } } COM_VERIFY(pShellFolder->GetDisplayNameOf( pItemIdList, dwFlags, &strRet)); if (SUCCEEDED(hr)) { COM_VERIFY(StrRetToBuf( &strRet, pItemIdList, pFriendlyName, cchBuf)); } if ( NULL == pSF ) { pShellFolder->Release(); pShellFolder = NULL; } return hr; }
HRESULT GetDisplayName(LPCITEMIDLIST pidlDirectory,TCHAR *szDisplayName,UINT cchMax,DWORD uFlags) { if(pidlDirectory == NULL || szDisplayName == NULL) { return E_FAIL; } IShellFolder *pShellFolder = NULL; LPITEMIDLIST pidlRelative = NULL; STRRET str; HRESULT hr; hr = SHBindToParent(pidlDirectory, IID_PPV_ARGS(&pShellFolder), (LPCITEMIDLIST *)&pidlRelative); if(SUCCEEDED(hr)) { hr = pShellFolder->GetDisplayNameOf(pidlRelative,uFlags,&str); if(SUCCEEDED(hr)) { hr = StrRetToBuf(&str,pidlDirectory,szDisplayName,cchMax); } pShellFolder->Release(); } return hr; }
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(); } }
/* TODO: These groups have changed as of Windows Vista. */ void CShellBrowser::DetermineItemTotalSizeGroup(int iItemInternal,TCHAR *szGroupHeader,int cchMax) const { IShellFolder *pShellFolder = NULL; LPITEMIDLIST pidlComplete = NULL; LPITEMIDLIST pidlDirectory = NULL; LPITEMIDLIST pidlRelative = NULL; TCHAR *SizeGroups[] = {_T("Unspecified"),_T("Small"),_T("Medium"),_T("Huge"),_T("Gigantic")}; TCHAR szItem[MAX_PATH]; STRRET str; ULARGE_INTEGER nTotalBytes; ULARGE_INTEGER nFreeBytes; BOOL bRoot; BOOL bRes = FALSE; ULARGE_INTEGER TotalSizeGroupLimits[6]; int nGroups = 5; int iSize = 0; int i; TotalSizeGroupLimits[0].QuadPart = 0; TotalSizeGroupLimits[1].QuadPart = 0; TotalSizeGroupLimits[2].QuadPart = GBYTE; TotalSizeGroupLimits[3].QuadPart = 20 * TotalSizeGroupLimits[2].QuadPart; TotalSizeGroupLimits[4].QuadPart = 100 * TotalSizeGroupLimits[2].QuadPart; GetIdlFromParsingName(m_CurDir,&pidlDirectory); pidlComplete = ILCombine(pidlDirectory,m_pExtraItemInfo[iItemInternal].pridl); SHBindToParent(pidlComplete, IID_PPV_ARGS(&pShellFolder), (LPCITEMIDLIST *) &pidlRelative); pShellFolder->GetDisplayNameOf(pidlRelative,SHGDN_FORPARSING,&str); StrRetToBuf(&str,pidlRelative,szItem,SIZEOF_ARRAY(szItem)); bRoot = PathIsRoot(szItem); if(bRoot) { bRes = GetDiskFreeSpaceEx(szItem,NULL,&nTotalBytes,&nFreeBytes); CoTaskMemFree(pidlDirectory); CoTaskMemFree(pidlComplete); pShellFolder->Release(); i = nGroups - 1; while(nTotalBytes.QuadPart < TotalSizeGroupLimits[i].QuadPart && i > 0) i--; iSize = i; } if(!bRoot || !bRes) { iSize = 0; } StringCchCopy(szGroupHeader,cchMax,SizeGroups[iSize]); }
void CreateLnkOnDesktop(const LPWSTR connTitle) { IShellLink *SLink; IPersistFile *PF; HRESULT HRes; TCHAR desktop_path[MAX_PATH] = TEXT(""); TCHAR pszFullLnkPath[MAX_PATH]; CoInitialize(NULL); ITEMIDLIST* pidl1 = NULL; SHGetFolderLocation(NULL, CSIDL_CONNECTIONS, NULL, 0, &pidl1); IShellFolder *desktop, *ncfolder; SHGetDesktopFolder(&desktop); desktop->BindToObject(pidl1, NULL, IID_IShellFolder, (void**)&ncfolder); IEnumIDList *items; ncfolder->EnumObjects(NULL, SHCONTF_NONFOLDERS, &items); ITEMIDLIST* pidl2 = NULL; while (S_OK == items->Next(1, &pidl2, NULL)) { STRRET sr = {STRRET_WSTR}; ncfolder->GetDisplayNameOf(pidl2, SHGDN_NORMAL, &sr); TCHAR buf[MAX_PATH] = TEXT(""); StrRetToBuf(&sr, pidl2, buf, MAX_PATH); if (0 == StrCmpI(buf, connTitle)) { ITEMIDLIST* pidl3 = ILCombine(pidl1, pidl2); HRESULT HRes = CoCreateInstance(CLSID_ShellLink, 0, CLSCTX_INPROC_SERVER, IID_IShellLink, ( LPVOID*)&SLink); SLink->SetIDList(pidl3); SHGetFolderPath(NULL, CSIDL_DESKTOP, NULL, 0, desktop_path); StringCbPrintf(pszFullLnkPath, MAX_PATH * sizeof(TCHAR), TEXT("%s\\%s.lnk"), desktop_path, connTitle); HRes = SLink->QueryInterface(IID_IPersistFile, (LPVOID*)&PF); HRes = PF->Save((LPCOLESTR)pszFullLnkPath, TRUE); PF->Release(); SLink->Release(); ILFree(pidl3); ILFree(pidl2); break; } ILFree(pidl2); pidl2 = NULL; } ncfolder->Release(); desktop->Release(); ILFree(pidl1); CoUninitialize(); }
////////////////// // Handy function to get the display name from pidl. // CString CFolderDialog::GetDisplayNameOf(IShellFolder* psf, LPCITEMIDLIST pidl, DWORD uFlags) { CString dn; STRRET strret; // special struct for GetDisplayNameOf strret.uType = STRRET_CSTR; // get as CSTR if (SUCCEEDED(psf->GetDisplayNameOf(pidl, uFlags, &strret))) { StrRetToBuf(&strret, pidl, dn.GetBuffer(MAX_PATH), MAX_PATH); dn.ReleaseBuffer(); } return dn; }
/* TODO: Need to sort based on percentage free. */ void CShellBrowser::DetermineItemFreeSpaceGroup(int iItemInternal,TCHAR *szGroupHeader,int cchMax) const { std::list<TypeGroup_t>::iterator itr; LPITEMIDLIST pidlComplete = NULL; LPITEMIDLIST pidlDirectory = NULL; TCHAR szFreeSpace[MAX_PATH]; IShellFolder *pShellFolder = NULL; LPITEMIDLIST pidlRelative = NULL; STRRET str; TCHAR szItem[MAX_PATH]; ULARGE_INTEGER nTotalBytes; ULARGE_INTEGER nFreeBytes; BOOL bRoot; BOOL bRes = FALSE; GetIdlFromParsingName(m_CurDir,&pidlDirectory); pidlComplete = ILCombine(pidlDirectory,m_pExtraItemInfo[iItemInternal].pridl); SHBindToParent(pidlComplete, IID_PPV_ARGS(&pShellFolder), (LPCITEMIDLIST *)&pidlRelative); pShellFolder->GetDisplayNameOf(pidlRelative,SHGDN_FORPARSING,&str); StrRetToBuf(&str,pidlRelative,szItem,SIZEOF_ARRAY(szItem)); CoTaskMemFree(pidlDirectory); CoTaskMemFree(pidlComplete); pShellFolder->Release(); bRoot = PathIsRoot(szItem); if(bRoot) { bRes = GetDiskFreeSpaceEx(szItem,NULL,&nTotalBytes,&nFreeBytes); LARGE_INTEGER lDiv1; LARGE_INTEGER lDiv2; lDiv1.QuadPart = 100; lDiv2.QuadPart = 10; /* Divide by 10 to remove the one's digit, then multiply by 10 so that only the ten's digit rmains. */ StringCchPrintf(szFreeSpace,SIZEOF_ARRAY(szFreeSpace), _T("%I64d%% free"),(((nFreeBytes.QuadPart * lDiv1.QuadPart) / nTotalBytes.QuadPart) / lDiv2.QuadPart) * lDiv2.QuadPart); } if(!bRoot || !bRes) { StringCchCopy(szFreeSpace,SIZEOF_ARRAY(szFreeSpace),_T("Unspecified")); } StringCchCopy(szGroupHeader,cchMax,szFreeSpace); }
//============================================================================= // // IL_GetDisplayName() // // Gets the Display Name of a pidl. lpsf is the parent IShellFolder Interface // dwFlags specify a SHGDN_xx value // BOOL IL_GetDisplayName(LPSHELLFOLDER lpsf, LPCITEMIDLIST pidl, DWORD dwFlags, LPWSTR lpszDisplayName, int nDisplayName) { STRRET str; if (NOERROR == lpsf->lpVtbl->GetDisplayNameOf(lpsf, pidl, dwFlags, &str)) { // Shlwapi.dll provides new function: return StrRetToBuf(&str,pidl,lpszDisplayName,nDisplayName); // ...but I suppose my version is faster ;-) /*switch (str.uType) { case STRRET_WSTR: WideCharToMultiByte(CP_ACP, 0, str.pOleStr, -1, lpszDisplayName, nDisplayName, NULL, NULL); CoTaskMemFree(str.pOleStr); break; case STRRET_OFFSET: lstrcpyn(lpszDisplayName, ((WCHAR *)(pidl)) + str.uOffset, nDisplayName); break; case STRRET_CSTR: lstrcpyn(lpszDisplayName,str.cStr,nDisplayName); break; } return TRUE;*/ } return FALSE; }
bool CDeskBand::CheckDisplayName(IShellFolder * shellFolder, LPITEMIDLIST pidl, LPCTSTR filter, bool bUseRegex) { STRRET str; if (SUCCEEDED(shellFolder->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)); if (bUseRegex) { try { const std::tr1::wregex regCheck(&filter[1], std::tr1::regex_constants::icase | std::tr1::regex_constants::ECMAScript); std::wstring s = dispname; return std::tr1::regex_search(s, regCheck); } catch (std::exception) { } } else { // we now have the display name of the item // i.e. the way the item is shown // since the windows file system is case-insensitive // we have to force the display name to lowercase // so the filter matches case-insensitive too TCHAR * pString = dispname; while (*pString) { *pString = _totlower(*pString); pString++; } // check if the item name matches the text of the edit control return (_tcsstr(dispname, filter) != NULL); } } return false; }
void CShellBrowser::DetermineItemFileSystemGroup(int iItemInternal,TCHAR *szGroupHeader,int cchMax) const { LPITEMIDLIST pidlComplete = NULL; IShellFolder *pShellFolder = NULL; LPITEMIDLIST pidlRelative = NULL; TCHAR szFileSystemName[MAX_PATH]; TCHAR szItem[MAX_PATH]; STRRET str; BOOL bRoot; BOOL bRes; pidlComplete = ILCombine(m_pidlDirectory,m_pExtraItemInfo[iItemInternal].pridl); SHBindToParent(pidlComplete, IID_PPV_ARGS(&pShellFolder), (LPCITEMIDLIST *)&pidlRelative); pShellFolder->GetDisplayNameOf(pidlRelative,SHGDN_FORPARSING,&str); StrRetToBuf(&str,pidlRelative,szItem,SIZEOF_ARRAY(szItem)); bRoot = PathIsRoot(szItem); if(bRoot) { bRes = GetVolumeInformation(szItem,NULL,0,NULL,NULL,NULL,szFileSystemName, SIZEOF_ARRAY(szFileSystemName)); if(!bRes || *szFileSystemName == '\0') { /* TODO: Move into string table. */ StringCchCopy(szFileSystemName,SIZEOF_ARRAY(szFileSystemName),_T("Unspecified")); } } else { /* TODO: Move into string table. */ StringCchCopy(szFileSystemName,SIZEOF_ARRAY(szFileSystemName),_T("Unspecified")); } StringCchCopy(szGroupHeader,cchMax,szFileSystemName); pShellFolder->Release(); CoTaskMemFree(pidlComplete); }
void GetExplorerWindows(std::vector<PairHwndPath>& windows, BOOL needPaths) { CComPtr<IShellWindows> psw; if(!psw.Create(CLSID_ShellWindows, CLSCTX_ALL)) return; VARIANT v; V_VT(&v) = VT_I4; CComPtr<IDispatch> pdisp; for(V_I4(&v) = 0; psw->Item(v, &pdisp) == S_OK; V_I4(&v)++) { CComPtr<IWebBrowserApp> pwba; if(!pwba.QueryFrom(pdisp)) continue; PairHwndPath pair; if(!SUCCEEDED(pwba->get_HWND((LONG_PTR*)&pair.hwnd))) continue; pair.path[0] = 0; CComPtr<IServiceProvider> psp; CComPtr<IShellBrowser> psb; CComPtr<IShellView> psv; CComPtr<IFolderView> pfv; CComPtr<IPersistFolder2> ppf2; CComPtr<IShellFolder> psf; LPITEMIDLIST pidlFolder = NULL; LPCITEMIDLIST pidlLast = NULL; STRRET strret; if(needPaths && psp.QueryFrom(pwba) && SUCCEEDED(psp->QueryService(SID_STopLevelBrowser, IID_IShellBrowser, (void**)&psb)) && SUCCEEDED(psb->QueryActiveShellView(&psv)) && pfv.QueryFrom(psv) && SUCCEEDED(pfv->GetFolder(IID_IPersistFolder2, (void**)&ppf2)) && SUCCEEDED(ppf2->GetCurFolder(&pidlFolder)) && !SHGetPathFromIDList(pidlFolder, pair.path) && SUCCEEDED(SHBindToParent(pidlFolder, IID_IShellFolder, (void**)&psf, &pidlLast)) && SUCCEEDED(psf->GetDisplayNameOf(pidlLast, 0x8000, &strret))) { StrRetToBuf(&strret, pidlLast, pair.path, MAX_PATH); } if(pidlFolder != NULL) CoTaskMemFree(pidlFolder); windows.push_back(pair); } }
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(); } }
HRESULT WINAPI SHEmptyRecycleBinW(HWND hwnd, LPCWSTR pszRootPath, DWORD dwFlags) { WCHAR szPath[MAX_PATH] = {0}, szBuffer[MAX_PATH]; DWORD dwSize, dwType, count; LONG ret; IShellFolder *pDesktop, *pRecycleBin; PIDLIST_ABSOLUTE pidlRecycleBin; PITEMID_CHILD pidl; HRESULT hr = S_OK; LPENUMIDLIST penumFiles; STRRET StrRet; TRACE("%p, %s, 0x%08x\n", hwnd, debugstr_w(pszRootPath), dwFlags); if (!(dwFlags & SHERB_NOCONFIRMATION)) { hr = SHGetDesktopFolder(&pDesktop); if (FAILED(hr)) return hr; hr = SHGetFolderLocation(NULL, CSIDL_BITBUCKET, NULL, 0, &pidlRecycleBin); if (FAILED(hr)) { pDesktop->Release(); return hr; } hr = pDesktop->BindToObject(pidlRecycleBin, NULL, IID_PPV_ARG(IShellFolder, &pRecycleBin)); CoTaskMemFree(pidlRecycleBin); pDesktop->Release(); if (FAILED(hr)) return hr; hr = pRecycleBin->EnumObjects(hwnd, SHCONTF_FOLDERS | SHCONTF_NONFOLDERS | SHCONTF_INCLUDEHIDDEN, &penumFiles); if (FAILED(hr)) { pRecycleBin->Release(); return hr; } count = 0; if (hr != S_FALSE) { while (penumFiles->Next(1, &pidl, NULL) == S_OK) { count++; pRecycleBin->GetDisplayNameOf(pidl, SHGDN_NORMAL, &StrRet); StrRetToBuf(&StrRet, pidl, szBuffer, _countof(szBuffer)); CoTaskMemFree(pidl); } penumFiles->Release(); } pRecycleBin->Release(); switch (count) { case 0: /* no files, don't need confirmation */ break; case 1: /* we have only one item inside the bin, so show a message box with its name */ if (ShellMessageBoxW(shell32_hInstance, hwnd, MAKEINTRESOURCEW(IDS_DELETEITEM_TEXT), MAKEINTRESOURCEW(IDS_EMPTY_BITBUCKET), MB_ICONEXCLAMATION | MB_YESNO | MB_DEFBUTTON2, szBuffer) == IDNO) { return S_OK; } break; default: /* we have more than one item, so show a message box with the count of the items */ StringCbPrintfW(szBuffer, sizeof(szBuffer), L"%u", count); if (ShellMessageBoxW(shell32_hInstance, hwnd, MAKEINTRESOURCEW(IDS_DELETEMULTIPLE_TEXT), MAKEINTRESOURCEW(IDS_EMPTY_BITBUCKET), MB_ICONEXCLAMATION | MB_YESNO | MB_DEFBUTTON2, szBuffer) == IDNO) { return S_OK; } break; } } if (dwFlags & SHERB_NOPROGRESSUI) { ret = EmptyRecycleBinW(pszRootPath); } else { /* FIXME * show a progress dialog */ ret = EmptyRecycleBinW(pszRootPath); } if (!ret) return HRESULT_FROM_WIN32(GetLastError()); if (!(dwFlags & SHERB_NOSOUND)) { dwSize = sizeof(szPath); ret = RegGetValueW(HKEY_CURRENT_USER, L"AppEvents\\Schemes\\Apps\\Explorer\\EmptyRecycleBin\\.Current", NULL, RRF_RT_REG_SZ, &dwType, (PVOID)szPath, &dwSize); if (ret != ERROR_SUCCESS) return S_OK; if (dwType != REG_EXPAND_SZ) /* type dismatch */ return S_OK; szPath[(sizeof(szPath)/sizeof(WCHAR))-1] = L'\0'; PlaySoundW(szPath, NULL, SND_FILENAME); } return S_OK; }
/* updates the names of the file-item through its PIDL */ static void update_by_pidl(FileItem* fileitem) { STRRET strret; TCHAR pszName[MAX_PATH]; IShellFolder *pFolder = NULL; if (fileitem == rootitem) pFolder = shl_idesktop; else { ASSERT(fileitem->parent); shl_idesktop->BindToObject(fileitem->parent->fullpidl, NULL, IID_IShellFolder, (LPVOID *)&pFolder); } /****************************************/ /* get the file name */ if (pFolder != NULL && pFolder->GetDisplayNameOf(fileitem->pidl, SHGDN_NORMAL | SHGDN_FORPARSING, &strret) == S_OK) { StrRetToBuf(&strret, fileitem->pidl, pszName, MAX_PATH); fileitem->filename = pszName; } else if (shl_idesktop->GetDisplayNameOf(fileitem->fullpidl, SHGDN_NORMAL | SHGDN_FORPARSING, &strret) == S_OK) { StrRetToBuf(&strret, fileitem->fullpidl, pszName, MAX_PATH); fileitem->filename = pszName; } else fileitem->filename = "ERR"; /****************************************/ /* get the name to display */ if (fileitem->isFolder() && pFolder && pFolder->GetDisplayNameOf(fileitem->pidl, SHGDN_INFOLDER, &strret) == S_OK) { StrRetToBuf(&strret, fileitem->pidl, pszName, MAX_PATH); fileitem->displayname = pszName; } else if (fileitem->isFolder() && shl_idesktop->GetDisplayNameOf(fileitem->fullpidl, SHGDN_INFOLDER, &strret) == S_OK) { StrRetToBuf(&strret, fileitem->fullpidl, pszName, MAX_PATH); fileitem->displayname = pszName; } else { fileitem->displayname = base::get_file_name(fileitem->filename); } if (pFolder != NULL && pFolder != shl_idesktop) { pFolder->Release(); } }
// ************************************************************ // Возвращает текущий выбранный каталог в активном Проводнике. // ************************************************************ lem::Path lem::Shell::GetCurrentFolder(void) { #if (defined LEM_MSC && _MSC_VER<1300) || defined LEM_WIN98 lem::Path res; return res; #else TCHAR g_szPath[MAX_PATH]; TCHAR g_szItem[MAX_PATH]; HWND hwndFind = GetForegroundWindow(); #if LEM_DEBUGGING==1 TCHAR wndTitle[261]; GetWindowText( hwndFind, wndTitle, sizeof(wndTitle) ); #endif g_szPath[0] = TEXT('\0'); g_szItem[0] = TEXT('\0'); IShellWindows *psw=NULL; if( SUCCEEDED(CoCreateInstance(CLSID_ShellWindows, NULL, CLSCTX_ALL, IID_IShellWindows, (void**)&psw))) { VARIANT v; V_VT(&v) = VT_I4; IDispatch *pdisp=NULL; BOOL fFound = FALSE; for( V_I4(&v) = 0; !fFound && psw->Item(v, &pdisp) == S_OK; V_I4(&v)++ ) { IWebBrowserApp *pwba=NULL; HRESULT rc = pdisp->QueryInterface(IID_IWebBrowserApp, (void**)&pwba); if( SUCCEEDED(rc) ) { HWND hwndWBA=NULL; rc = pwba->get_HWND((LONG_PTR*)&hwndWBA); if( SUCCEEDED(rc) && hwndWBA == hwndFind ) { fFound = TRUE; IServiceProvider *psp=NULL; if( SUCCEEDED(pwba->QueryInterface(IID_IServiceProvider, (void**)&psp)) ) { IShellBrowser *psb=NULL; if( SUCCEEDED(psp->QueryService(SID_STopLevelBrowser, IID_IShellBrowser, (void**)&psb))) { IShellView *psv=NULL; if( SUCCEEDED(psb->QueryActiveShellView(&psv)) ) { IFolderView *pfv=NULL; if (SUCCEEDED(psv->QueryInterface(IID_IFolderView, (void**)&pfv))) { IPersistFolder2 *ppf2=NULL; if (SUCCEEDED(pfv->GetFolder(IID_IPersistFolder2, (void**)&ppf2))) { LPITEMIDLIST pidlFolder=NULL; if (SUCCEEDED(ppf2->GetCurFolder(&pidlFolder))) { if (!SHGetPathFromIDList(pidlFolder, g_szPath)) { //lstrcpyn(g_szPath, TEXT("<not a directory>"), MAX_PATH); } int iFocus=0; if (SUCCEEDED(pfv->GetFocusedItem(&iFocus))) { LPITEMIDLIST pidlItem=NULL; if (SUCCEEDED(pfv->Item(iFocus, &pidlItem))) { IShellFolder *psf=NULL; if (SUCCEEDED(ppf2->QueryInterface(IID_IShellFolder, (void**)&psf))) { STRRET str; if (SUCCEEDED(psf->GetDisplayNameOf(pidlItem, SHGDN_INFOLDER, &str))) { StrRetToBuf(&str, pidlItem, g_szItem, MAX_PATH); } psf->Release(); } CoTaskMemFree(pidlItem); } } CoTaskMemFree(pidlFolder); } ppf2->Release(); } pfv->Release(); } psv->Release(); } psb->Release(); } psp->Release(); } } pwba->Release(); } pdisp->Release(); } psw->Release(); } lem::Path res(g_szPath); return res; #endif }
void CShellBrowser::OnFileActionAdded(const TCHAR *szFileName) { IShellFolder *pShellFolder = NULL; LPITEMIDLIST pidlFull = NULL; LPITEMIDLIST pidlRelative = NULL; Added_t Added; TCHAR FullFileName[MAX_PATH]; TCHAR szDisplayName[MAX_PATH]; STRRET str; BOOL bFileAdded = FALSE; HRESULT hr; StringCchCopy(FullFileName,SIZEOF_ARRAY(FullFileName),m_CurDir); PathAppend(FullFileName,szFileName); hr = GetIdlFromParsingName(FullFileName,&pidlFull); /* It is possible that by the time a file is registered here, it will have already been renamed. In this the following check will fail. If the file is not added, store its filename. */ if(SUCCEEDED(hr)) { hr = SHBindToParent(pidlFull, IID_PPV_ARGS(&pShellFolder), (LPCITEMIDLIST *)&pidlRelative); if(SUCCEEDED(hr)) { /* 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. */ if(m_bVirtualFolder) hr = pShellFolder->GetDisplayNameOf(pidlRelative,SHGDN_INFOLDER,&str); else hr = pShellFolder->GetDisplayNameOf(pidlRelative,SHGDN_INFOLDER|SHGDN_FORPARSING,&str); if(SUCCEEDED(hr)) { StrRetToBuf(&str,pidlRelative,szDisplayName,SIZEOF_ARRAY(szDisplayName)); std::list<DroppedFile_t>::iterator itr; BOOL bDropped = FALSE; if(!m_DroppedFileNameList.empty()) { for(itr = m_DroppedFileNameList.begin();itr != m_DroppedFileNameList.end();itr++) { if(lstrcmp(szDisplayName,itr->szFileName) == 0) { bDropped = TRUE; break; } } } /* Only insert the item in its sorted position if it wasn't dropped in. */ if(m_bInsertSorted && !bDropped) { int iItemId; int iSorted; iItemId = SetItemInformation(m_pidlDirectory,pidlRelative,szDisplayName); iSorted = DetermineItemSortedPosition(iItemId); AddItemInternal(iSorted,iItemId,TRUE); } else { /* Just add the item to the end of the list. */ AddItemInternal(m_pidlDirectory,pidlRelative,szDisplayName,-1,FALSE); } InsertAwaitingItems(m_bShowInGroups); bFileAdded = TRUE; } pShellFolder->Release(); } CoTaskMemFree(pidlFull); } if(!bFileAdded) { /* The file does not exist. However, it is possible that is was simply renamed shortly after been created. Record the filename temporarily (so that it can later be added). */ StringCchCopy(Added.szFileName,SIZEOF_ARRAY(Added.szFileName),szFileName); m_FilesAdded.push_back(Added); } }
static base::string get_key_for_pidl(LPITEMIDLIST pidl) { #if 0 char *key = base_malloc(get_pidl_size(pidl)+1); UINT c, i = 0; while (pidl) { for (c=0; c<pidl->mkid.cb; ++c) { if (pidl->mkid.abID[c]) key[i++] = pidl->mkid.abID[c]; else key[i++] = 1; } pidl = get_next_pidl(pidl); } key[i] = 0; return key; #else STRRET strret; TCHAR pszName[MAX_PATH]; char key[4096]; int len; ustrcpy(key, empty_string); // Go pidl by pidl from the fullpidl to the root (desktop) //PRINTF("FS: ***\n"); pidl = clone_pidl(pidl); while (pidl->mkid.cb > 0) { if (shl_idesktop->GetDisplayNameOf(pidl, SHGDN_INFOLDER | SHGDN_FORPARSING, &strret) == S_OK) { StrRetToBuf(&strret, pidl, pszName, MAX_PATH); //PRINTF("FS: + %s\n", pszName); len = ustrlen(pszName); if (len > 0) { if (*key) { if (pszName[len-1] != '\\') { memmove(key+len+1, key, ustrlen(key)+1); key[len] = '\\'; } else memmove(key+len, key, ustrlen(key)+1); } else key[len] = 0; memcpy(key, pszName, len); } } remove_last_pidl(pidl); } free_pidl(pidl); //PRINTF("FS: =%s\n***\n", key); return key; #endif }
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; }