bool CXTPShellListCtrlEx::BrowseToFolder(LPCTSTR lpszPath) { XTP_TVITEMDATA lpTVID; LPITEMIDLIST pidl; LPSHELLFOLDER pDesktopFolder; OLECHAR szOleChar[MAX_PATH]; ULONG chEaten; ULONG dwAttributes; HRESULT hr; // Get a pointer to the Desktop's IShellFolder interface. if (SUCCEEDED(::SHGetDesktopFolder(&pDesktopFolder))) { // IShellFolder::ParseDisplayName requires the file name be in // Unicode. #if !defined(_UNICODE) ::MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, lpszPath, -1, szOleChar, MAX_PATH); #else STRCPY_S(szOleChar, MAX_PATH, lpszPath); #endif // Convert the path to an ITEMIDLIST. hr = pDesktopFolder->ParseDisplayName(NULL, NULL, szOleChar, &chEaten, &pidl, &dwAttributes); if (SUCCEEDED(hr)) { IShellFolder *psfMyFolder; lpTVID.lpi = lpTVID.lpifq = pidl; pDesktopFolder->BindToObject(lpTVID.lpifq, NULL, IID_IShellFolder, (LPVOID*)&psfMyFolder); lpTVID.lpsfParent = psfMyFolder; PopulateListView(&lpTVID, lpTVID.lpsfParent); m_strItemPath = lpszPath; pDesktopFolder->Release(); return true; } pDesktopFolder->Release(); } return false; }
LPITEMIDLIST GetFullyQualPidl(LPSHELLFOLDER lpsf, LPITEMIDLIST lpi) { char szBuff[MAX_PATH]; OLECHAR szOleChar[MAX_PATH]; LPSHELLFOLDER lpsfDeskTop; LPITEMIDLIST lpifq; ULONG ulEaten, ulAttribs; HRESULT hr; if( !GetName(lpsf, lpi, SHGDN_FORPARSING, szBuff)) return NULL; hr=SHGetDesktopFolder(&lpsfDeskTop) ; if( FAILED(hr)) return NULL; MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, szBuff, -1, szOleChar, sizeof(szOleChar)) ; hr=lpsfDeskTop->ParseDisplayName(NULL,NULL,szOleChar,&ulEaten,&lpifq,&ulAttribs) ; lpsfDeskTop->Release() ; if( FAILED(hr)) return NULL; return lpifq; }
//*************************************************************************************** HRESULT CBCGPShellList::DisplayFolder (LPCTSTR lpszPath) { if (g_pShellManager == NULL) { ASSERT (FALSE); return E_FAIL; } ASSERT (lpszPath != NULL); ASSERT_VALID (g_pShellManager); BCGCBITEMINFO info; HRESULT hr = g_pShellManager->ItemFromPath (lpszPath, info.pidlRel); if (FAILED (hr)) { return hr; } LPSHELLFOLDER pDesktopFolder; hr = SHGetDesktopFolder(&pDesktopFolder); if (SUCCEEDED (hr)) { info.pParentFolder = pDesktopFolder; info.pidlFQ = info.pidlRel; hr = DisplayFolder (&info); pDesktopFolder->Release(); } g_pShellManager->FreeItem (info.pidlFQ); return hr; }
//Pabs inserted //Parts copied from compiler docs - search for ITEMIDLIST in title in msdn //Adapted from Q132750:"HOWTO: Convert a File Path to an ITEMIDLIST" in the Knowledge Base STDAPI PathsEqual(LPCTSTR p0, LPCTSTR p1) { LPSHELLFOLDER pFolder; HRESULT hr; if (SUCCEEDED(hr = SHGetDesktopFolder(&pFolder))) { LPITEMIDLIST pidl[2] = { NULL, NULL }; ULONG chEaten;//only needed by parse dispname // Convert the paths to ITEMIDLISTs. if (SUCCEEDED(hr = pFolder->ParseDisplayName(NULL, NULL, const_cast<LPOLESTR>(&*static_cast<T2W>(p0)), &chEaten, &pidl[0], NULL)) && SUCCEEDED(hr = pFolder->ParseDisplayName(NULL, NULL, const_cast<LPOLESTR>(&*static_cast<T2W>(p1)), &chEaten, &pidl[1], NULL))) { hr = pFolder->CompareIDs(0, pidl[0], pidl[1]); } //free ITEMIDLISTs IMalloc* pm; SHGetMalloc(&pm); pm->Free(pidl[0]); pm->Free(pidl[1]); pm->Release(); pFolder->Release(); } return hr; }
/* * Get a fully qualified PIDL for a ShellFolder. * * This is a rather roundabout way of doing things (converting to a full * display name and then converting that to a PIDL). However, there doesn't * seem to be a way to just ask a ShellFolder for its fully qualified PIDL. * TODO: see if there's a better way now. * * Pass in the parent ShellFolder and the item's partial PIDL. */ LPITEMIDLIST Pidl::GetFullyQualPidl(LPSHELLFOLDER lpsf, LPITEMIDLIST lpi) { //char szBuff[MAX_PATH]; //OLECHAR szOleChar[MAX_PATH]; CString name; WCHAR pathBuf[MAX_PATH]; LPSHELLFOLDER lpsfDeskTop; LPITEMIDLIST lpifq; ULONG ulAttribs = 0; HRESULT hr; if (!GetName(lpsf, lpi, SHGDN_FORPARSING, &name)) return NULL; hr = SHGetDesktopFolder(&lpsfDeskTop); if (FAILED(hr)) return NULL; //MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, szBuff, -1, // (USHORT *)szOleChar, sizeof(szOleChar)); wcscpy_s(pathBuf, name); hr = lpsfDeskTop->ParseDisplayName(NULL, NULL, pathBuf, NULL, &lpifq, &ulAttribs); lpsfDeskTop->Release(); if (FAILED(hr)) return NULL; return lpifq; }
BOOL CRecBinViewer::GetFolder2 () { BOOL bReturn = FALSE; STRRET strRet; LPSHELLFOLDER pDesktop = NULL; LPITEMIDLIST pidlRecycleBin = NULL; CString dspName; if (NULL != m_pFolder2) { m_pFolder2->Release (); m_pFolder2 = NULL; } if ((SUCCEEDED (SHGetDesktopFolder(&pDesktop))) && (SUCCEEDED (SHGetSpecialFolderLocation (m_hWnd, CSIDL_BITBUCKET, &pidlRecycleBin)))) { if (SUCCEEDED (pDesktop->BindToObject(pidlRecycleBin, NULL, IID_IShellFolder2, (LPVOID *)&m_pFolder2))) { if (S_OK == pDesktop->GetDisplayNameOf (pidlRecycleBin, SHGDN_NORMAL, &strRet)) GetName (strRet, dspName); bReturn = TRUE; } } CoTaskMemFree (pidlRecycleBin); if (NULL != pDesktop) pDesktop->Release(); return bReturn; }
ITEMIDLIST* CUtil::IDListFromPath(LPCTSTR pathName) { LPSHELLFOLDER pDesktopFolder; HRESULT hr = SHGetDesktopFolder(&pDesktopFolder); ITEMIDLIST* pidl=NULL; if (FAILED(hr)) { assert(0); return NULL; } OLECHAR olePath [MAX_PATH]; #ifdef _UNICODE lstrcpy(olePath, pathName); #else MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, lpszPath, -1, pathName, MAX_PATH); #endif ULONG chEaten; ULONG dwAttributes; hr = pDesktopFolder->ParseDisplayName(NULL, NULL, olePath, &chEaten, &pidl, &dwAttributes); pDesktopFolder->Release(); return pidl; }
BOOL sh_get_displayname(LPSHELLFOLDER piFolder, LPCITEMIDLIST pidl, DWORD dwFlags, LPTSTR pszName) { STRRET str; BOOL fDesktop = FALSE; BOOL fSuccess = TRUE; // // Check to see if a parent folder was specified. If not, get a pointer // to the desktop folder. // if (NULL == piFolder) { HRESULT hr = SHGetDesktopFolder(&piFolder); if (FAILED(hr)) return (FALSE); fDesktop = TRUE; } // // Get the display name from the folder. Then do any conversions necessary // depending on the type of string returned. // if (NOERROR == piFolder->GetDisplayNameOf(pidl, dwFlags, &str)) { //StrRetToBufA(&str, pidl, pszName, MAX_PATH); switch (str.uType) { case STRRET_WSTR: WideCharToMultiByte(CP_ACP, 0, str.pOleStr, -1, pszName, MAX_PATH, NULL, NULL); SHMalloc_Free(str.pOleStr); //dbg_printf("WSTR: %s", pszName); break; case STRRET_OFFSET: strcpy(pszName, (LPSTR)pidl + str.uOffset); //dbg_printf("OFFS: %s", pszName); break; case STRRET_CSTR: strcpy(pszName, str.cStr); //dbg_printf("CSTR: %s", pszName); break; default: fSuccess = FALSE; break; } } else { fSuccess = FALSE; } if (fDesktop) piFolder->Release(); return (fSuccess); }
BOOL COXShellNamespaceNavigator:: GetShellFolderFullIDL(CString sFolderFullPath, LPITEMIDLIST* ppidlFull) const { ASSERT(ppidlFull!=NULL); // If lpcsFolderFullPath is NULL then just return the Desktop's IDL which is NULL if(sFolderFullPath.IsEmpty()) { *ppidlFull=NULL; return TRUE; } // First of all get the Desktop's IShellFolder interface. LPSHELLFOLDER lpDesktopFolder; if(FAILED(SHGetDesktopFolder(&lpDesktopFolder))) return FALSE; OLECHAR unicodeFolderPath[MAX_PATH]; #ifndef _UNICODE UTBStr::mbstowcs(unicodeFolderPath,MAX_PATH,sFolderFullPath,MAX_PATH); #else UTBStr::tcscpy(unicodeFolderPath, MAX_PATH, sFolderFullPath); #endif LPITEMIDLIST lpidl; ULONG chEaten; ULONG dwAttributes; HRESULT hResult=lpDesktopFolder-> ParseDisplayName(m_pOwnerWnd!=NULL ? m_pOwnerWnd->GetSafeHwnd() : NULL, NULL,unicodeFolderPath,&chEaten,&lpidl,&dwAttributes); if(FAILED(hResult)) { lpDesktopFolder->Release(); m_pMalloc->Free(lpidl); return FALSE; } *ppidlFull=CopyPIDL(lpidl); lpDesktopFolder->Release(); m_pMalloc->Free(lpidl); return TRUE; }
/** * 简单的枚举文件夹内容,返回内容数量 */ 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; }
//This gets a fully qualified long absolute filename from any other type of file name ON ANY Win32 PLATFORM damn stupid Micro$uck$ & bloody GetLongPathName //It was copied and enhanced from an article by Jeffrey Richter available in the MSDN under "Periodicals\Periodicals 1997\Microsoft Systems Journal\May\Win32 Q & A" (search for GetLongPathName & choose the last entry) STDAPI GetLongPathNameWin32(LPCTSTR lpszShortPath, LPTSTR lpszLongPath) { /*Alternative methods to consider adding here GetLongPathName on Win98/NT5 Recursive FindFirstFile ... FindClose calls Interrupt 21h Function 7160h Minor Code 2h - does exactly what we want - to the damn letter - even resolves SUBST's (or not if you only want the drive letter) - remember those from DOS? - but the MSDN doesn't say anything about whether or not it is supported by WinNT4 (It is only listed in Win95 docs)*/ // Do not attempt to operate in-place if (lpszLongPath == lpszShortPath) return S_FALSE; // Make sure it is an absolute path LPTSTR lpszFilePart = 0; if (GetFullPathName(lpszShortPath, MAX_PATH, lpszLongPath, &lpszFilePart) <= MAX_PATH) { // Get the Desktop's shell folder interface LPSHELLFOLDER psfDesktop = 0; HRESULT hr = SHGetDesktopFolder(&psfDesktop); if (SUCCEEDED(hr)) { // Request an ID list (relative to the desktop) for the short pathname ULONG chEaten = 0; LPITEMIDLIST pidlShellItem = 0; hr = psfDesktop->ParseDisplayName(0, 0, const_cast<LPWSTR>(&*static_cast<T2W>(lpszLongPath)), &chEaten, &pidlShellItem, 0); if (SUCCEEDED(hr)) { // We did get an ID list, convert it to a long pathname SHGetPathFromIDList(pidlShellItem, lpszLongPath); // Free the ID list allocated by ParseDisplayName LPMALLOC pMalloc = NULL; SHGetMalloc(&pMalloc); pMalloc->Free(pidlShellItem); pMalloc->Release(); } psfDesktop->Release(); // Release the desktop's IShellFolder } } else { lstrcpy(lpszLongPath, lpszShortPath); } return S_OK; }
Ztring OpenFolder_Show(void* Handle, const Ztring &Title, const Ztring &Caption) { //Caption Directory_Select_Caption=Caption; if (IsWin9X()) { return Ztring(); //Not supported in Win9X } else { //Values LPMALLOC Malloc; LPSHELLFOLDER ShellFolder; BROWSEINFO BrowseInfo; LPITEMIDLIST ItemIdList; //Initializing the SHBrowseForFolder function if (SHGetMalloc(&Malloc)!=NOERROR) return Ztring(); if (SHGetDesktopFolder(&ShellFolder)!=NOERROR) return Ztring(); ZeroMemory(&BrowseInfo, sizeof(BROWSEINFOW)); BrowseInfo.ulFlags+=BIF_RETURNONLYFSDIRS; BrowseInfo.hwndOwner=(HWND)Handle; BrowseInfo.pszDisplayName=InitDir; BrowseInfo.lpszTitle=Title.c_str(); BrowseInfo.lpfn=ShowOpenFolder_CallbackProc; //Displaying ItemIdList=SHBrowseForFolder(&BrowseInfo); //Releasing ShellFolder->Release(); if (ItemIdList!=NULL) { SHGetPathFromIDList(ItemIdList, InitDir); Malloc->Free(ItemIdList); Malloc->Release(); //The value return InitDir; } else return Ztring(); } }
void CSelectDrivesDlg::OnBnClickedBrowsefolder() { // Buffer, because SHBrowseForFolder() wants a buffer CString sDisplayName, sSelectedFolder = m_folderName; BROWSEINFO bi; ZeroMemory(&bi, sizeof(bi)); // Load a meaningful title for the browse dialog CString title= LoadString(IDS_SELECTFOLDER); bi.hwndOwner= m_hWnd; // Use the CString as buffer (minimum is MAX_PATH as length) bi.pszDisplayName= sDisplayName.GetBuffer(_MAX_PATH); bi.lpszTitle= title; // Set a callback function to pre-select a folder bi.lpfn = BFFCALLBACK(BrowseCallbackProc); bi.lParam = LPARAM(sSelectedFolder.GetBuffer()); // Set the required flags bi.ulFlags= BIF_RETURNONLYFSDIRS | BIF_EDITBOX | BIF_NEWDIALOGSTYLE | BIF_NONEWFOLDERBUTTON; LPITEMIDLIST pidl= SHBrowseForFolder(&bi); // Release the actual buffer sDisplayName.ReleaseBuffer(); sSelectedFolder.ReleaseBuffer(); if (pidl != NULL) { CString sDir; LPSHELLFOLDER pshf; HRESULT hr= SHGetDesktopFolder(&pshf); ASSERT(SUCCEEDED(hr)); STRRET strret; strret.uType= STRRET_CSTR; hr= pshf->GetDisplayNameOf(pidl, SHGDN_FORPARSING, &strret); ASSERT(SUCCEEDED(hr)); sDir= MyStrRetToString(pidl, &strret); CoTaskMemFree(pidl); pshf->Release(); m_folderName= sDir; m_radio= RADIO_AFOLDER; UpdateData(false); UpdateButtons(); } }
HRESULT WINAPI _SHILCreateFromPath(LPCWSTR pszPath, LPITEMIDLIST *ppidl, DWORD *rgflnOut) { if (!pszPath || !ppidl) { return E_INVALIDARG; } LPSHELLFOLDER psf; HRESULT hr = ::SHGetDesktopFolder(&psf); if (hr != NOERROR) { return hr; } ULONG chEaten; LPOLESTR lpszDisplayName = ::StrDupW(pszPath); hr = psf->ParseDisplayName(NULL, NULL, lpszDisplayName, &chEaten, ppidl, rgflnOut); ::LocalFree(lpszDisplayName); psf->Release(); return hr; }
LPITEMIDLIST ConvertPathToLpItemIdList(const TCHAR* pszPath) { LPITEMIDLIST pidl = NULL; LPSHELLFOLDER pDesktopFolder; if (SUCCEEDED(SHGetDesktopFolder(&pDesktopFolder))) { OLECHAR olePath[MAX_PATH]; ULONG chEaten; ULONG dwAttributes; HRESULT hr; _tcscpy_s(olePath, pszPath); hr = pDesktopFolder->ParseDisplayName(NULL, NULL, olePath, &chEaten, &pidl, &dwAttributes); pDesktopFolder->Release(); } return pidl; }
//*************************************************************************************** HRESULT CBCGPShellList::DisplayParentFolder () { ASSERT_VALID (g_pShellManager); HRESULT hr = E_FAIL; if (m_pidlCurFQ == NULL) { return hr; } BCGCBITEMINFO info; int nLevel = g_pShellManager->GetParentItem (m_pidlCurFQ, info.pidlFQ); if (nLevel < 0) { return hr; } if (nLevel == 0) // Desktop { hr = DisplayFolder (&info); } else { LPSHELLFOLDER pDesktopFolder; hr = SHGetDesktopFolder(&pDesktopFolder); if (SUCCEEDED (hr)) { info.pParentFolder = pDesktopFolder; info.pidlRel = info.pidlFQ; hr = DisplayFolder (&info); pDesktopFolder->Release(); } } g_pShellManager->FreeItem (info.pidlFQ); return hr; }
void CBrowseForFolder::GetPidl(CString name, LPITEMIDLIST pidl) { LPSHELLFOLDER pshf; ULONG chEaten; #ifdef _UNICODE OLECHAR* oleRoot = name.GetBuffer(name.GetLength()); #else OLECHAR oleRoot[MAX_PATH]; // convert path to Unicode string MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, name, -1, oleRoot, MAX_PATH); #endif if (SUCCEEDED(SHGetDesktopFolder(&pshf))) { // get pidl pshf->ParseDisplayName(hWndOwner, NULL, oleRoot, &chEaten, &pidl, NULL); } else return; pshf->Release(); }
BOOL BrowseForFolder(HWND hWnd, CString& strTitle, CString& strResult, BOOL bIncludeFiles, _tBrowseCallbackProc pCallback) { BOOL bRet = FALSE; WCHAR szFolder[MAX_PATH * 2]; ZeroMemory(szFolder, sizeof(szFolder)); BROWSEINFO info; LPSHELLFOLDER shell; LPITEMIDLIST FolderID; SHGetDesktopFolder(&shell); info.hwndOwner = hWnd; info.pidlRoot = NULL; info.pszDisplayName = szFolder; info.lpszTitle = strTitle.GetBuffer(MAX_PATH); info.ulFlags = BIF_NEWDIALOGSTYLE; if (bIncludeFiles) info.ulFlags |= BIF_BROWSEINCLUDEFILES | BIF_NONEWFOLDERBUTTON; info.lpfn = pCallback; FolderID = SHBrowseForFolder(&info); if(FolderID != NULL) { if(SHGetPathFromIDList(FolderID, szFolder)) { strResult= szFolder; bRet = TRUE; } } shell->Release(); strTitle.ReleaseBuffer(); return bRet; }
// first called when the mouse enters our target window space STDMETHODIMP CDropTarget::DragEnter(LPDATAOBJECT pDataObject, DWORD grfKeyState, POINTL pt, LPDWORD pdwEffect) { // don't set "*pdwEffect = DROPEFFECT_NONE"; that would adversely affect the drop target BOOL ok = FALSE; AddRef(); if (m_pidl) { LPSHELLFOLDER psfFolder; LPITEMIDLIST pidlItem; LPITEMIDLIST pidlFull; if (sh_get_uiobject(m_pidl, &pidlFull, &pidlItem, &psfFolder, IID_IDropTarget, (void**)&m_pDropTarget)) { HRESULT hr = m_pDropTarget->DragEnter(pDataObject, grfKeyState, pt, pdwEffect); if(SUCCEEDED(hr)) ok = TRUE; } if (psfFolder) psfFolder->Release(); freeIDList(pidlItem); freeIDList(pidlFull); } if(FALSE == ok) *pdwEffect = DROPEFFECT_NONE; // we can't understand this thing m_pDataObject = pDataObject; return S_OK; }
LPITEMIDLIST getAbsolutePidlFromAbsFilePath(LPWSTR path) { LPITEMIDLIST pidl = NULL; LPITEMIDLIST pidlAbsolute = NULL; // namespace extension root (desktop) for parsing path LPSHELLFOLDER psfDesktop = NULL; if (FAILED(SHGetDesktopFolder(&psfDesktop))) return pidl; // parse path for absolute PIDL if (FAILED(psfDesktop->ParseDisplayName(NULL, NULL, path, NULL, &pidl, NULL))) return pidl; // get the absolute pidl, do not need to free pidlTemp pidlAbsolute = ILClone(pidl); // cleanup CoTaskMemFree(pidl); psfDesktop->Release(); return pidlAbsolute; }
// Get long path name from short path name. // assumes that LongPath has enough characters to hold the generated name static bool ShortPathToLongPath (const char *ShortPath, char *LongPath) { // Man, this is a seriously disturbed function. // Win32 could use a GetLongFileName function (NT 5 has one...) LPSHELLFOLDER psfDesktop = NULL; WCHAR szShortPathNameW[MAX_PATH]; // convert path name to wide and copy to local storage ULONG chEaten = 0; LPITEMIDLIST pidlShellItem = NULL; mbstowcs (szShortPathNameW, ShortPath, MAX_PATH); // Get desktop's shell folder interface HRESULT hr = SHGetDesktopFolder (&psfDesktop); // request an ID list (relative to the desktop) for the short pathname hr = psfDesktop->ParseDisplayName (NULL, NULL, szShortPathNameW, &chEaten, &pidlShellItem, NULL); psfDesktop->Release (); // release desktop's IShellFolder if (FAILED (hr)) { return false; } // got an ID list. Convert it to a long pathname SHGetPathFromIDListA (pidlShellItem, LongPath); // Free the ID list allocated by ParseDisplayName LPMALLOC pMalloc = NULL; SHGetMalloc (&pMalloc); pMalloc->Free (pidlShellItem); pMalloc->Release (); return true; }
//初始化浏览器控件(nID为资源文件中树型控件的id) BOOL Init_Browser(HWND hWnd,UINT nID) { HIMAGELIST hImageList; LPSHELLFOLDER lpsf = 0 ; SHFILEINFO sfi; HRESULT hr ; BOOL bOK; memset(szFoldername,0,MAX_PATH); hTreeWnd=GetDlgItem(hWnd,nID); hImageList = (HIMAGELIST)SHGetFileInfo((LPCSTR)"C:\\", 0, &sfi, sizeof(SHFILEINFO), SHGFI_SYSICONINDEX | SHGFI_SMALLICON) ; if(hImageList) TreeView_SetImageList(hTreeWnd,hImageList,0); hr=SHGetDesktopFolder(&lpsf) ; if( SUCCEEDED(hr)) { TreeView_DeleteAllItems(hTreeWnd); FillTreeView(hTreeWnd,lpsf,NULL,TVI_ROOT) ; ExpandTree(); TreeView_SelectItem(hTreeWnd,TreeView_GetRoot(hTreeWnd));//,TVGN_FIRSTVISIBLE); bOK = TRUE; } else bOK = FALSE; if(lpsf) lpsf->Release(); return bOK; }
/* #FN# Populates the tree view control with file list */ void /* #AS# Nothing */ CShellTree:: PopulateTree() { LPSHELLFOLDER lpsf = NULL; LPITEMIDLIST lpi = NULL; HRESULT hr; /* Get a pointer to the desktop folder */ hr = SHGetDesktopFolder( &lpsf ); if( SUCCEEDED(hr) ) { /* Initialize the tree view to be empty */ DeleteAllItems(); /* Fill in the tree view from the root */ FillTreeView( lpsf, NULL, TVI_ROOT ); /* Release the folder pointer */ lpsf->Release(); } TV_SORTCB tvscb; tvscb.hParent = TVI_ROOT; tvscb.lParam = 0; tvscb.lpfnCompare = TreeViewCompareProc; /* Sort the items in the tree view */ SortChildrenCB( &tvscb /*, FALSE*/ ); HTREEITEM hItem = GetRootItem(); Expand( hItem, TVE_EXPAND ); Select( GetRootItem(), TVGN_CARET ); } /* #OF# CShellTree::PopulateTree */
int CDirectoryDlg::DoModal() { LPMALLOC pMalloc; BROWSEINFO bi; LPITEMIDLIST pidl; LPSHELLFOLDER pDesktopFolder; TCHAR szInitialPath[MAX_PATH]; OLECHAR oleInitialPath[MAX_PATH]; ULONG chEaten; ULONG dwAttributes; HRESULT hr; CFileStatus FileStatus; lstrcpy(szInitialPath, m_strInitialDir); /* IMPORTANT NOTE: Do not forget that the path may not be existent, SHBrowseForFolder reacts very vexing to this fact. So assure that the path is valid and exists. */ if(!CFile::GetStatus(m_strInitialDir, FileStatus)) { ::GetCurrentDirectory(MAX_PATH, m_strInitialDir.GetBuffer(MAX_PATH+1)); m_strInitialDir.ReleaseBuffer(); lstrcpy(szInitialPath, m_strInitialDir); } // // Get a pointer to the Desktop's IShellFolder interface. // hr = SHGetDesktopFolder(&pDesktopFolder); if (FAILED(hr)) { UTIL_DisplaySysError(hr, NULL, NULL); return IDABORT; } // // IShellFolder::ParseDisplayName requires the file name be in // Unicode. // MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, szInitialPath, -1, oleInitialPath, MAX_PATH); // // Convert the path to an ITEMIDLIST. // hr = pDesktopFolder->ParseDisplayName(NULL, NULL, oleInitialPath, &chEaten, &pidl, &dwAttributes); //release the desktop folder object pDesktopFolder->Release(); if (FAILED(hr)) { UTIL_DisplaySysError(hr, NULL, NULL); return IDABORT; } // // pidl now contains a pointer to an ITEMIDLIST for .\readme.txt. // This ITEMIDLIST needs to be freed using the IMalloc allocator // returned from SHGetMalloc(). // hr = SHGetMalloc(&pMalloc); if(FAILED(hr)) { UTIL_DisplaySysError(hr, NULL, NULL); return IDABORT; } HWND hWndTop; HWND hWndOwner = CWnd::GetSafeOwner_(NULL, &hWndTop); ZeroMemory(&bi,sizeof(bi)); bi.hwndOwner = hWndOwner; bi.pidlRoot = NULL; bi.pszDisplayName = NULL; bi.lpszTitle = ""; bi.ulFlags = BIF_RETURNONLYFSDIRS | BIF_VALIDATE; bi.lpfn = BrowsePathCallbackProc; bi.lParam = (LPARAM)szInitialPath; pidl = SHBrowseForFolder(&bi); if (hWndTop != NULL) { EnableWindow(hWndTop, TRUE); } if (pidl) { SHGetPathFromIDList(pidl, szInitialPath); pMalloc->Free(pidl); pMalloc->Release(); m_strDirectory = szInitialPath; } if(m_strDirectory.IsEmpty()) { return IDCANCEL; } return IDOK; }
LRESULT WINAPI WMCommandProc(HWND hWnd, UINT id, HWND hwndCtl, UINT codeNotify) { int nIdx = FindControlIdx(id); // Ignore if the dialog is in the process of being created if (g_done || nIdx < 0) return 0; switch (pFields[nIdx].nType) { case FIELD_BROWSEBUTTON: --nIdx; case FIELD_LINK: case FIELD_BUTTON: case FIELD_CHECKBOX: case FIELD_RADIOBUTTON: if (codeNotify != BN_CLICKED) return 0; break; case FIELD_COMBOBOX: case FIELD_LISTBOX: if (codeNotify != LBN_SELCHANGE) // LBN_SELCHANGE == CBN_SELCHANGE return 0; break; default: return 0; } FieldType *pField = pFields + nIdx; char szBrowsePath[MAX_PATH]; switch (pField->nType) { case FIELD_FILEREQUEST: { OPENFILENAME ofn={0,}; ofn.lStructSize = sizeof(ofn); ofn.hwndOwner = hConfigWindow; ofn.lpstrFilter = pField->pszFilter; ofn.lpstrFile = szBrowsePath; ofn.nMaxFile = sizeof(szBrowsePath); ofn.Flags = pField->nFlags & (OFN_OVERWRITEPROMPT | OFN_HIDEREADONLY | OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST | OFN_CREATEPROMPT | OFN_EXPLORER); GetWindowText(pField->hwnd, szBrowsePath, sizeof(szBrowsePath)); tryagain: GetCurrentDirectory(BUFFER_SIZE, szResult); // save working dir if ((pField->nFlags & FLAG_SAVEAS) ? GetSaveFileName(&ofn) : GetOpenFileName(&ofn)) { mySetWindowText(pField->hwnd, szBrowsePath); SetCurrentDirectory(szResult); // restore working dir // OFN_NOCHANGEDIR doesn't always work (see MSDN) break; } else if (szBrowsePath[0] && CommDlgExtendedError() == FNERR_INVALIDFILENAME) { szBrowsePath[0] = '\0'; goto tryagain; } break; } case FIELD_DIRREQUEST: { BROWSEINFO bi; bi.hwndOwner = hConfigWindow; bi.pidlRoot = NULL; bi.pszDisplayName = szBrowsePath; bi.lpszTitle = pField->pszText; #ifndef BIF_NEWDIALOGSTYLE #define BIF_NEWDIALOGSTYLE 0x0040 #endif bi.ulFlags = BIF_STATUSTEXT | BIF_RETURNONLYFSDIRS | BIF_NEWDIALOGSTYLE; bi.lpfn = BrowseCallbackProc; bi.lParam = nIdx; bi.iImage = 0; if (pField->pszRoot) { LPSHELLFOLDER sf; ULONG eaten; LPITEMIDLIST root; int ccRoot = (lstrlen(pField->pszRoot) * 2) + 2; LPWSTR pwszRoot = (LPWSTR) MALLOC(ccRoot); MultiByteToWideChar(CP_ACP, 0, pField->pszRoot, -1, pwszRoot, ccRoot); SHGetDesktopFolder(&sf); sf->ParseDisplayName(hConfigWindow, NULL, pwszRoot, &eaten, &root, NULL); bi.pidlRoot = root; sf->Release(); FREE(pwszRoot); } //CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); LPITEMIDLIST pResult = SHBrowseForFolder(&bi); if (!pResult) break; if (SHGetPathFromIDList(pResult, szBrowsePath)) { mySetWindowText(pField->hwnd, szBrowsePath); } CoTaskMemFree(pResult); break; } case FIELD_LINK: case FIELD_BUTTON: // Allow the state to be empty - this might be useful in conjunction // with the NOTIFY flag if (*pField->pszState) ShellExecute(hMainWindow, NULL, pField->pszState, NULL, NULL, SW_SHOWDEFAULT); break; } if (pField->nFlags & LBS_NOTIFY) { // Remember which control was activated then pretend the user clicked Next g_NotifyField = nIdx + 1; mySendMessage(hMainWindow, WM_NOTIFY_OUTER_NEXT, 1, 0); } return 0; }
LPITEMIDLIST GetCurrentFolder() { /* How To Convert a File Path to an ITEMIDLIST http://support.microsoft.com/default.aspx?scid=kb;en-us;132750 */ LPITEMIDLIST pidl; LPSHELLFOLDER pDesktopFolder; TCHAR szPath[ MAX_PATH ]; #ifndef PA_UNICODE OLECHAR olePath[ MAX_PATH ]; #endif ULONG chEaten; ULONG dwAttributes; HRESULT hr; // // Get the path we need to convert. // GetCurrentDirectory( MAX_PATH, szPath ); // // Get a pointer to the Desktop's IShellFolder interface. // if( SUCCEEDED( SHGetDesktopFolder( &pDesktopFolder ) ) ) { // // IShellFolder::ParseDisplayName requires the file name be in // Unicode. // #ifndef PA_UNICODE MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED, szPath, -1, olePath, MAX_PATH ); #endif // // Convert the path to an ITEMIDLIST. // // hr = pDesktopFolder->lpVtbl->ParseDisplayName( hr = pDesktopFolder->ParseDisplayName( ( HWND__ * )pDesktopFolder, NULL, #ifndef PA_UNICODE olePath, #else szPath, #endif &chEaten, &pidl, &dwAttributes ); if( FAILED( hr ) ) { // Handle error. return NULL; } // // pidl now contains a pointer to an ITEMIDLIST for .\readme.txt. // This ITEMIDLIST needs to be freed using the IMalloc allocator // returned from SHGetMalloc(). // // release the desktop folder object // pDesktopFolder->lpVtbl->Release(); pDesktopFolder->Release(); return pidl; } else { return NULL; } }
LPSHELLFOLDER COXShellNamespaceNavigator::GetShellFolder(LPCITEMIDLIST pidlFull) const { // First of all get the Desktop's IShellFolder interface. LPSHELLFOLDER lpDesktopFolder; if(FAILED(SHGetDesktopFolder(&lpDesktopFolder))) return NULL; // If pidlFull is NULL then just return the Desktop's IShellFolder if(pidlFull==NULL) { ASSERT(lpDesktopFolder!=NULL); if(lpDesktopFolder!=NULL) m_mapIShellFolderToRelease.SetAt((DWORD_PTR)lpDesktopFolder,NULL); return lpDesktopFolder; } // If we have valid IDL we should retrieve its IShellFolder interface. We accomplish it // using IShellFolder::BindToObject // /* HRESULT BindToObject( LPCITEMIDLIST pidl, LPBC pbcReserved, REFIID riid, LPVOID *ppvOut ); Retrieves an IShellFolder object for a subfolder. Returns NOERROR if successful, or an OLE-defined error value otherwise. pidl - Address of an ITEMIDLIST structure that identifies the subfolder relative to its parent folder. pbcReserved - Reserved. Callers should specify NULL for this parameter; those called should ignore it. riid - Identifier of the interface to return. This parameter must point to the IID_IShellFolder interface identifier. ppvOut - Address that receives the interface pointer. If an error occurs, a NULL pointer is returned in this address. */ // // Note that pidl have to be relative to its parent folder but as long as we are // going to call this method of desktop folder interface then the fully qualified // pidl we got using ParseDisplayName method can be used. // LPSHELLFOLDER lpFolder; HRESULT hResult=lpDesktopFolder-> BindToObject(pidlFull,0,IID_IShellFolder,(LPVOID*)&lpFolder); if(FAILED(hResult)) { ASSERT(lpDesktopFolder!=NULL); if(lpDesktopFolder!=NULL) m_mapIShellFolderToRelease.SetAt((DWORD_PTR)lpDesktopFolder,NULL); return lpDesktopFolder; } else { // release desktop folder lpDesktopFolder->Release(); ASSERT(lpFolder!=NULL); if(lpFolder!=NULL) m_mapIShellFolderToRelease.SetAt((DWORD_PTR)lpFolder,NULL); return lpFolder; } }
/*! 独自拡張プロパティシートのウィンドウプロシージャ @author ryoji @date 2007.05.25 新規 */ static LRESULT CALLBACK PropSheetWndProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) { switch( uMsg ){ case WM_SHOWWINDOW: // 追加ボタンの位置を調整する if( wParam ){ HWND hwndBtn; RECT rcOk; RECT rcTab; POINT pt; hwndBtn = ::GetDlgItem( hwnd, 0x02000 ); ::GetWindowRect( ::GetDlgItem( hwnd, IDOK ), &rcOk ); ::GetWindowRect( PropSheet_GetTabControl( hwnd ), &rcTab ); pt.x = rcTab.left; pt.y = rcOk.top; ::ScreenToClient( hwnd, &pt ); ::MoveWindow( hwndBtn, pt.x, pt.y, DpiScaleX(140), rcOk.bottom - rcOk.top, FALSE ); } break; case WM_COMMAND: // 追加ボタンが押された時はその処理を行う if( HIWORD( wParam ) == BN_CLICKED && LOWORD( wParam ) == 0x02000 ){ HWND hwndBtn = ::GetDlgItem( hwnd, 0x2000 ); RECT rc; POINT pt; // メニューを表示する ::GetWindowRect( hwndBtn, &rc ); pt.x = rc.left; pt.y = rc.bottom; GetMonitorWorkRect( pt, &rc ); // モニタのワークエリア HMENU hMenu = ::CreatePopupMenu(); ::InsertMenu( hMenu, 0, MF_BYPOSITION | MF_STRING, 100, LS(STR_SHELL_MENU_OPEN) ); ::InsertMenu( hMenu, 1, MF_BYPOSITION | MF_STRING, 101, LS(STR_SHELL_MENU_IMPEXP) ); int nId = ::TrackPopupMenu( hMenu, TPM_LEFTALIGN | TPM_TOPALIGN | TPM_LEFTBUTTON | TPM_RETURNCMD, ( pt.x > rc.left )? pt.x: rc.left, ( pt.y < rc.bottom )? pt.y: rc.bottom, 0, hwnd, NULL ); ::DestroyMenu( hMenu ); // 選択されたメニューの処理 switch( nId ){ case 100: // 設定フォルダを開く TCHAR szPath[_MAX_PATH]; GetInidir( szPath ); // フォルダの ITEMIDLIST を取得して ShellExecuteEx() で開く // Note. MSDN の ShellExecute() の解説にある方法でフォルダを開こうとした場合、 // フォルダと同じ場所に <フォルダ名>.exe があるとうまく動かない。 // verbが"open"やNULLではexeのほうが実行され"explore"では失敗する // (フォルダ名の末尾に'\\'を付加してもWindows 2000では付加しないのと同じ動作になってしまう) LPSHELLFOLDER pDesktopFolder; if( SUCCEEDED(::SHGetDesktopFolder(&pDesktopFolder)) ){ LPMALLOC pMalloc; if( SUCCEEDED(::SHGetMalloc(&pMalloc)) ){ LPITEMIDLIST pIDL; WCHAR pwszDisplayName[_MAX_PATH]; _tcstowcs(pwszDisplayName, szPath, _countof(pwszDisplayName)); //#ifdef _UNICODE // pwszDisplayName = szPath; //#else // WCHAR wszPath[_MAX_PATH]; // ::MultiByteToWideChar( CP_ACP, 0, szPath, -1, wszPath, _MAX_PATH ); // pwszDisplayName = wszPath; //#endif if( SUCCEEDED(pDesktopFolder->ParseDisplayName(NULL, NULL, pwszDisplayName, NULL, &pIDL, NULL)) ){ SHELLEXECUTEINFO si; ::ZeroMemory( &si, sizeof(si) ); si.cbSize = sizeof(si); si.fMask = SEE_MASK_IDLIST; si.lpVerb = _T("open"); si.lpIDList = pIDL; si.nShow = SW_SHOWNORMAL; ::ShellExecuteEx( &si ); // フォルダを開く pMalloc->Free( (void*)pIDL ); } pMalloc->Release(); } pDesktopFolder->Release(); } break; case 101: // インポート/エクスポートの起点リセット(起点を設定フォルダにする) int nMsgResult = MYMESSAGEBOX( hwnd, MB_OKCANCEL | MB_ICONINFORMATION, GSTR_APPNAME, LS(STR_SHELL_IMPEXPDIR) ); if( IDOK == nMsgResult ) { DLLSHAREDATA *pShareData = &GetDllShareData(); GetInidir( pShareData->m_sHistory.m_szIMPORTFOLDER ); AddLastChar( pShareData->m_sHistory.m_szIMPORTFOLDER, _countof2(pShareData->m_sHistory.m_szIMPORTFOLDER), _T('\\') ); } break; } } break; case WM_DESTROY: ::SetWindowLongPtr( hwnd, GWLP_WNDPROC, (LONG_PTR)s_pOldPropSheetWndProc ); break; } return ::CallWindowProc( s_pOldPropSheetWndProc, hwnd, uMsg, wParam, lParam ); }
LRESULT WINAPI WMCommandProc(HWND hWnd, UINT id, HWND hwndCtl, UINT codeNotify) { switch (codeNotify) { case BN_CLICKED: // The user pressed a button case LBN_SELCHANGE: // The user changed the selection in a ListBox control // case CBN_SELCHANGE: // The user changed the selection in a DropList control (same value as LBN_SELCHANGE) { char szBrowsePath[MAX_PATH]; int nIdx = FindControlIdx(id); if (nIdx < 0) break; if (pFields[nIdx].nType == FIELD_BROWSEBUTTON) --nIdx; FieldType *pField = pFields + nIdx; switch (pField->nType) { case FIELD_FILEREQUEST: { OPENFILENAME ofn={0,}; ofn.lStructSize = sizeof(ofn); ofn.hwndOwner = hConfigWindow; ofn.lpstrFilter = pField->pszFilter; ofn.lpstrFile = szBrowsePath; ofn.nMaxFile = sizeof(szBrowsePath); ofn.Flags = pField->nFlags & (OFN_OVERWRITEPROMPT | OFN_HIDEREADONLY | OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST | OFN_CREATEPROMPT | OFN_EXPLORER); GetWindowText(pField->hwnd, szBrowsePath, sizeof(szBrowsePath)); tryagain: if ((pField->nFlags & FLAG_SAVEAS) ? GetSaveFileName(&ofn) : GetOpenFileName(&ofn)) { mySetWindowText(pField->hwnd, szBrowsePath); break; } else if (szBrowsePath[0] && CommDlgExtendedError() == FNERR_INVALIDFILENAME) { szBrowsePath[0] = '\0'; goto tryagain; } break; } case FIELD_DIRREQUEST: { BROWSEINFO bi; bi.hwndOwner = hConfigWindow; bi.pidlRoot = NULL; bi.pszDisplayName = szBrowsePath; bi.lpszTitle = pField->pszText; #ifndef BIF_NEWDIALOGSTYLE #define BIF_NEWDIALOGSTYLE 0x0040 #endif bi.ulFlags = BIF_STATUSTEXT | BIF_RETURNONLYFSDIRS | BIF_NEWDIALOGSTYLE; bi.lpfn = BrowseCallbackProc; bi.lParam = nIdx; bi.iImage = 0; if (pField->pszRoot) { LPSHELLFOLDER sf; ULONG eaten; LPITEMIDLIST root; int ccRoot = (lstrlen(pField->pszRoot) * 2) + 2; LPWSTR pwszRoot = (LPWSTR) MALLOC(ccRoot); MultiByteToWideChar(CP_ACP, 0, pField->pszRoot, -1, pwszRoot, ccRoot); SHGetDesktopFolder(&sf); sf->ParseDisplayName(hConfigWindow, NULL, pwszRoot, &eaten, &root, NULL); bi.pidlRoot = root; sf->Release(); FREE(pwszRoot); } // CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); LPITEMIDLIST pResult = SHBrowseForFolder(&bi); if (!pResult) break; if (SHGetPathFromIDList(pResult, szBrowsePath)) { mySetWindowText(pField->hwnd, szBrowsePath); } LPMALLOC pMalloc; if (!SHGetMalloc(&pMalloc)) { pMalloc->Free(pResult); } break; } case FIELD_LINK: case FIELD_BUTTON: // Allow the state to be empty - this might be useful in conjunction // with the NOTIFY flag if (*pField->pszState) ShellExecute(hMainWindow, NULL, pField->pszState, NULL, NULL, SW_SHOWDEFAULT); break; } if (pField->nFlags & LBS_NOTIFY) { // Remember which control was activated then pretend the user clicked Next g_NotifyField = nIdx + 1; // the next button must be enabled or nsis will ignore WM_COMMAND BOOL bWasDisabled = EnableWindow(hNextButton, TRUE); FORWARD_WM_COMMAND(hMainWindow, IDOK, hNextButton, BN_CLICKED, mySendMessage); if (bWasDisabled) EnableWindow(hNextButton, FALSE); } } break; } return 0; }
/** * Begin a saved search. */ JNIEXPORT jlong JNICALL WindowsSavedSearch_METHOD(beginSearch) ( JNIEnv *env, jclass, jstring jPath ) { jstring_to_c const cPath( env, jPath ); SavedSearch* cSavedSearch = NULL; bool error = false; LPITEMIDLIST pidl = NULL; LPSHELLFOLDER pDesktop = NULL; HRESULT result; if ( FAILED( ::CoInitialize( NULL ) ) ) goto error; cSavedSearch = new SavedSearch; if ( FAILED( ::SHGetMalloc( &cSavedSearch->m_pMalloc ) ) ) goto error; // // We have to start at the filesystem root (the "Desktop" in Windows). // if ( FAILED( ::SHGetDesktopFolder( &pDesktop ) ) ) goto error; // // ParseDisplayName() wants UTF-16, so convert the path first. // WCHAR wPath[ MAX_PATH ]; if ( !LC_toWCHAR( cPath, wPath, sizeof wPath ) ) goto error; result = pDesktop->ParseDisplayName( NULL, NULL, wPath, NULL, &pidl, NULL ); if ( FAILED( result ) ) goto error; // // Binding the path of what we want relative to the Desktop gets us the // PIDL for the path of the saved search file. // result = pDesktop->BindToObject( pidl, NULL, IID_IShellFolder, reinterpret_cast<void**>( &cSavedSearch->m_pFolder ) ); if ( FAILED( result ) ) goto error; // // We can now start the enumeration of the saved search file which runs the // search. // result = cSavedSearch->m_pFolder->EnumObjects( NULL, SHCONTF_FOLDERS | SHCONTF_NONFOLDERS, &cSavedSearch->m_pEnumIDList ); if ( result == S_FALSE || FAILED( result ) ) goto error; goto done; error: error = true; done: if ( pDesktop ) pDesktop->Release(); if ( cSavedSearch && cSavedSearch->m_pMalloc && pidl ) cSavedSearch->m_pMalloc->Free( pidl ); if ( error ) { delete cSavedSearch; return 0; } return reinterpret_cast<jlong>( cSavedSearch ); }