DWORD Network::GetComputerNameFromIDList(LPITEMIDLIST lpiil,LPSTR szName,DWORD dwBufferLen) { // May be computer? IShellFolder *psf; if (!SUCCEEDED(SHGetDesktopFolder(&psf))) return 0; SHDESCRIPTIONID di; if (!SUCCEEDED(SHGetDataFromIDList(psf,lpiil,SHGDFIL_DESCRIPTIONID,&di,sizeof(SHDESCRIPTIONID)))) { psf->Release(); return 0; } if (di.clsid!=CLSID_NetworkPlaces) { psf->Release(); return 0; } STRRET str; if (!SUCCEEDED(psf->GetDisplayNameOf(lpiil,SHGDN_FORPARSING,&str))) { psf->Release(); return 0; } psf->Release(); if (ShellFunctions::StrRetToStr(str,lpiil,szName,dwBufferLen)) return istrlen(szName); return 0; }
HRESULT Entry::do_context_menu(HWND hwnd, const POINT& pos, CtxMenuInterfaces& cm_ifs) { ShellPath shell_path = create_absolute_pidl(); LPCITEMIDLIST pidl_abs = shell_path; if (!pidl_abs) return S_FALSE; // no action for registry entries, etc. #ifdef USE_MY_SHBINDTOPARENT IShellFolder* parentFolder; LPCITEMIDLIST pidlLast; // get and use the parent folder to display correct context menu in all cases -> correct "Properties" dialog for directories, ... HRESULT hr = my_SHBindToParent(pidl_abs, IID_IShellFolder, (LPVOID*)&parentFolder, &pidlLast); if (SUCCEEDED(hr)) { hr = ShellFolderContextMenu(parentFolder, hwnd, 1, &pidlLast, pos.x, pos.y, cm_ifs); parentFolder->Release(); } return hr; #else static DynamicFct<HRESULT(WINAPI*)(LPCITEMIDLIST, REFIID, LPVOID*, LPCITEMIDLIST*)> SHBindToParent(TEXT("SHELL32"), "SHBindToParent"); if (SHBindToParent) { IShellFolder* parentFolder; LPCITEMIDLIST pidlLast; // get and use the parent folder to display correct context menu in all cases -> correct "Properties" dialog for directories, ... HRESULT hr = (*SHBindToParent)(pidl_abs, IID_IShellFolder, (LPVOID*)&parentFolder, &pidlLast); if (SUCCEEDED(hr)) { hr = ShellFolderContextMenu(parentFolder, hwnd, 1, &pidlLast, pos.x, pos.y, cm_ifs); parentFolder->Release(); } return hr; } else { /**@todo use parent folder instead of desktop folder Entry* dir = _up; ShellPath parent_path; if (dir) parent_path = dir->create_absolute_pidl(); else parent_path = DesktopFolderPath(); ShellPath shell_path = create_relative_pidl(parent_path); LPCITEMIDLIST pidl = shell_path; ShellFolder parent_folder = parent_path; return ShellFolderContextMenu(parent_folder, hwnd, 1, &pidl, pos.x, pos.y); */ return ShellFolderContextMenu(GetDesktopFolder(), hwnd, 1, &pidl_abs, pos.x, pos.y, cm_ifs); } #endif }
void CShellContextMenu::SetObjects(const QStringList &strList) { // free all allocated datas if (m_psfFolder && bDelete) m_psfFolder->Release (); m_psfFolder = NULL; FreePIDLArray (m_pidlArray); m_pidlArray = NULL; // get IShellFolder interface of Desktop (root of shell namespace) IShellFolder * psfDesktop = NULL; SHGetDesktopFolder (&psfDesktop); // needed to obtain full qualified pidl // ParseDisplayName creates a PIDL from a file system path relative to the IShellFolder interface // but since we use the Desktop as our interface and the Desktop is the namespace root // that means that it's a fully qualified PIDL, which is what we need LPITEMIDLIST pidl = NULL; psfDesktop->ParseDisplayName (NULL, 0, (LPOLESTR)strList[0].utf16(), NULL, &pidl, NULL); // now we need the parent IShellFolder interface of pidl, and the relative PIDL to that interface LPITEMIDLIST pidlItem = NULL; // relative pidl SHBindToParentEx (pidl, IID_IShellFolder, (void **) &m_psfFolder, NULL); free (pidlItem); // get interface to IMalloc (need to free the PIDLs allocated by the shell functions) LPMALLOC lpMalloc = NULL; SHGetMalloc (&lpMalloc); lpMalloc->Free (pidl); // now we have the IShellFolder interface to the parent folder specified in the first element in strArray // since we assume that all objects are in the same folder (as it's stated in the MSDN) // we now have the IShellFolder interface to every objects parent folder IShellFolder * psfFolder = NULL; nItems = strList.size (); for (int i = 0; i < nItems; i++) { pidl=0; psfDesktop->ParseDisplayName (NULL, 0, (LPOLESTR)strList[i].utf16(), NULL, &pidl, NULL); if (pidl) { m_pidlArray = (LPITEMIDLIST *) realloc (m_pidlArray, (i + 1) * sizeof (LPITEMIDLIST)); // get relative pidl via SHBindToParent SHBindToParentEx (pidl, IID_IShellFolder, (void **) &psfFolder, (LPCITEMIDLIST *) &pidlItem); m_pidlArray[i] = CopyPIDL (pidlItem); // copy relative pidl to pidlArray free (pidlItem); lpMalloc->Free (pidl); // free pidl allocated by ParseDisplayName psfFolder->Release (); } } lpMalloc->Release (); psfDesktop->Release (); bDelete = TRUE; // indicates that m_psfFolder should be deleted by CShellContextMenu }
void FillItemVector() { // 1. Desktop #ifdef SUPPORT_CURFOLDER_AS_ITEM ShellFolderWithPidl aDesktop; SHGetDesktopFolder(&aDesktop.SF); SHGetSpecialFolderLocation(NULL, CSIDL_DESKTOP, &aDesktop.Pidl); myItems.push_back( aDesktop ); #else myItems.push_back( new ShellFolder(CSIDL_DESKTOP) ); #endif // 2. Others if (myEnumerationPidl->mkid.cb == 0) return; LPCITEMIDLIST aTempPidl = myEnumerationPidl; IShellFolder * aTempSF = 0; SHGetDesktopFolder(&aTempSF); while(aTempPidl != 0) { // the PIDL needs not be destroyed here since ShellFolder will destroy it LPITEMIDLIST aLocalSinglePidl = UtilPidlFunc::Copy<MemoryWriter_Crt>(aTempPidl, aTempPidl->mkid.cb); #ifdef SUPPORT_CURFOLDER_AS_ITEM myItems.push_back( ShellFolderWithPidl(aTempSF, aLocalSinglePidl) ); #else myItems.push_back( new ShellFolder(aLocalSinglePidl, aTempSF) ); #endif // Advance the Shell Folder to the next PIDL IShellFolder * aSF = 0; HRESULT aRes = aTempSF->BindToObject(aLocalSinglePidl, NULL, IID_IShellFolder, (void **) &aSF); if ( FAILED(aRes) || aSF == 0) break; aTempSF->Release(); aTempSF = aSF; // Advance the PIDL aTempPidl = UtilPidlFunc::GetNextItemID(aTempPidl); } aTempSF->Release(); }
HRESULT CContextMenuHelper::SHGetContextMenu(std::vector<LPCTSTR> files) { HRESULT hr; IMalloc *pm = NULL; IShellFolder *pDesktop = NULL; IShellFolder *psf = NULL; LPITEMIDLIST pidl = NULL; WCHAR fwname[MAX_PATH + 1]; if (SUCCEEDED(hr = SHGetMalloc(&pm))) { if (SUCCEEDED(hr = SHGetDesktopFolder(&pDesktop))) { std::vector<LPITEMIDLIST> pidls; IShellFolder* psfFolder = NULL; for (UINT i = 0; SUCCEEDED(hr) && i < files.size(); i++) { LPCTSTR lpszFilePath = files[i]; ULONG cch; ULONG attrs; // Convert to Unicode memset(fwname, L'\0', (MAX_PATH + 1) * sizeof(WCHAR)); MultiByteToWideChar(CP_THREAD_ACP, 0, lpszFilePath, -1, fwname, MAX_PATH); if (SUCCEEDED(hr = pDesktop->ParseDisplayName(m_hWnd, NULL, fwname, &cch, &pidl, &attrs))) { LPITEMIDLIST pidlItem = NULL; if (SUCCEEDED(hr = SHBindToParentEx((LPCITEMIDLIST)pidl, IID_IShellFolder, (void **)&psf, (LPCITEMIDLIST *) &pidlItem, pDesktop, pm))) { pidls.push_back(CopyPIDL(pidlItem, pm)); pm->Free(pidlItem); if (psfFolder == NULL) { // Remember first folder and we wiil show menu for this one // All other folder will be ignored psfFolder = psf; } else { psf->Release(); } } pm->Free(pidl); } } if (SUCCEEDED(hr) && psfFolder != NULL) { hr = psfFolder->GetUIObjectOf(m_hWnd, pidls.size(), const_cast<LPCITEMIDLIST*>(pidls.begin()), IID_IContextMenu, NULL, (void**)&m_lpcm); psfFolder->Release(); } FreeItemIDList(pidls, pm); pDesktop->Release(); } pm->Release(); } return hr; }
LPITEMIDLIST ShellFunctions::GetIDListForParent(LPCSTR lpszFileName) { int temp=LastCharIndex(lpszFileName,'\\'); LPCWSTR szFolder; if (temp==-1) szFolder=alloccopyAtoW(lpszFileName); else szFolder=alloccopyAtoW(lpszFileName,temp+1); LPITEMIDLIST pidl=NULL; IShellFolder *pDesktop; if (FAILED(SHGetDesktopFolder(&pDesktop))) { delete[] szFolder; return NULL; } if (FAILED(pDesktop->ParseDisplayName(NULL,NULL,(LPOLESTR)szFolder,NULL,&pidl,NULL))) { pDesktop->Release(); delete[] szFolder; return NULL; } return pidl; }
HRESULT CFShellUtil::GetItemIDListFromPath(LPCTSTR szFullPath, LPITEMIDLIST* ppidl, IShellFolder* pSF) { HRESULT hr = E_FAIL; IShellFolder* pShellFolder = pSF; if ( pShellFolder == NULL ) { COM_VERIFY(SHGetDesktopFolder( &pShellFolder )); if ( !pShellFolder ) { return hr; } } ULONG chEaten = 0; DWORD dwAttributes = SFGAO_COMPRESSED; OLECHAR olePath[MAX_PATH] = { '\0' }; #ifdef UNICODE StringCchCopy( olePath, MAX_PATH, szFullPath ); #else MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED, szFileName, -1, olePath, MAX_PATH ); #endif //LPWSTR pszNPath = (LPWSTR)conv.TCHAR_TO_UTF16(szFullPath); COM_VERIFY(pShellFolder->ParseDisplayName(NULL, NULL, olePath, &chEaten, ppidl, &dwAttributes)); if ( NULL == pSF ) { pShellFolder->Release(); pShellFolder = NULL; } return hr; }
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 CRecBinViewer::Properties (CSelRowArray &ar) { CShellContextMenu scm; IShellFolder*psfRecycle = NULL; IShellFolder* psfDesktop = NULL; SHGetDesktopFolder (&psfDesktop); LPITEMIDLIST pidl = NULL; SHGetSpecialFolderLocation (NULL, CSIDL_BITBUCKET, &pidl); psfDesktop->BindToObject(pidl, NULL, IID_IShellFolder, (LPVOID *)&psfRecycle); LPITEMIDLIST *pidlArray = (LPITEMIDLIST *) malloc (ar.size () * sizeof (LPITEMIDLIST)); for (int i = 0 ; i < static_cast<int>(ar.size()) ; i++) pidlArray[i] = m_List[ar[i].m_nRow-1].m_PIDL; scm.SetObjects (psfRecycle, pidlArray, ar.size ()); free (pidlArray); psfDesktop->Release (); scm.InvokeCommand (_T("properties")); if (psfRecycle) psfRecycle->Release (); }
static void ShowItemInFolder(const Path& fullPath) { if( !ShellOpenFolderSelectItems ) { ShellExecuteA(NULL, "open", fullPath.c_str(), NULL, NULL, SW_SHOW); return; } IShellFolder* desktop; HRESULT hr = SHGetDesktopFolder(&desktop); if( hr != S_OK ) return; ITEMIDLIST> dir_item; hr = desktop->ParseDisplayName(NULL, NULL, const_cast<wchar_t *>(dir.value().c_str()), NULL, &dir_item, NULL); desktop->Release(); IDLIST_ABSOLUTE abs; if( ShellOpenFolderSelectItems() != S_OK ) { LogError("Could not open and select the items in the shell"); return; } }
void CRecBinViewer::ContextMenu (CView* pView, CSelRowArray &ar, CPoint &pt) { CShellContextMenu scm; IShellFolder*psfRecycle = NULL; IShellFolder* psfDesktop = NULL; SHGetDesktopFolder (&psfDesktop); LPITEMIDLIST pidl = NULL; SHGetSpecialFolderLocation (NULL, CSIDL_BITBUCKET, &pidl); psfDesktop->BindToObject(pidl, NULL, IID_IShellFolder, (LPVOID *)&psfRecycle); LPITEMIDLIST *pidlArray = (LPITEMIDLIST *) malloc (ar.size () * sizeof (LPITEMIDLIST)); for (unsigned int i = 0 ; i < ar.size () ; i++) pidlArray[i] = m_List[ar[i].m_nRow-1].m_PIDL; scm.SetObjects (psfRecycle, pidlArray, ar.size ()); free (pidlArray); psfDesktop->Release (); scm.ShowContextMenu (pView, pt); if (psfRecycle) psfRecycle->Release (); }
HRESULT GetIdlFromParsingName(const TCHAR *szParsingName,LPITEMIDLIST *pidl) { if(szParsingName == NULL || pidl == NULL) { return E_FAIL; } IShellFolder *pDesktopFolder = NULL; HRESULT hr; hr = SHGetDesktopFolder(&pDesktopFolder); if(SUCCEEDED(hr)) { /* For some reason, ParseDisplayName takes a pointer to a non-constant string, so copy the incoming string. */ TCHAR szParsingNameTemp[MAX_PATH]; StringCchCopy(szParsingNameTemp, SIZEOF_ARRAY(szParsingNameTemp), szParsingName); hr = pDesktopFolder->ParseDisplayName(NULL,NULL, szParsingNameTemp,NULL,pidl,NULL); pDesktopFolder->Release(); } return hr; }
//------------------------------------------------------------------------------ // CDevicePropertyPage::GetIconFromItem [STATIC FUNC] // // Gets a handle to the icon of the shell item. phIcon needs to be cleaned // up with DestroyIcon() when done. //------------------------------------------------------------------------------ HRESULT CDevicePropertyPage::GetIconFromItem( __in IShellItem* pShellItem, __in int iImageList, __out HICON* phIcon ) { HRESULT hr = S_OK; int iIcon = 0; PITEMID_CHILD pidl = NULL; IImageList* pImageList = NULL; IParentAndItem* pParentAndItem = NULL; IShellFolder* pShellFolder = NULL; *phIcon = NULL; hr = pShellItem->QueryInterface( &pParentAndItem ); if( S_OK == hr ) { hr = pParentAndItem->GetParentAndItem( NULL, &pShellFolder, &pidl ); } if( S_OK == hr ) { hr = SHGetImageList( iImageList, __uuidof(IImageList), reinterpret_cast<void**>(&pImageList) ); } if( S_OK == hr ) { iIcon = SHMapPIDLToSystemImageListIndex( pShellFolder, pidl, NULL ); hr = pImageList->GetIcon( iIcon, 0, phIcon ); } // // Cleanup // if( NULL != pImageList ) { pImageList->Release(); } if( NULL != pidl ) { ILFree( pidl ); } if( NULL != pShellFolder ) { pShellFolder->Release(); } if( NULL != pParentAndItem ) { pParentAndItem->Release(); } return hr; }// CDevicePropertyPage::GetIconFromItem
void CDropHandler::HandleRightClickDrop(void) { IShellFolder *pDesktop = NULL; IShellFolder *pShellFolder = NULL; IDropTarget *pDrop = NULL; LPITEMIDLIST pidlDirectory = NULL; DWORD dwe; HRESULT hr; hr = GetIdlFromParsingName(m_szDestDirectory,&pidlDirectory); if(SUCCEEDED(hr)) { hr = SHGetDesktopFolder(&pDesktop); if(SUCCEEDED(hr)) { hr = pDesktop->BindToObject(pidlDirectory,0,IID_IShellFolder,(void **)&pShellFolder); if(SUCCEEDED(hr)) { dwe = *m_pdwEffect; hr = pShellFolder->CreateViewObject(m_hwndDrop,IID_IDropTarget,(void **)&pDrop); if(SUCCEEDED(hr)) { pDrop->DragEnter(m_pDataObject,MK_RBUTTON,m_ptl,&dwe); dwe = *m_pdwEffect; pDrop->Drop(m_pDataObject,m_grfKeyState,m_ptl,&dwe); pDrop->DragLeave(); pDrop->Release(); } pShellFolder->Release(); } pDesktop->Release(); } CoTaskMemFree(pidlDirectory); } }
/* 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 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(); } }
stdstring ItemIDList::toString() { IShellFolder *shellFolder = NULL; IShellFolder *parentFolder = NULL; STRRET name; TCHAR * szDisplayName = NULL; stdstring ret; HRESULT hr; hr = ::SHGetDesktopFolder(&shellFolder); if (!SUCCEEDED(hr)) return ret; if (parent_) { hr = shellFolder->BindToObject(parent_, 0, IID_IShellFolder, (void**) &parentFolder); if (!SUCCEEDED(hr)) parentFolder = shellFolder; } else { parentFolder = shellFolder; } if ((parentFolder != 0)&&(item_ != 0)) { hr = parentFolder->GetDisplayNameOf(item_, SHGDN_NORMAL | SHGDN_FORPARSING, &name); if (!SUCCEEDED(hr)) { parentFolder->Release(); return ret; } hr = StrRetToStr (&name, item_, &szDisplayName); if (!SUCCEEDED(hr)) return ret; } parentFolder->Release(); if (szDisplayName == NULL) { CoTaskMemFree(szDisplayName); return ret; //to avoid a crash! } ret = szDisplayName; CoTaskMemFree(szDisplayName); return ret; }
/** * 폴더 가져오기 */ BOOL GetFolder(CString* strSelectedFolder, const char* lpszTitle, const HWND hwndOwner, const char* strRootFolder, const char* strStartFolder) { char pszDisplayName[ MAX_PATH ]; LPITEMIDLIST lpID; BROWSEINFOA bi; bi.hwndOwner = hwndOwner; if (strRootFolder == NULL) { bi.pidlRoot = NULL; } else { LPITEMIDLIST pIdl = NULL; IShellFolder* pDesktopFolder; char szPath[ MAX_PATH ]; OLECHAR olePath[ MAX_PATH ]; ULONG chEaten; ULONG dwAttributes; strcpy(szPath, (LPCTSTR)strRootFolder); if (SUCCEEDED (SHGetDesktopFolder (&pDesktopFolder))) { MultiByteToWideChar (CP_ACP, MB_PRECOMPOSED, szPath, -1, olePath, MAX_PATH); pDesktopFolder->ParseDisplayName (NULL, NULL, olePath, &chEaten, &pIdl, &dwAttributes); pDesktopFolder->Release (); } bi.pidlRoot = pIdl; } bi.pszDisplayName = pszDisplayName; bi.lpszTitle = lpszTitle; bi.ulFlags = BIF_RETURNONLYFSDIRS | BIF_STATUSTEXT; bi.lpfn = BrowseCallbackProc; if (strStartFolder == NULL) { bi.lParam = FALSE; } else { strTmpPath.Format ("%s", strStartFolder); bi.lParam = TRUE; } bi.iImage = NULL; lpID = SHBrowseForFolderA(&bi); if (lpID != NULL) { BOOL b = SHGetPathFromIDList (lpID, pszDisplayName); if (b == TRUE) { strSelectedFolder->Format ("%s",pszDisplayName); return TRUE; } } else { strSelectedFolder->Empty (); } return FALSE; }
// this is workaround function for the Shell API Function SHBindToParent // SHBindToParent is not available under Win95/98 HRESULT CShellContextMenu::SHBindToParentEx (LPCITEMIDLIST pidl, REFIID riid, VOID **ppv, LPCITEMIDLIST *ppidlLast) { HRESULT hr = 0; if (!pidl || !ppv) return E_POINTER; int nCount = GetPIDLCount (pidl); if (nCount == 0) // desktop pidl of invalid pidl return E_POINTER; IShellFolder * psfDesktop = NULL; SHGetDesktopFolder (&psfDesktop); if (nCount == 1) // desktop pidl { if ((hr = psfDesktop->QueryInterface(riid, ppv)) == S_OK) { if (ppidlLast) *ppidlLast = CopyPIDL (pidl); } psfDesktop->Release (); return hr; } LPBYTE pRel = GetPIDLPos (pidl, nCount - 1); LPITEMIDLIST pidlParent = NULL; pidlParent = CopyPIDL (pidl, pRel - (LPBYTE) pidl); IShellFolder * psfFolder = NULL; if ((hr = psfDesktop->BindToObject (pidlParent, NULL, __uuidof (psfFolder), (void **) &psfFolder)) != S_OK) { free (pidlParent); psfDesktop->Release (); return hr; } if ((hr = psfFolder->QueryInterface (riid, ppv)) == S_OK) { if (ppidlLast) *ppidlLast = CopyPIDL ((LPCITEMIDLIST) pRel); } free (pidlParent); psfFolder->Release (); psfDesktop->Release (); return hr; }
LPITEMIDLIST ShellFunctions::GetIDList(LPCWSTR lpszFileName) { LPITEMIDLIST pidl=NULL; IShellFolder *pDesktop; if (FAILED(SHGetDesktopFolder(&pDesktop))) return NULL; HRESULT hRes=pDesktop->ParseDisplayName(NULL,NULL,(LPOLESTR)lpszFileName,NULL,&pidl,NULL); pDesktop->Release(); return FAILED(hRes)?NULL:pidl; }
/** * 简单的枚举文件夹内容,返回内容数量 */ int SimpleEnumFolder(LPCTSTR lpszPath // 文件夹路径 , CShellManager* pShellManager // Shell管理器 , function<void(LPITEMIDLIST)> filter) // 过滤器函数 { ENSURE(lpszPath != nullptr); ASSERT_VALID(pShellManager); AFX_SHELLITEMINFO info; HRESULT hr = pShellManager->ItemFromPath(lpszPath, info.pidlRel); if (FAILED(hr)) { return 0; } int nFolderCount = 0; LPSHELLFOLDER pDesktopFolder; hr = SHGetDesktopFolder(&pDesktopFolder); if (SUCCEEDED(hr)) { IShellFolder* psfCurFolder = nullptr; hr = pDesktopFolder->BindToObject(info.pidlRel, nullptr, IID_IShellFolder, (LPVOID*)&psfCurFolder); LPENUMIDLIST pEnum = nullptr; HRESULT hRes = psfCurFolder->EnumObjects(nullptr, (SHCONTF)(SHCONTF_FOLDERS), &pEnum); if (SUCCEEDED(hRes) && pEnum != nullptr) { DWORD dwFetched = 1; LPITEMIDLIST pidlTemp; while (pEnum->Next(1, &pidlTemp, &dwFetched) == S_OK && dwFetched) { if (!filter._Empty()) { LPITEMIDLIST itemID = pShellManager->ConcatenateItem(info.pidlRel, pidlTemp); filter(itemID); pShellManager->FreeItem(itemID); } pShellManager->FreeItem(pidlTemp); nFolderCount++; dwFetched = 0; } pEnum->Release(); } psfCurFolder->Release(); pDesktopFolder->Release(); } pShellManager->FreeItem(info.pidlRel); return nFolderCount; }
/* 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); }
// Retrieves the UIObject interface for the specified full PIDL STDAPI SHGetUIObjectFromFullPIDL(LPITEMIDLIST pidl, HWND hwnd, REFIID riid, void **ppv) { LPCITEMIDLIST pidlChild; IShellFolder* psf; *ppv = NULL; HRESULT hr = SHBindToParent(pidl, IID_IShellFolder, (void**)(&psf), &pidlChild); if (SUCCEEDED(hr)) { hr = psf->GetUIObjectOf(hwnd, 1, &pidlChild, riid, NULL, ppv); psf->Release(); } return hr; }
HRESULT CDropHandler::CopyShellIDListData(IDataObject *pDataObject, list<PastedFile_t> *pPastedFileList) { STGMEDIUM stg; HRESULT hr; hr = pDataObject->GetData(&m_ftcShellIDList,&stg); if(hr == S_OK) { CIDA *pcida = (CIDA *)GlobalLock(stg.hGlobal); if(pcida != NULL) { IShellFolder *pShellFolder = NULL; HRESULT hr; LPCITEMIDLIST pidlDirectory = HIDA_GetPIDLFolder(pcida); hr = BindToShellFolder(pidlDirectory,&pShellFolder); if(SUCCEEDED(hr)) { LPCITEMIDLIST pidlItem = NULL; IStorage *pStorage = NULL; for(unsigned int i = 0;i < pcida->cidl;i++) { pidlItem = HIDA_GetPIDLItem(pcida,i); hr = pShellFolder->BindToStorage(pidlItem,NULL,IID_IStorage,(LPVOID *)&pStorage); if(SUCCEEDED(hr)) { /* TODO: Copy the files. */ pStorage->Release(); } } pShellFolder->Release(); } GlobalUnlock(stg.hGlobal); } ReleaseStgMedium(&stg); } return hr; }
BOOL GetThumbNail(HDC hDC, LPCTSTR lpszFilePath,LPCTSTR lpszSavepath) { bool bFileExit = PathFileExists(lpszSavepath); if(bFileExit) return TRUE; IShellFolder * pShellFolder = NULL; if( SHGetDesktopFolder( &pShellFolder) == S_OK ) { LPITEMIDLIST pidl = NULL; HRESULT hRes = pShellFolder->ParseDisplayName( NULL, NULL, (LPTSTR)(LPCTSTR)lpszFilePath, NULL, &pidl, NULL); if( hRes == S_OK ) { LPCITEMIDLIST pidlLast = NULL; IShellFolder * pParentFolder = NULL; HRESULT hRes = SHBindToParent( pidl, IID_IShellFolder, (void**)&pParentFolder, &pidlLast ); if( hRes == S_OK ) { HBITMAP hBmpImage = ExtractThumb(pParentFolder, pidlLast ); if( hBmpImage ) { SaveImage(hDC,hBmpImage,lpszSavepath); //HBITMAP hbmpOld = hBmpImage; //if( hbmpOld ) // DeleteObject(hbmpOld); } else return false; pParentFolder->Release(); } } pShellFolder->Release(); return true; } return false; }
LPITEMIDLIST ShellFunctions::GetIDList(LPCSTR lpszFileName) { LPITEMIDLIST pidl=NULL; IShellFolder *pDesktop; if (FAILED(SHGetDesktopFolder(&pDesktop))) return NULL; if (FAILED(pDesktop->ParseDisplayName(NULL,NULL,(LPOLESTR)(LPCWSTR)A2W(lpszFileName),NULL,&pidl,NULL))) { pDesktop->Release(); return NULL; } return pidl; }
bool prepareContextMenuForObjects(std::vector<std::wstring> objects, void * parentWindow, HMENU& hmenu, IContextMenu*& imenu) { ComInitializer comInitializer; if (objects.empty()) return false; std::vector<ITEMIDLIST*> ids; std::vector<LPCITEMIDLIST> relativeIds; IShellFolder * ifolder = 0; for (size_t i = 0; i < objects.size(); ++i) { std::replace(objects[i].begin(), objects[i].end(), '/', '\\'); ids.push_back(0); HRESULT result = SHParseDisplayName(objects[i].c_str(), 0, &ids.back(), 0, 0); if (!SUCCEEDED(result) || !ids.back()) { ids.pop_back(); continue; } relativeIds.push_back(0); result = SHBindToParent(ids.back(), IID_IShellFolder, (void**)&ifolder, &relativeIds.back()); if (!SUCCEEDED(result) || !relativeIds.back()) relativeIds.pop_back(); else if (i < objects.size() - 1 && ifolder) { ifolder->Release(); ifolder = nullptr; } } CItemIdArrayReleaser arrayReleaser(ids); assert_r(parentWindow); assert_and_return_message_r(ifolder, "Error getting ifolder", false); assert_and_return_message_r(!relativeIds.empty(), "RelativeIds is empty", false); imenu = 0; HRESULT result = ifolder->GetUIObjectOf((HWND)parentWindow, (UINT)relativeIds.size(), (const ITEMIDLIST **)relativeIds.data(), IID_IContextMenu, 0, (void**)&imenu); if (!SUCCEEDED(result) || !imenu) return false; hmenu = CreatePopupMenu(); if (!hmenu) return false; return (SUCCEEDED(imenu->QueryContextMenu(hmenu, 0, 1, 0x7FFF, CMF_NORMAL))); }
void CFTLComTester::test_SbsCreateInstance() { HRESULT hr = E_FAIL; BOOL bRet = FALSE; TCHAR strPath[MAX_PATH] = {0}; API_VERIFY( 0 != GetWindowsDirectory(strPath,_countof(strPath))); COM_VERIFY(StringCchCat(strPath,_countof(strPath),TEXT("\\System32\\shell32.dll"))); IShellFolder* pShellFolder = NULL; COM_VERIFY(FTL::CFSideBySide::SbsCreateInstance(strPath,CLSID_ShellDesktop,NULL,CLSCTX_INPROC,IID_IShellFolder, (void**)&pShellFolder)); if (SUCCEEDED(hr)) { pShellFolder->Release(); } //SAFE_RELEASE(pShellFolder); }
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); }