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 (); }
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 (); }
/* * Class: sun_awt_shell_Win32ShellFolder2 * Method: initSpecial * Signature: (JI)V */ JNIEXPORT void JNICALL Java_sun_awt_shell_Win32ShellFolder2_initSpecial (JNIEnv* env, jobject folder, jlong desktopIShellFolder, jint folderType) { // Get desktop IShellFolder interface IShellFolder* pDesktop = (IShellFolder*)desktopIShellFolder; if (pDesktop == NULL) { JNU_ThrowInternalError(env, "Desktop shell folder missing"); return; } // Get special folder relative PIDL LPITEMIDLIST relPIDL; HRESULT res = fn_SHGetSpecialFolderLocation(NULL, folderType, &relPIDL); if (res != S_OK) { JNU_ThrowIOException(env, "Could not get shell folder ID list"); return; } // Set field ID for relative PIDL env->CallVoidMethod(folder, MID_relativePIDL, (jlong)relPIDL); // Get special folder IShellFolder interface IShellFolder* pFolder; res = pDesktop->BindToObject(relPIDL, NULL, IID_IShellFolder, (void**)&pFolder); if (res != S_OK) { JNU_ThrowInternalError(env, "Could not bind shell folder to interface"); return; } // Set field ID for pIShellFolder env->CallVoidMethod(folder, MID_pIShellFolder, (jlong)pFolder); }
CString ShellIO::PIDLToString(LPITEMIDLIST pIdl, LPITEMIDLIST pParentIdl, SHGDNF flags) { IShellFolder *desktopFolder; IShellFolder2 *shellFolder = NULL; STRRET strRet; HRESULT hRes; hRes = SHGetDesktopFolder(&desktopFolder); if(FAILED(hRes)) { return L""; } if(pParentIdl) { desktopFolder->BindToObject((PCUIDLIST_RELATIVE)pParentIdl, NULL, IID_IShellFolder, (void**)&shellFolder); } if(shellFolder == NULL) { shellFolder = (IShellFolder2*)desktopFolder; } hRes = shellFolder->GetDisplayNameOf((PCUITEMID_CHILD)pIdl, flags, &strRet); if(FAILED(hRes)) { return L""; } return strRet.pOleStr; }
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(); }
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); } }
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; }
/* * Class: sun_awt_shell_Win32ShellFolder2 * Method: bindToObject * Signature: (JJ)J */ JNIEXPORT jlong JNICALL Java_sun_awt_shell_Win32ShellFolder2_bindToObject (JNIEnv* env, jclass cls, jlong parentIShellFolder, jlong relativePIDL) { IShellFolder* pParent = (IShellFolder*)parentIShellFolder; if (pParent == NULL) { return 0; } LPITEMIDLIST pidl = (LPITEMIDLIST)relativePIDL; if (pidl == NULL) { return 0; } IShellFolder* pFolder; HRESULT hr = pParent->BindToObject(pidl, NULL, IID_IShellFolder, (void**)&pFolder); if (SUCCEEDED (hr)) { return (jlong)pFolder; } return 0; }
PFAVORITELIST CFavoriteEngine::GetAllFavorites(){ if(FAILED(CoInitialize(NULL))) return NULL; HRESULT hRet = ::SHGetMalloc(&m_pMalloc); if(FAILED(hRet)){ m_pMalloc->Release(); return NULL; } LPITEMIDLIST pidl; hRet = ::SHGetSpecialFolderLocation( NULL, CSIDL_FAVORITES, &pidl); if(FAILED(hRet)){ m_pMalloc->Release(); return NULL; } IShellFolder *pShellFolder = NULL; hRet = ::SHGetDesktopFolder (&pShellFolder); if (FAILED (hRet)){ m_pMalloc->Free (pidl); m_pMalloc->Release (); return NULL; } IShellFolder *pFavFolder = NULL; hRet = pShellFolder->BindToObject (pidl, NULL, IID_IShellFolder, reinterpret_cast<void **>(&pFavFolder)); long nItems = 0; IEnumIDList* pItems = NULL; hRet = pFavFolder->EnumObjects(NULL, SHCONTF_FOLDERS|SHCONTF_NONFOLDERS, &pItems); if(m_pFavoListRoot){ CleanUp(); } m_pFavoListRoot = new FAVORITELIST; ZeroMemory(m_pFavoListRoot, sizeof(FAVORITELIST)); PFAVORITELIST pFavoListCur = GetFavorite( pFavFolder, m_pFavoListRoot, pItems); if (NULL != pItems){ pItems->Release(); } m_pMalloc->Free(pidl); m_pMalloc->Release(); return m_pFavoListRoot; }
// 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; }
/* * Class: sun_awt_shell_Win32ShellFolder * Method: bindToObject * Signature: (JJ)J */ JNIEXPORT jlong JNICALL Java_sun_awt_shell_Win32ShellFolder_bindToObject (JNIEnv* env, jobject folder, jlong parentIShellFolder, jlong relativePIDL) { IShellFolder* pParent = (IShellFolder*)parentIShellFolder; if (pParent == NULL) { return 0; } LPITEMIDLIST pidl = (LPITEMIDLIST)relativePIDL; if (pidl == NULL) { return 0; } IShellFolder* pFolder; if (pParent->BindToObject(pidl, NULL, IID_IShellFolder, (void**)&pFolder) != S_OK) { return 0; } return (jlong)pFolder; }
// this is workaround function for the Shell API Function SHBindToParent // SHBindToParent is not available under Win95/98 HRESULT CContextMenuHelper::SHBindToParentEx(LPCITEMIDLIST pidl, REFIID riid, LPVOID *ppv, LPCITEMIDLIST *ppidlLast, IShellFolder *psfDesktop, IMalloc *pm) { HRESULT hr = 0; if (pidl == NULL || ppv == NULL) { return E_POINTER; } IShellFolder *psfFolder = NULL; if (SUCCEEDED(hr == psfDesktop->QueryInterface(riid, (LPVOID*)&psfFolder))) { IShellFolder *psfParent = NULL; // For each pidl component, bind to folder LPITEMIDLIST pidlNext, pidlLast; pidlNext = NEXTPIDL(pidl); pidlLast = (LPITEMIDLIST)pidl; while (pidlNext->mkid.cb != 0) { UINT uSave = pidlNext->mkid.cb; //stop the chain temporarily pidlNext->mkid.cb = 0; //so we can bind to the next folder 1 deeper if (!SUCCEEDED(hr = psfFolder->BindToObject(pidlLast, NULL, riid, (LPVOID*)&psfParent))) { return hr; } pidlNext->mkid.cb = uSave; //restore the chain psfFolder->Release(); //and set up to work with the next-level folder psfFolder = psfParent; pidlLast = pidlNext; pidlNext = NEXTPIDL(pidlNext); //advance to next pidl } if (ppidlLast != NULL) { *ppidlLast = CopyPIDL((LPCITEMIDLIST)pidlLast, pm); } *ppv = psfFolder; } return hr; }
IShellFolder* sh_get_folder_interface(LPCITEMIDLIST pIDFolder) { IShellFolder* pShellFolder = NULL; IShellFolder* pThisFolder = NULL; HRESULT hr; hr = SHGetDesktopFolder(&pShellFolder); if (NOERROR != hr) return NULL; if (NextID(pIDFolder) == pIDFolder) return pShellFolder; hr = pShellFolder->BindToObject( pIDFolder, NULL, IID_IShellFolder, (LPVOID*)&pThisFolder); pShellFolder->Release(); if (NOERROR != hr) return NULL; return pThisFolder; }
void CDisplayWindow::ExtractThumbnailImageInternal(ThumbnailEntry_t *pte) { IExtractImage *pExtractImage = NULL; IShellFolder *pShellDesktop = NULL; IShellFolder *pShellFolder = NULL; LPITEMIDLIST pidlParent = NULL; LPITEMIDLIST pidlFull = NULL; LPITEMIDLIST pridl = NULL; HBITMAP hBitmap; BITMAP bm; RECT rc; SIZE size; TCHAR szImage[MAX_PATH]; DWORD dwPriority; DWORD dwFlags; HRESULT hr; m_bThumbnailExtracted = TRUE; m_bThumbnailExtractionFailed = TRUE; hr = GetIdlFromParsingName(m_ImageFile,&pidlFull); if(SUCCEEDED(hr)) { pidlParent = ILClone(pidlFull); ILRemoveLastID(pidlParent); pridl = ILClone(ILFindLastID(pidlFull)); hr = SHGetDesktopFolder(&pShellDesktop); if(SUCCEEDED(hr)) { hr = pShellDesktop->BindToObject(pidlParent,NULL,IID_IShellFolder,(void **)&pShellFolder); if(SUCCEEDED(hr)) { hr = pShellFolder->GetUIObjectOf(NULL,1,(LPCITEMIDLIST *)&pridl, IID_IExtractImage,NULL,(void **)&pExtractImage); if(SUCCEEDED(hr)) { GetClientRect(m_hDisplayWindow,&rc); /* First, query the thumbnail so that its actual aspect ratio can be calculated. */ dwFlags = IEIFLAG_OFFLINE|IEIFLAG_QUALITY|IEIFLAG_ORIGSIZE; size.cx = GetRectHeight(&rc) - THUMB_HEIGHT_DELTA; size.cy = GetRectHeight(&rc) - THUMB_HEIGHT_DELTA; hr = pExtractImage->GetLocation(szImage,MAX_PATH, &dwPriority,&size,32,&dwFlags); if(SUCCEEDED(hr)) { hr = pExtractImage->Extract(&hBitmap); if(SUCCEEDED(hr)) { /* Get bitmap information (including height and width). */ GetObject(hBitmap,sizeof(BITMAP),&bm); /* Delete the original bitmap. */ DeleteObject(hBitmap); /* ...now query the thumbnail again, this time adjusting the width of the suggested area based on the actual aspect ratio. */ dwFlags = IEIFLAG_OFFLINE|IEIFLAG_QUALITY|IEIFLAG_ASPECT|IEIFLAG_ORIGSIZE; size.cy = GetRectHeight(&rc) - THUMB_HEIGHT_DELTA; size.cx = (LONG)((double)size.cy * ((double)bm.bmWidth / (double)bm.bmHeight)); m_iImageWidth = size.cx; m_iImageHeight = size.cy; pExtractImage->GetLocation(szImage,MAX_PATH, &dwPriority,&size,32,&dwFlags); hr = pExtractImage->Extract(&m_hbmThumbnail); if(SUCCEEDED(hr)) { /* Check first if we've been cancelled. This might happen, for example, if another file is selected while the current thumbnail is been found. */ EnterCriticalSection(&m_csDWThumbnails); if(!pte->bCancelled) { m_bThumbnailExtractionFailed = FALSE; InvalidateRect(m_hDisplayWindow,NULL,FALSE); } LeaveCriticalSection(&m_csDWThumbnails); } else { m_bThumbnailExtractionFailed = TRUE; m_hbmThumbnail = NULL; } } } pExtractImage->Release(); } pShellFolder->Release(); } pShellDesktop->Release(); } CoTaskMemFree(pidlFull); CoTaskMemFree(pidlParent); CoTaskMemFree(pridl); } }
void GetDrives (CDriveArray &array) { array.clear (); IShellFolder *psfDesktop; SHGetDesktopFolder(&psfDesktop); if(psfDesktop == NULL) return; LPITEMIDLIST pidlMyComputer; SHGetSpecialFolderLocation(NULL, CSIDL_DRIVES, &pidlMyComputer); if(pidlMyComputer == NULL) { psfDesktop->Release(); return; } IShellFolder *psfMyComputer; psfDesktop->BindToObject(pidlMyComputer, NULL, IID_IShellFolder, (LPVOID*)&psfMyComputer); if(psfMyComputer) { IEnumIDList* pEnum; if(SUCCEEDED(psfMyComputer->EnumObjects(NULL, SHCONTF_FOLDERS|SHCONTF_INCLUDEHIDDEN, &pEnum))) { ITEMIDLIST* pidl; DWORD dwFetched = 1; TCHAR path[MAX_PATH]; while(SUCCEEDED(pEnum->Next(1, &pidl, &dwFetched)) && dwFetched) { SHFILEINFO sfi; //LPITEMIDLIST pidl_full = Pidl_Concatenate (pidlMyComputer, pidl); LPITEMIDLIST pidl_full = ILCombine (pidlMyComputer, pidl); SHGetPathFromIDList (pidl_full, path); UINT nType = GetDriveType( path); // if( DRIVE_REMOVABLE < nType && nType <= DRIVE_RAMDISK ) if( nType != DRIVE_UNKNOWN && nType != DRIVE_NO_ROOT_DIR ) if(SHGetFileInfo((LPCTSTR)pidl_full, 0, &sfi, sizeof(sfi), SHGFI_PIDL | SHGFI_DISPLAYNAME | SHGFI_TYPENAME | SHGFI_SYSICONINDEX | SHGFI_SMALLICON | SHGFI_LINKOVERLAY)) { CDriveInfo info; info.m_Name = sfi.szDisplayName; info.m_Path = path; info.m_Type = sfi.szTypeName; info.m_nImage = sfi.iIcon; info.m_nType = nType; DWORD SectorsPerCluster; // sectors per cluster DWORD BytesPerSector; // bytes per sector DWORD NumberOfFreeClusters; // free clusters DWORD TotalNumberOfClusters; // total clusters // TRACE (L"%s %s\n", sfi.szDisplayName, path); if (nType != DRIVE_REMOVABLE ) if (GetDiskFreeSpace (path, &SectorsPerCluster, &BytesPerSector, &NumberOfFreeClusters, &TotalNumberOfClusters)) { DWORD BytesPerCluster = BytesPerSector * SectorsPerCluster; info.m_FreeSpace = UInt32x32To64(NumberOfFreeClusters, BytesPerCluster); info.m_TotalSize= UInt32x32To64(TotalNumberOfClusters, BytesPerCluster); } array.push_back (info); } } pEnum->Release (); } psfMyComputer->Release(); } CoTaskMemFree(pidlMyComputer); psfDesktop->Release(); }
BOOL CImageUtility::PrintImage(wchar_t* path, wchar_t* file_name ) { IShellFolder* pDesktop = NULL; HRESULT hr = ::SHGetDesktopFolder( &pDesktop ); if( !SUCCEEDED( hr ) ) return FALSE; LPITEMIDLIST pidl = NULL; hr = pDesktop->ParseDisplayName(NULL, NULL, path, NULL, &pidl, NULL); if( !SUCCEEDED( hr ) ) { pDesktop->Release(); return FALSE; } IShellFolder* pPath = NULL; hr = pDesktop->BindToObject(pidl, NULL, IID_IShellFolder, (void**)(&pPath) ); if( !SUCCEEDED( hr ) ) { pDesktop->Release(); CoTaskMemFree( pidl ); return FALSE; } LPITEMIDLIST pidl2 = NULL; hr = pPath->ParseDisplayName(NULL, NULL, file_name, NULL, &pidl2, NULL); if( !SUCCEEDED( hr ) ) { pDesktop->Release(); CoTaskMemFree( pidl ); pPath->Release(); return FALSE; } IContextMenu* contextMenu_ptr = NULL; hr = pPath->GetUIObjectOf( GetActiveWindow(), 1, (LPCITEMIDLIST*)(&pidl2), IID_IContextMenu, NULL,(void**)(&contextMenu_ptr) ); if( !SUCCEEDED( hr ) ) { pDesktop->Release(); CoTaskMemFree( pidl ); pPath->Release(); CoTaskMemFree( pidl2 ); return FALSE; } HMENU hMenu = CreatePopupMenu(); if( hMenu == NULL ) { pDesktop->Release(); CoTaskMemFree( pidl ); pPath->Release(); CoTaskMemFree( pidl2 ); contextMenu_ptr->Release(); return FALSE; } contextMenu_ptr->QueryContextMenu( hMenu, 0, 1, 0x7FFF, CMF_NORMAL ); CMINVOKECOMMANDINFO cmdInfo; ::memset( &cmdInfo, 0, sizeof(CMINVOKECOMMANDINFO) ); cmdInfo.cbSize = sizeof(CMINVOKECOMMANDINFO); cmdInfo.lpVerb = "print";//"properties";"Print" cmdInfo.nShow = SW_SHOW; cmdInfo.hwnd = GetActiveWindow(); hr = contextMenu_ptr->InvokeCommand( &cmdInfo ); pDesktop->Release(); CoTaskMemFree( pidl ); pPath->Release(); CoTaskMemFree( pidl2 ); contextMenu_ptr->Release(); DestroyMenu( hMenu ); if( SUCCEEDED( hr ) ) return TRUE; else return FALSE; }
/************************************************************************** * IExtractIconW_Constructor */ IExtractIconW* IExtractIconW_Constructor(LPCITEMIDLIST pidl) { CComPtr<IDefaultExtractIconInit> initIcon; IExtractIconW *extractIcon; GUID const * riid; int icon_idx; UINT flags; CHAR sTemp[MAX_PATH]; WCHAR wTemp[MAX_PATH]; LPITEMIDLIST pSimplePidl = ILFindLastID(pidl); HRESULT hr; hr = SHCreateDefaultExtractIcon(IID_PPV_ARG(IDefaultExtractIconInit,&initIcon)); if (FAILED(hr)) return NULL; hr = initIcon->QueryInterface(IID_PPV_ARG(IExtractIconW,&extractIcon)); if (FAILED(hr)) return NULL; if (_ILIsDesktop(pSimplePidl)) { initIcon->SetNormalIcon(swShell32Name, -IDI_SHELL_DESKTOP); } else if ((riid = _ILGetGUIDPointer(pSimplePidl))) { /* my computer and other shell extensions */ static const WCHAR fmt[] = { 'C', 'L', 'S', 'I', 'D', '\\', '{', '%', '0', '8', 'l', 'x', '-', '%', '0', '4', 'x', '-', '%', '0', '4', 'x', '-', '%', '0', '2', 'x', '%', '0', '2', 'x', '-', '%', '0', '2', 'x', '%', '0', '2', 'x', '%', '0', '2', 'x', '%', '0', '2', 'x', '%', '0', '2', 'x', '%', '0', '2', 'x', '}', 0 }; WCHAR xriid[50]; swprintf(xriid, fmt, riid->Data1, riid->Data2, riid->Data3, riid->Data4[0], riid->Data4[1], riid->Data4[2], riid->Data4[3], riid->Data4[4], riid->Data4[5], riid->Data4[6], riid->Data4[7]); const WCHAR* iconname = NULL; if (_ILIsBitBucket(pSimplePidl)) { static const WCHAR szFull[] = {'F','u','l','l',0}; static const WCHAR szEmpty[] = {'E','m','p','t','y',0}; IEnumIDList *EnumIDList = NULL; CoInitialize(NULL); IShellFolder2 *psfRecycleBin = NULL; IShellFolder *psfDesktop = NULL; hr = SHGetDesktopFolder(&psfDesktop); if (SUCCEEDED(hr)) hr = psfDesktop->BindToObject(pSimplePidl, NULL, IID_IShellFolder2, (void**) &psfRecycleBin); if (SUCCEEDED(hr)) hr = psfRecycleBin->EnumObjects(NULL, SHCONTF_FOLDERS | SHCONTF_NONFOLDERS, &EnumIDList); ULONG itemcount; LPITEMIDLIST pidl = NULL; if (SUCCEEDED(hr) && (hr = EnumIDList->Next(1, &pidl, &itemcount)) == S_OK) { CoTaskMemFree(pidl); iconname = szFull; } else { iconname = szEmpty; } if (psfDesktop) psfDesktop->Release(); if (psfRecycleBin) psfRecycleBin->Release(); if (EnumIDList) EnumIDList->Release(); } if (HCR_GetIconW(xriid, wTemp, iconname, MAX_PATH, &icon_idx)) { initIcon->SetNormalIcon(wTemp, icon_idx); } else { if (IsEqualGUID(*riid, CLSID_MyComputer)) initIcon->SetNormalIcon(swShell32Name, -IDI_SHELL_MY_COMPUTER); else if (IsEqualGUID(*riid, CLSID_MyDocuments)) initIcon->SetNormalIcon(swShell32Name, -IDI_SHELL_MY_DOCUMENTS); else if (IsEqualGUID(*riid, CLSID_NetworkPlaces)) initIcon->SetNormalIcon(swShell32Name, -IDI_SHELL_MY_NETWORK_PLACES); else initIcon->SetNormalIcon(swShell32Name, -IDI_SHELL_FOLDER); } } else if (_ILIsDrive (pSimplePidl)) { static const WCHAR drive[] = { 'D', 'r', 'i', 'v', 'e', 0 }; int icon_idx = -1; if (_ILGetDrive(pSimplePidl, sTemp, MAX_PATH)) { switch(GetDriveTypeA(sTemp)) { case DRIVE_REMOVABLE: icon_idx = IDI_SHELL_FLOPPY; break; case DRIVE_CDROM: icon_idx = IDI_SHELL_CDROM; break; case DRIVE_REMOTE: icon_idx = IDI_SHELL_NETDRIVE; break; case DRIVE_RAMDISK: icon_idx = IDI_SHELL_RAMDISK; break; case DRIVE_NO_ROOT_DIR: icon_idx = IDI_SHELL_CDROM; break; } } if (icon_idx != -1) { initIcon->SetNormalIcon(swShell32Name, -icon_idx); } else { if (HCR_GetIconW(drive, wTemp, NULL, MAX_PATH, &icon_idx)) initIcon->SetNormalIcon(wTemp, icon_idx); else initIcon->SetNormalIcon(swShell32Name, -IDI_SHELL_DRIVE); } } else if (_ILIsFolder (pSimplePidl)) { if (SUCCEEDED(getIconLocationForFolder( pidl, 0, wTemp, MAX_PATH, &icon_idx, &flags))) { initIcon->SetNormalIcon(wTemp, icon_idx); // FIXME: if/when getIconLocationForFolder does something for // GIL_FORSHORTCUT, code below should be uncommented. and // the following line removed. initIcon->SetShortcutIcon(wTemp, icon_idx); } if (SUCCEEDED(getIconLocationForFolder( pidl, GIL_DEFAULTICON, wTemp, MAX_PATH, &icon_idx, &flags))) { initIcon->SetDefaultIcon(wTemp, icon_idx); } // if (SUCCEEDED(getIconLocationForFolder( // pidl, GIL_FORSHORTCUT, wTemp, MAX_PATH, // &icon_idx, // &flags))) // { // initIcon->SetShortcutIcon(wTemp, icon_idx); // } if (SUCCEEDED(getIconLocationForFolder( pidl, GIL_OPENICON, wTemp, MAX_PATH, &icon_idx, &flags))) { initIcon->SetOpenIcon(wTemp, icon_idx); } } else { BOOL found = FALSE; if (_ILIsCPanelStruct(pSimplePidl)) { if (SUCCEEDED(CPanel_GetIconLocationW(pSimplePidl, wTemp, MAX_PATH, &icon_idx))) found = TRUE; } else if (_ILGetExtension(pSimplePidl, sTemp, MAX_PATH)) { if (HCR_MapTypeToValueA(sTemp, sTemp, MAX_PATH, TRUE) && HCR_GetIconA(sTemp, sTemp, NULL, MAX_PATH, &icon_idx)) { if (!lstrcmpA("%1", sTemp)) /* icon is in the file */ { SHGetPathFromIDListW(pidl, wTemp); icon_idx = 0; } else { MultiByteToWideChar(CP_ACP, 0, sTemp, -1, wTemp, MAX_PATH); } found = TRUE; } else if (!lstrcmpiA(sTemp, "lnkfile")) { /* extract icon from shell shortcut */ CComPtr<IShellFolder> dsf; CComPtr<IShellLinkW> psl; if (SUCCEEDED(SHGetDesktopFolder(&dsf))) { HRESULT hr = dsf->GetUIObjectOf(NULL, 1, (LPCITEMIDLIST*)&pidl, IID_IShellLinkW, NULL, (LPVOID *)&psl); if (SUCCEEDED(hr)) { hr = psl->GetIconLocation(wTemp, MAX_PATH, &icon_idx); if (SUCCEEDED(hr) && *sTemp) found = TRUE; } } } } if (!found) /* default icon */ initIcon->SetNormalIcon(swShell32Name, 0); else initIcon->SetNormalIcon(wTemp, icon_idx); } return extractIcon; }
BOOL CFileTreeCtrl::OnNotify ( WPARAM wParam, LPARAM lParam, LRESULT* pResult ) { LPNMHDR pnmh = (LPNMHDR) lParam; // Tree ? if (wParam == 0) { switch (pnmh->code) { case TVN_GETDISPINFO: { LPNMTVDISPINFO lpdi = (LPNMTVDISPINFO)pnmh; CTreeItemInfo* pItemInfo = (CTreeItemInfo*)lpdi->item.lParam; SHFILEINFO sfi; if (pItemInfo) { if(lpdi->item.mask & TVIF_TEXT) { if(SHGetFileInfo((LPCTSTR)pItemInfo->pidlFullyQual, 0, &sfi, sizeof(sfi), SHGFI_PIDL | SHGFI_DISPLAYNAME)) lstrcpy(lpdi->item.pszText, sfi.szDisplayName); } if(lpdi->item.mask & TVIF_IMAGE) { if(SHGetFileInfo((LPCTSTR)pItemInfo->pidlFullyQual, 0, &sfi, sizeof(sfi), SHGFI_PIDL | SHGFI_SYSICONINDEX | SHGFI_SMALLICON | SHGFI_LINKOVERLAY)) lpdi->item.iImage = sfi.iIcon; } if(lpdi->item.mask & TVIF_SELECTEDIMAGE) { if(SHGetFileInfo((LPCTSTR)pItemInfo->pidlFullyQual, 0, &sfi, sizeof(sfi), SHGFI_PIDL | SHGFI_SYSICONINDEX | SHGFI_SMALLICON | SHGFI_OPENICON)) lpdi->item.iSelectedImage = sfi.iIcon; } } } break; case TVN_ITEMEXPANDING: { LPNMTREEVIEW pnmtv = (LPNMTREEVIEW)pnmh; IShellFolder *pParentFolder; if(pnmtv->action == TVE_COLLAPSE) _TreeCtrl.Expand(pnmtv->itemNew.hItem, TVE_COLLAPSE | TVE_COLLAPSERESET); else if(pnmtv->action == TVE_EXPAND) { HCURSOR hCursor; TVITEM tvItem = {0}; tvItem.mask = TVIF_PARAM; tvItem.hItem = pnmtv->itemNew.hItem; if(!_TreeCtrl.GetItem(&tvItem)) return FALSE; CTreeItemInfo* pItemInfo = (CTreeItemInfo*)tvItem.lParam; hCursor = SetCursor(LoadCursor(NULL, IDC_WAIT)); if(pItemInfo->pParentFolder == 0) { if(FAILED(SHGetDesktopFolder(&pParentFolder))) return FALSE; if (_RootDirectory != "") { SHGetDesktopFolder(&pParentFolder); if(FAILED(pParentFolder->BindToObject(pItemInfo->pidlSelf, NULL, IID_IShellFolder, (void**)&pParentFolder))) return 0; } } else if(FAILED(pItemInfo->pParentFolder->BindToObject(pItemInfo->pidlSelf, NULL, IID_IShellFolder, (void**)&pParentFolder))) return 0; _TreeCtrl.SetRedraw(FALSE); enumObjects (pnmtv->itemNew.hItem, pParentFolder, pItemInfo->pidlFullyQual); _TreeCtrl.SetRedraw(TRUE); pParentFolder->Release(); SetCursor(hCursor); } } break; case TVN_DELETEITEM: { LPNMTREEVIEW pnmtv = (LPNMTREEVIEW)pnmh; IMalloc* pMalloc; CTreeItemInfo* pItemInfo = (CTreeItemInfo*)pnmtv->itemOld.lParam; if (pItemInfo) { if (SUCCEEDED(SHGetMalloc(&pMalloc))) { if (pItemInfo->dwFlags == 0) { pMalloc->Free(pItemInfo->pidlSelf); pMalloc->Release(); if (pItemInfo->pParentFolder) { pItemInfo->pParentFolder->Release(); pMalloc->Free(pItemInfo->pidlFullyQual); } } } delete pItemInfo; } } break; case NM_RCLICK: { TVHITTESTINFO tvhti; GetCursorPos(&tvhti.pt); ::ScreenToClient(_TreeCtrl, &tvhti.pt); tvhti.flags = LVHT_NOWHERE; TreeView_HitTest(_TreeCtrl, &tvhti); if(TVHT_ONITEM & tvhti.flags) { ::ClientToScreen(_TreeCtrl, &tvhti.pt); doItemMenu(_TreeCtrl, tvhti.hItem , &tvhti.pt); } } break; case NM_DBLCLK: { // Get the item TVHITTESTINFO tvhti; GetCursorPos(&tvhti.pt); ::ScreenToClient(_TreeCtrl, &tvhti.pt); tvhti.flags = LVHT_NOWHERE; TreeView_HitTest(_TreeCtrl, &tvhti); if(TVHT_ONITEM & tvhti.flags) { if (_TreeCtrl.GetRootItem () != tvhti.hItem) { ::ClientToScreen(_TreeCtrl, &tvhti.pt); doClick(_TreeCtrl, tvhti.hItem); } } } break; } } return CWnd::OnNotify ( wParam, lParam, pResult ); }
HRESULT AddContextMenu(WCHAR* file) { HRESULT hr = E_UNEXPECTED; LPVOID lpVoid; HMENU fileMenu = CreatePopupMenu(); IShellFolder* deskFolder = NULL; IShellFolder* appObject = NULL; LPITEMIDLIST pidlLocal = NULL; LPITEMIDLIST pidlRelative = NULL; IContextMenu* contextMenu = NULL; CONTEXTINFO contextInfo; wcscpy(contextInfo.value, file); hr = SHGetDesktopFolder(&deskFolder); if (FAILED(hr)) { return hr; } hr = deskFolder->ParseDisplayName(NULL, NULL, file, NULL, &pidlLocal, NULL); if (FAILED(hr)) { deskFolder->Release(); return hr; } pidlRelative = ILClone(ILFindLastID(pidlLocal)); ILRemoveLastID(pidlLocal); hr = deskFolder->BindToObject(pidlLocal, NULL, IID_IShellFolder, &lpVoid); if (FAILED(hr)) { deskFolder->Release(); ILFree(pidlLocal); return hr; } appObject = reinterpret_cast <IShellFolder*> (lpVoid); deskFolder->Release(); ILFree(pidlLocal); hr = appObject->GetUIObjectOf(NULL, 1, (LPCITEMIDLIST*)&pidlRelative, IID_IContextMenu, NULL, &lpVoid); if (FAILED(hr)) { appObject->Release(); ILFree(pidlRelative); return hr; } contextMenu = reinterpret_cast <IContextMenu*> (lpVoid); ILFree(pidlRelative); appObject->Release(); contextMenu->QueryInterface(IID_IContextMenu2, &lpVoid); if (FAILED(hr)) { contextMenu->Release(); return hr; } contextInfo.ic2 = reinterpret_cast <IContextMenu2*> (lpVoid); contextMenu->Release(); hr = contextInfo.ic2->QueryContextMenu(fileMenu, 0, SYSMENUMIN, SYSMENUMAX, CMF_NORMAL); if (FAILED(hr)) { contextInfo.ic2->Release(); return hr; } if (!ELIsDirectory(file)) { AppendMenu(fileMenu, MF_SEPARATOR, 0x8000, NULL); AppendMenu(fileMenu, MF_STRING, 0x8001, TEXT("Open Folder")); } contextMap.insert(std::pair<HMENU, CONTEXTINFO>(fileMenu, contextInfo)); return hr; }
STDAPI _IEBindToObjectInternal(BOOL fStrictBind, LPCITEMIDLIST pidl, IBindCtx * pbc, REFIID riid, void **ppvOut) { IShellFolder *psfTemp; HRESULT hr; *ppvOut = NULL; BOOL fIsUrlChild = IsURLChild(pidl, TRUE); if (fIsUrlChild || ILIsRooted(pidl)) { hr = _GetRoot(pidl, fIsUrlChild, &psfTemp); if (SUCCEEDED(hr)) { pidl = _ILNext(pidl); if (!ILIsEmpty(pidl)) hr = psfTemp->BindToObject(pidl, pbc, riid, ppvOut); else hr = psfTemp->QueryInterface(riid, ppvOut); psfTemp->Release(); } } else { // non integrated browser mode will succeed on // BindToObject(IID_IShellFolder) even for things that should // fail (files). to avoid the down stream problems caused by this we // filter out things that are not "browseable" up front, // // NOTE: this does not work on simple PIDLs DWORD dwAttribs = SFGAO_FOLDER | SFGAO_BROWSABLE | SFGAO_FILESYSTEM; hr = _IEGetAttributesOf(pidl, &dwAttribs, fStrictBind); if (SUCCEEDED(hr)) { switch (_ShouldDocObjBind(dwAttribs, fStrictBind)) { case SHOULDBIND_DOCOBJ: { // // shortcircuit and bind using our CDocObjectFolder for // files which are BROWSABLE. Without this code, file: // to non-Docobject files (such as multi-media files) // won't do anything. // // is is needed for non integraded browser mode // CDocObjectFolder *pdof = new CDocObjectFolder(); TraceMsg(TF_URLNAMESPACE, "IEBTO(%x) using DocObjectFolder", pidl); if (pdof) { hr = pdof->Initialize(pidl); if (SUCCEEDED(hr)) hr = pdof->QueryInterface(riid, ppvOut); pdof->Release(); } else hr = E_OUTOFMEMORY; } break; case SHOULDBIND_DESKTOP: { // // This is the normal case. We just bind down through the desktop... // TraceMsg(TF_URLNAMESPACE, "IEBTO(%x) using Desktop", pidl); hr = SHGetDesktopFolder(&psfTemp); if (SUCCEEDED(hr)) { // BRYANST: 7/22/97 - NT Bug #188099 // shell32.dll in IE4 SI and only in that version had a bug if pbc was passed // to IShellFolder::BindToObject() (fstreex.c!FSBindToFSFolder), it would fail // to bind to Shell Extensions that extended file system folders, such as: // the history folder, the occache, etc. We work around this by passing a NULL pbc // if the destination is an IE4 shell32.dll and it will go thru FSBindToFSFolder(). if (pbc && ShouldWorkAroundBCBug(pidl)) { pbc = NULL; } hr = psfTemp->BindToObject(pidl, pbc, riid, ppvOut); psfTemp->Release(); } } break; default: hr = E_FAIL; } } } }