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 }
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; } }
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 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; }
/* * Class: sun_awt_shell_Win32ShellFolder2 * Method: parseDisplayName0 * Signature: (JLjava/lang/String;)J */ JNIEXPORT jlong JNICALL Java_sun_awt_shell_Win32ShellFolder2_parseDisplayName0 (JNIEnv* env, jclass cls, jlong jpIShellFolder, jstring jname) { // Get desktop IShellFolder interface IShellFolder* pIShellFolder = (IShellFolder*)jpIShellFolder; if (pIShellFolder == NULL) { JNU_ThrowInternalError(env, "Desktop shell folder missing"); return 0; } // Get relative PIDL for name LPITEMIDLIST pIDL; int nLength = env->GetStringLength(jname); const jchar* strPath = env->GetStringChars(jname, NULL); JNU_CHECK_EXCEPTION_RETURN(env, 0); jchar* wszPath = new jchar[nLength + 1]; wcsncpy(reinterpret_cast<LPWSTR>(wszPath), reinterpret_cast<LPCWSTR>(strPath), nLength); wszPath[nLength] = 0; HRESULT res = pIShellFolder->ParseDisplayName(NULL, NULL, reinterpret_cast<LPWSTR>(wszPath), NULL, &pIDL, NULL); if (res != S_OK) { JNU_ThrowIOException(env, "Could not parse name"); pIDL = 0; } delete[] wszPath; env->ReleaseStringChars(jname, strPath); return (jlong)pIDL; }
/** * 폴더 가져오기 */ 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; }
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; }
/* * Class: sun_awt_shell_Win32ShellFolder * Method: initFile * Signature: (JLjava/lang/String;Z)J */ JNIEXPORT jlong JNICALL Java_sun_awt_shell_Win32ShellFolder_initFile (JNIEnv* env, jobject folder, jlong desktopIShellFolder, jstring absolutePath, jboolean initAttributes) { // Get desktop IShellFolder interface IShellFolder* pDesktop = (IShellFolder*)desktopIShellFolder; if (pDesktop == NULL) { JNU_ThrowInternalError(env, "Desktop shell folder missing"); return 0; } // Get PIDL for file from desktop LPITEMIDLIST pIDL; int nLength = env->GetStringLength(absolutePath); jchar* wszPath = new jchar[nLength + 1]; const jchar* strPath = env->GetStringChars(absolutePath, NULL); wcsncpy(wszPath, strPath, nLength); wszPath[nLength] = 0; HRESULT res = pDesktop->ParseDisplayName(NULL, NULL, const_cast<jchar*>(wszPath), NULL, &pIDL, NULL); if (res != S_OK) { JNU_ThrowIOException(env, "Could not parse file path"); delete[] wszPath; env->ReleaseStringChars(absolutePath, strPath); return 0; } delete[] wszPath; env->ReleaseStringChars(absolutePath, strPath); // Get display name, folder type, and possibly attributes SHFILEINFO fileInfo; UINT flags; if (initAttributes) { flags = SHGFI_ATTRIBUTES | SHGFI_DISPLAYNAME | SHGFI_TYPENAME | SHGFI_PIDL; } else { flags = SHGFI_DISPLAYNAME | SHGFI_TYPENAME | SHGFI_PIDL; } if (fn_SHGetFileInfo((char *)pIDL, 0L, &fileInfo, sizeof(fileInfo), flags) != 0) { if (initAttributes) { env->SetLongField(folder, FID_attributes, (jlong)fileInfo.dwAttributes); } env->SetObjectField(folder, FID_displayName, JNU_NewStringPlatform(env, fileInfo.szDisplayName)); env->SetObjectField(folder, FID_folderType, JNU_NewStringPlatform(env, fileInfo.szTypeName)); } return (jlong)pIDL; }
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::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; }
// Use the IShellFolder API to get the connection name for the given Guid. static HRESULT lana_ShellGetNameFromGuidW(WCHAR *wGuid, WCHAR *wName, int NameSize) { // This is the GUID for the network connections folder. It is constant. // {7007ACC7-3202-11D1-AAD2-00805FC1270E} const GUID CLSID_NetworkConnections = { 0x7007ACC7, 0x3202, 0x11D1, { 0xAA, 0xD2, 0x00, 0x80, 0x5F, 0xC1, 0x27, 0x0E } }; LPITEMIDLIST pidl; IShellFolder *pShellFolder; IMalloc *pShellMalloc; // Build the display name in the form "::{GUID}". if (wcslen(wGuid) >= MAX_PATH) return E_INVALIDARG; WCHAR szAdapterGuid[MAX_PATH + 2]; swprintf(szAdapterGuid, L"::%ls", wGuid); // Initialize COM. CoInitialize(NULL); // Get the shell allocator. HRESULT hr = SHGetMalloc(&pShellMalloc); if (SUCCEEDED(hr)) { // Create an instance of the network connections folder. hr = CoCreateInstance(CLSID_NetworkConnections, NULL, CLSCTX_INPROC_SERVER, IID_IShellFolder, reinterpret_cast<LPVOID *>(&pShellFolder)); } if (SUCCEEDED(hr)) { hr = pShellFolder->ParseDisplayName(NULL, NULL, szAdapterGuid, NULL, &pidl, NULL); } if (SUCCEEDED(hr)) { // Get the display name; this returns the friendly name. STRRET sName; hr = pShellFolder->GetDisplayNameOf(pidl, SHGDN_NORMAL, &sName); if (SUCCEEDED(hr)) wcsncpy(wName, sName.pOleStr, NameSize); pShellMalloc->Free(pidl); } CoUninitialize(); return hr; }
// // NB: This function leaks memory/references. // EXTERN_C void RenameAdapter(const GUID *AdapterGuid, const WCHAR *NewName) { HRESULT hr; IShellFolder *pShellFolder; hr = CoCreateInstance(CLSID_NetworkConnections, NULL, CLSCTX_INPROC_SERVER, IID_IShellFolder, reinterpret_cast<LPVOID *>(&pShellFolder)); if (FAILED(hr)) { fprintf(stderr, "mcl: RenameAdapter: CoCreateInstance: %x\n", hr); return; } LPOLESTR szClsId; hr = StringFromCLSID(*AdapterGuid, &szClsId); if (FAILED(hr)) { fprintf(stderr, "mcl: RenameAdapter: StringFromCLSID: %x\n", hr); return; } WCHAR szAdapterGuid[MAX_PATH]; swprintf(szAdapterGuid, L"::%s", szClsId); LPITEMIDLIST pidl; hr = pShellFolder->ParseDisplayName(NULL, NULL, szAdapterGuid, NULL, &pidl, NULL); if (FAILED(hr)) { fprintf(stderr, "mcl: RenameAdapter: ParseDisplayName: %x\n", hr); return; } hr = pShellFolder->SetNameOf(NULL, pidl, NewName, SHGDN_NORMAL, &pidl); if (FAILED(hr)) { fprintf(stderr, "mcl: RenameAdapter: SetNameOf: %x\n", hr); return; } }
BOOL CFolderDialog::SetRootFolder(IN LPCTSTR pszPath) { ASSERT_VALID(this); if (!pszPath) { SAFE_COTASKMEMFREE(m_bi.pidlRoot); return TRUE; } ASSERT(AfxIsValidString(pszPath, MAX_PATH)); HRESULT hResult = S_FALSE; IShellFolder* pDeskFolder = NULL; hResult = ::SHGetDesktopFolder(&pDeskFolder); if (hResult == S_OK) { LPITEMIDLIST pidlRoot = NULL; LPTSTR pszRoot = const_cast< LPTSTR >(pszPath); // Convert the path to an ITEMIDLIST: USES_CONVERSION; hResult = pDeskFolder->ParseDisplayName( NULL, NULL, T2W(pszRoot), NULL, &pidlRoot, NULL ); if (hResult == S_OK) { SAFE_COTASKMEMFREE(m_bi.pidlRoot); m_bi.pidlRoot = pidlRoot; } SAFE_RELEASE(pDeskFolder); } return (hResult == S_OK); }
BOOL CFolderDialog::SetRootFolder( IN LPCTSTR pszPath ) { ASSERT_VALID( this ); if( pszPath == NULL ) { _coTaskMemFree( m_bi.pidlRoot ); return ( TRUE ); } ASSERT( AfxIsValidString( pszPath, MAX_PATH ) ); HRESULT hResult = S_FALSE; IShellFolder* pDeskFolder = NULL; if ( ( hResult = ::SHGetDesktopFolder( &pDeskFolder ) ) == S_OK ) { LPITEMIDLIST pidlRoot = NULL; LPTSTR pszRoot = const_cast< LPTSTR >( pszPath ); // Convert the path to an ITEMIDLIST: USES_CONVERSION; hResult = pDeskFolder->ParseDisplayName( NULL, NULL, T2W( pszRoot ), NULL, &pidlRoot, NULL ); if ( hResult == S_OK ) { _coTaskMemFree( m_bi.pidlRoot ); m_bi.pidlRoot = pidlRoot; } _releaseInterface( pDeskFolder ); } return ( hResult == S_OK ); }
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; }
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; }
void CShellContextMenu::SetPath(const tstring& strPath) { // 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); // 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)const_cast<TCHAR*>(strPath.c_str()), NULL, &pidl, NULL); // now we need the parent IShellFolder interface of pidl, and the relative PIDL to that interface typedef HRESULT (CALLBACK* LPFUNC)(LPCITEMIDLIST pidl, REFIID riid, void **ppv, LPCITEMIDLIST *ppidlLast); LPFUNC MySHBindToParent = (LPFUNC)GetProcAddress(LoadLibrary(_T("shell32")), "SHBindToParent"); if(MySHBindToParent == NULL) return; MySHBindToParent(pidl, IID_IShellFolder, (LPVOID*)&m_psfFolder, NULL); // get interface to IMalloc (need to free the PIDLs allocated by the shell functions) LPMALLOC lpMalloc = NULL; SHGetMalloc(&lpMalloc); lpMalloc->Free(pidl); // now we need the relative pidl IShellFolder* psfFolder = NULL; HRESULT res = psfDesktop->ParseDisplayName (NULL, 0, (LPOLESTR)const_cast<TCHAR*>(strPath.c_str()), NULL, &pidl, NULL); if(res != S_OK) return; LPITEMIDLIST pidlItem = NULL; SHBindToParent(pidl, IID_IShellFolder, (LPVOID*)&psfFolder, (LPCITEMIDLIST*)&pidlItem); // copy pidlItem to m_pidlArray m_pidlArray = (LPITEMIDLIST *) realloc(m_pidlArray, sizeof (LPITEMIDLIST)); int nSize = 0; LPITEMIDLIST pidlTemp = pidlItem; if(pidlTemp) //[+]PPA http://iceberg.leschat.net/forum/index.php?s=&showtopic=265&view=findpost&p=26331 while(pidlTemp->mkid.cb) { nSize += pidlTemp->mkid.cb; pidlTemp = (LPITEMIDLIST) (((LPBYTE) pidlTemp) + pidlTemp->mkid.cb); } LPITEMIDLIST pidlRet = (LPITEMIDLIST) calloc(nSize + sizeof (USHORT), sizeof (BYTE)); CopyMemory(pidlRet, pidlItem, nSize); m_pidlArray[0] = pidlRet; //free(pidlItem); lpMalloc->Free(pidl); lpMalloc->Release(); if(psfFolder) //[+]PPA http://iceberg.leschat.net/forum/index.php?showtopic=265&st=2320&# psfFolder->Release(); psfDesktop->Release(); bDelete = true; // indicates that m_psfFolder should be deleted by CShellContextMenu }
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; }
void CShellContextMenu::SetObjects(CString &strArray) { // 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; #ifndef _UNICODE OLECHAR * olePath = (OLECHAR *) calloc (strArray.GetLength () + 1, sizeof (OLECHAR)); MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, (LPCSTR)strArray, -1, olePath, strArray.GetLength () + 1); psfDesktop->ParseDisplayName (NULL, 0, olePath, NULL, &pidl, NULL); free (olePath); #else psfDesktop->ParseDisplayName (NULL, 0, strArray.GetBuffer (0), NULL, &pidl, NULL); #endif // 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 = 1; for (int i = 0; i < nItems; i++) { #ifndef _UNICODE olePath = (OLECHAR *) calloc (strArray.GetLength () + 1, sizeof (OLECHAR)); MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, (strArray), -1, olePath, strArray.GetLength () + 1); psfDesktop->ParseDisplayName (NULL, 0, olePath, NULL, &pidl, NULL); free (olePath); #else psfDesktop->ParseDisplayName (NULL, 0, strArray.GetBuffer (0), NULL, &pidl, NULL); #endif 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 }
bool CFileTreeCtrl::setRootDirectory (const char *dir) { // Save the string _RootDirectory = dir; if (!_RootDirectory.empty ()) { // Is a window ? if (IsWindow (m_hWnd)) { // Clrear the tree _TreeCtrl.DeleteAllItems (); IShellFolder* pDesktop; ITEMIDLIST* pidl; ITEMIDLIST* pidlDir; TV_ITEM tvItem={0}; TV_INSERTSTRUCT tvInsert={0}; // Create tmp image list CImageList *imageList = CImageList::FromHandle( _ImageListSmall ); _TreeCtrl.SetImageList( imageList, TVSIL_NORMAL); if(SUCCEEDED(SHGetSpecialFolderLocation(NULL, CSIDL_DESKTOP, &pidl))) { if(FAILED(SHGetDesktopFolder(&pDesktop))) { //TODO: free the pidl through IMalloc return false; } CTreeItemInfo* pItemInfo = new CTreeItemInfo; if(pItemInfo == NULL) { //TODO: free the pidl through IMalloc pDesktop->Release(); return false; } // String null ? if (_RootDirectory == "") { pidlDir = pidl; } else { OLECHAR olePath[MAX_PATH]; ULONG chEaten; ULONG dwAttributes; HRESULT hr; // IShellFolder::ParseDisplayName requires the file name be in // Unicode. MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, _RootDirectory.c_str(), -1, olePath, MAX_PATH); // Convert the path to an ITEMIDLIST. hr = pDesktop->ParseDisplayName(m_hWnd, NULL, olePath, &chEaten, &pidlDir, &dwAttributes); if (FAILED(hr)) { return false; } } pItemInfo->pidlSelf = pidlDir; pItemInfo->pidlFullyQual = pidlDir; tvItem.mask = TVIF_PARAM | TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_CHILDREN; tvItem.lParam= (LPARAM)pItemInfo; tvItem.pszText = LPSTR_TEXTCALLBACK; tvItem.iImage = tvItem.iSelectedImage = I_IMAGECALLBACK; tvItem.cChildren = TRUE; tvInsert.item = tvItem; tvInsert.hInsertAfter = TVI_LAST; HTREEITEM hItem = _TreeCtrl.InsertItem(&tvInsert); _TreeCtrl.SelectItem (hItem); _TreeCtrl.Expand (hItem, TVE_EXPAND); pDesktop->Release(); return true; } } } return false; }
IShellFolder* ShellFolderPidlsFromFileSpec (char* pszRelSpec, PidlVector& pidls) { char* pszFullSpec; IShellFolder* psfParent = NULL; LPITEMIDLIST pidlRel; BOOL success = FALSE; // build fully qualified path name pszFullSpec = _fullpath (NULL, pszRelSpec, 0); if (pszFullSpec == NULL) return FALSE; // make copy to expand wildcards in char szExpandedPath[MAX_PATH]; lstrcpy (szExpandedPath, pszFullSpec); char* pszWildcard = strrchr (szExpandedPath, '\\'); if (pszWildcard) ++pszWildcard; else pszWildcard = szExpandedPath + lstrlen (szExpandedPath); // Problem: // we could be passed a drive, a file, or a group of files (wildcard). // (do we take multiple filenames on command line? if not, should we?) // On drive, findfirstfile will fail, but parsedisplayname will give us a pidl // on normal file, both will succeed // on wildcard, findfirstfile will always succeed, but parsedisplayname will work on 9x and not on NT. // So which do we do first? in NT case, either one failing has to be nonfatal. // And, to make things worse, on Win9x (but not NT), FindFirstFile ("E:\") // will behave as if we'd passed E:\* if E: is a mapped network drive, // so they can't get props for any mapped network drive. Hence the hack strlen // comparison in the initialization of bDone. WIN32_FIND_DATA find; HANDLE hFind; hFind = FindFirstFile (pszFullSpec, &find); BOOL bDone = (hFind == INVALID_HANDLE_VALUE) || (lstrlen (pszFullSpec) <= 3); // expand wildcards -- get all files matching spec while (!bDone) { // build psfParent from the first full filename if (!psfParent) { lstrcpy (pszWildcard, find.cFileName); GetPidlAndShellFolder (szExpandedPath, &psfParent, &pidlRel); } // then use psfParent to pidl-ize them if (psfParent) { LPITEMIDLIST pidl; ULONG cch; WCHAR wszFile[MAX_PATH]; mbstowcs (wszFile, find.cFileName, 1+lstrlen(find.cFileName)); //TODO -- could optionally mask hidden, system, etc. files here if (SUCCEEDED (psfParent->ParseDisplayName (NULL, NULL, wszFile, &cch, &pidl, NULL))) pidls.push_back (pidl); } bDone = !(FindNextFile (hFind, &find)); } FindClose (hFind); // if we didn't get anything from FindFirstFile, maybe it's a drive letter... if (pidls.size() == 0) { if (!psfParent) GetPidlAndShellFolder (pszFullSpec, &psfParent, &pidlRel); if (psfParent) { // we were able to find a pidl directly from the given path, // but not from FindFirstFile. This is what happens when the // path is, i.e., a drive (C:\) // so just use the first pidl we got. pidls.push_back (pidlRel); } } free (pszFullSpec); return psfParent; }
static BOOL GetPidlAndShellFolder (char* pszPath, IShellFolder** ppsfOut, LPITEMIDLIST* ppidlOut) { IShellFolder * pd = NULL; IMalloc* shMalloc = NULL; LPITEMIDLIST pidlFull = NULL; ULONG cch; ULONG attrs; BOOL success = FALSE; if (!SUCCEEDED (SHGetDesktopFolder (&pd))) goto BailOut; if (!SUCCEEDED (SHGetMalloc (&shMalloc))) goto BailOut; WCHAR wpath[MAX_PATH]; mbstowcs (wpath, pszPath, 1+lstrlen(pszPath)); //get fully-qualified pidl if (!SUCCEEDED (pd->ParseDisplayName (NULL, NULL, wpath, &cch, &pidlFull, &attrs))) goto BailOut; IShellFolder *psfCurr, *psfNext; if (!SUCCEEDED (pd->QueryInterface (IID_IShellFolder, (LPVOID*)&psfCurr))) goto BailOut; //for each pidl component, bind to folder LPITEMIDLIST pidlNext, pidlLast; pidlNext = PidlNext (pidlFull); pidlLast = pidlFull; 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 (psfCurr->BindToObject(pidlLast, NULL, IID_IShellFolder, (LPVOID*)&psfNext))) goto BailOut; pidlNext->mkid.cb = uSave; //restore the chain psfCurr->Release(); //and set up to work with the next-level folder psfCurr = psfNext; pidlLast = pidlNext; pidlNext = PidlNext (pidlNext); //advance to next pidl } success = TRUE; *ppidlOut = CopyPidl (pidlLast, shMalloc); *ppsfOut = psfCurr; BailOut: //cleanup if (pidlFull != NULL && shMalloc != NULL) shMalloc->Free (pidlFull); //other pidl's were only offsets into this, and don't need freeing if (pd != NULL) pd->Release(); if (shMalloc != NULL) shMalloc->Release(); return success; }