HRESULT SHELL32_CompareDetails(IShellFolder2* isf, LPARAM lParam, LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2) { SHELLDETAILS sd; WCHAR wszItem1[MAX_PATH], wszItem2[MAX_PATH]; HRESULT hres; hres = isf->GetDetailsOf(pidl1, lParam, &sd); if (FAILED(hres)) return MAKE_COMPARE_HRESULT(1); hres = StrRetToBufW(&sd.str, pidl1, wszItem1, MAX_PATH); if (FAILED(hres)) return MAKE_COMPARE_HRESULT(1); hres = isf->GetDetailsOf(pidl2, lParam, &sd); if (FAILED(hres)) return MAKE_COMPARE_HRESULT(1); hres = StrRetToBufW(&sd.str, pidl2, wszItem2, MAX_PATH); if (FAILED(hres)) return MAKE_COMPARE_HRESULT(1); int ret = wcsicmp(wszItem1, wszItem2); if (ret == 0) return SHELL32_CompareChildren(isf, lParam, pidl1, pidl2); return MAKE_COMPARE_HRESULT(ret); }
HRESULT SHELL32_CompareDetails(IShellFolder2* isf, LPARAM lParam, LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2) { SHELLDETAILS sd; WCHAR wszItem1[MAX_PATH], wszItem2[MAX_PATH]; isf->GetDetailsOf(pidl1, lParam, &sd); StrRetToBufW(&sd.str, pidl1, wszItem1, MAX_PATH); isf->GetDetailsOf(pidl2, lParam, &sd); StrRetToBufW(&sd.str, pidl2, wszItem2, MAX_PATH); int ret = wcsicmp(wszItem1, wszItem2); return MAKE_COMPARE_HRESULT(ret); }
static void update_shell_folder_listview(HWND dialog) { int i; LVITEMW item; LONG lSelected = SendDlgItemMessageW(dialog, IDC_LIST_SFPATHS, LVM_GETNEXTITEM, -1, MAKELPARAM(LVNI_SELECTED,0)); SendDlgItemMessageW(dialog, IDC_LIST_SFPATHS, LVM_DELETEALLITEMS, 0, 0); for (i=0; i<NUM_ELEMS(asfiInfo); i++) { WCHAR buffer[MAX_PATH]; HRESULT hr; LPITEMIDLIST pidlCurrent; /* Some acrobatic to get the localized name of the shell folder */ hr = SHGetFolderLocation(dialog, asfiInfo[i].nFolder, NULL, 0, &pidlCurrent); if (SUCCEEDED(hr)) { LPSHELLFOLDER psfParent; LPCITEMIDLIST pidlLast; hr = SHBindToParent(pidlCurrent, &IID_IShellFolder, (LPVOID*)&psfParent, &pidlLast); if (SUCCEEDED(hr)) { STRRET strRet; hr = IShellFolder_GetDisplayNameOf(psfParent, pidlLast, SHGDN_FORADDRESSBAR, &strRet); if (SUCCEEDED(hr)) { hr = StrRetToBufW(&strRet, pidlLast, buffer, MAX_PATH); } IShellFolder_Release(psfParent); } ILFree(pidlCurrent); } /* If there's a dangling symlink for the current shell folder, SHGetFolderLocation * will fail above. We fall back to the (non-verified) path of the shell folder. */ if (FAILED(hr)) { hr = SHGetFolderPathW(dialog, asfiInfo[i].nFolder|CSIDL_FLAG_DONT_VERIFY, NULL, SHGFP_TYPE_CURRENT, buffer); } item.mask = LVIF_TEXT | LVIF_PARAM; item.iItem = i; item.iSubItem = 0; item.pszText = buffer; item.lParam = (LPARAM)&asfiInfo[i]; SendDlgItemMessageW(dialog, IDC_LIST_SFPATHS, LVM_INSERTITEMW, 0, (LPARAM)&item); item.mask = LVIF_TEXT; item.iItem = i; item.iSubItem = 1; item.pszText = strdupU2W(asfiInfo[i].szLinkTarget); SendDlgItemMessageW(dialog, IDC_LIST_SFPATHS, LVM_SETITEMW, 0, (LPARAM)&item); HeapFree(GetProcessHeap(), 0, item.pszText); } /* Ensure that the previously selected item is selected again. */ if (lSelected >= 0) { item.mask = LVIF_STATE; item.state = LVIS_SELECTED; item.stateMask = LVIS_SELECTED; SendDlgItemMessageW(dialog, IDC_LIST_SFPATHS, LVM_SETITEMSTATE, lSelected, (LPARAM)&item); } }
/*********************************************************************** * SHOpenFolderAndSelectItems * * Unimplemented. */ EXTERN_C HRESULT WINAPI SHOpenFolderAndSelectItems(LPITEMIDLIST pidlFolder, UINT cidl, PCUITEMID_CHILD_ARRAY apidl, DWORD dwFlags) { ERR("SHOpenFolderAndSelectItems() is hackplemented\n"); PCIDLIST_ABSOLUTE pidlItem; if (cidl) { /* Firefox sends a full pidl here dispite the fact it is a PCUITEMID_CHILD_ARRAY -_- */ if (ILGetNext(apidl[0]) != NULL) { pidlItem = apidl[0]; } else { pidlItem = ILCombine(pidlFolder, apidl[0]); } } else { pidlItem = pidlFolder; } CComPtr<IShellFolder> psfDesktop; HRESULT hr = SHGetDesktopFolder(&psfDesktop); if (FAILED_UNEXPECTEDLY(hr)) return hr; STRRET strret; hr = psfDesktop->GetDisplayNameOf(pidlItem, SHGDN_FORPARSING, &strret); if (FAILED_UNEXPECTEDLY(hr)) return hr; WCHAR wszBuf[MAX_PATH]; hr = StrRetToBufW(&strret, pidlItem, wszBuf, _countof(wszBuf)); if (FAILED_UNEXPECTEDLY(hr)) return hr; WCHAR wszParams[MAX_PATH]; wcscpy(wszParams, L"/select,"); wcscat(wszParams, wszBuf); SHELLEXECUTEINFOW sei; memset(&sei, 0, sizeof sei); sei.cbSize = sizeof sei; sei.fMask = SEE_MASK_WAITFORINPUTIDLE; sei.lpFile = L"explorer.exe"; sei.lpParameters = wszParams; if (ShellExecuteExW(&sei)) return S_OK; else return E_FAIL; }
/// <summary> /// Get's the display name of a particular PIDL /// </summary> HRESULT TileGroup::GetDisplayNameOf(PCITEMID_CHILD pidl, SHGDNF flags, LPWSTR buf, UINT cchBuf) const { STRRET ret; HRESULT hr; hr = mRootFolder->GetDisplayNameOf(pidl, flags, &ret); if (SUCCEEDED(hr)) { hr = StrRetToBufW(&ret, pidl, buf, cchBuf); } return hr; }
// Gets the Display Name of a pidl. lpsf is the parent IShellFolder Interface // dwFlags specify a SHGDN_xx value BOOL IL_GetDisplayName(LPSHELLFOLDER lpsf, LPCITEMIDLIST pidl, DWORD dwFlags, WCHAR* lpszDisplayName, int nDisplayName) { STRRET str; if (NOERROR == lpsf->GetDisplayNameOf(pidl, dwFlags, &str)) { // Shlwapi.dll provides new function: return SUCCEEDED(StrRetToBufW(&str, pidl, lpszDisplayName, nDisplayName)); // ...but I suppose my version is faster ;-) /*switch (str.uType) { case STRRET_WSTR: WideCharToMultiByte(CP_ACP, 0, str.pOleStr, -1, lpszDisplayName, nDisplayName, NULL, NULL); CoTaskMemFree(str.pOleStr); break; case STRRET_OFFSET: lstrcpyn(lpszDisplayName, ((WCHAR *)(pidl)) + str.uOffset, nDisplayName); break; case STRRET_CSTR: lstrcpyn(lpszDisplayName,str.cStr,nDisplayName); break; } return TRUE;*/ } return FALSE; }
static void COMDLG32_UpdateCurrentDir(const FileOpenDlgInfos *fodInfos) { LPSHELLFOLDER psfDesktop; STRRET strret; HRESULT res; res = SHGetDesktopFolder(&psfDesktop); if (FAILED(res)) return; res = IShellFolder_GetDisplayNameOf(psfDesktop, fodInfos->ShellInfos.pidlAbsCurrent, SHGDN_FORPARSING, &strret); if (SUCCEEDED(res)) { WCHAR wszCurrentDir[MAX_PATH]; res = StrRetToBufW(&strret, fodInfos->ShellInfos.pidlAbsCurrent, wszCurrentDir, MAX_PATH); if (SUCCEEDED(res)) SetCurrentDirectoryW(wszCurrentDir); } IShellFolder_Release(psfDesktop); }
/// <summary> /// Retrives the parsing path for the current folder. /// </summary> HRESULT TileGroup::GetFolderPath(LPWSTR buf, UINT cchBuf) const { IPersistFolder2 *ipsf2; LPITEMIDLIST curFolder; STRRET curFolderName; HRESULT hr; if (SUCCEEDED(hr = mWorkingFolder->QueryInterface(IID_IPersistFolder2, (LPVOID*) &ipsf2))) { hr = ipsf2->GetCurFolder(&curFolder); if (SUCCEEDED(hr)) { hr = mRootFolder->GetDisplayNameOf(curFolder, SHGDN_FORPARSING, &curFolderName); } if (SUCCEEDED(hr)) { hr = StrRetToBufW(&curFolderName, curFolder, buf, cchBuf); } ipsf2->Release(); } return hr; }
/* Process items in the StartUp group of the user's Programs under the Start Menu. Some installers put * shell links here to restart themselves after boot. */ static BOOL ProcessStartupItems(void) { BOOL ret = FALSE; HRESULT hr; IMalloc *ppM = NULL; IShellFolder *psfDesktop = NULL, *psfStartup = NULL; LPITEMIDLIST pidlStartup = NULL, pidlItem; ULONG NumPIDLs; IEnumIDList *iEnumList = NULL; STRRET strret; WCHAR wszCommand[MAX_PATH]; WINE_TRACE("Processing items in the StartUp folder.\n"); hr = SHGetMalloc(&ppM); if (FAILED(hr)) { WINE_ERR("Couldn't get IMalloc object.\n"); goto done; } hr = SHGetDesktopFolder(&psfDesktop); if (FAILED(hr)) { WINE_ERR("Couldn't get desktop folder.\n"); goto done; } hr = SHGetSpecialFolderLocation(NULL, CSIDL_STARTUP, &pidlStartup); if (FAILED(hr)) { WINE_TRACE("Couldn't get StartUp folder location.\n"); goto done; } hr = IShellFolder_BindToObject(psfDesktop, pidlStartup, NULL, &IID_IShellFolder, (LPVOID*)&psfStartup); if (FAILED(hr)) { WINE_TRACE("Couldn't bind IShellFolder to StartUp folder.\n"); goto done; } hr = IShellFolder_EnumObjects(psfStartup, NULL, SHCONTF_NONFOLDERS | SHCONTF_INCLUDEHIDDEN, &iEnumList); if (FAILED(hr)) { WINE_TRACE("Unable to enumerate StartUp objects.\n"); goto done; } while (IEnumIDList_Next(iEnumList, 1, &pidlItem, &NumPIDLs) == S_OK && (NumPIDLs) == 1) { hr = IShellFolder_GetDisplayNameOf(psfStartup, pidlItem, SHGDN_FORPARSING, &strret); if (FAILED(hr)) WINE_TRACE("Unable to get display name of enumeration item.\n"); else { hr = StrRetToBufW(&strret, pidlItem, wszCommand, MAX_PATH); if (FAILED(hr)) WINE_TRACE("Unable to parse display name.\n"); else { HINSTANCE hinst; hinst = ShellExecuteW(NULL, NULL, wszCommand, NULL, NULL, SW_SHOWNORMAL); if (PtrToUlong(hinst) <= 32) WINE_WARN("Error %p executing command %s.\n", hinst, wine_dbgstr_w(wszCommand)); } } IMalloc_Free(ppM, pidlItem); } /* Return success */ ret = TRUE; done: if (iEnumList) IEnumIDList_Release(iEnumList); if (psfStartup) IShellFolder_Release(psfStartup); if (pidlStartup) IMalloc_Free(ppM, pidlStartup); return ret; }
/*********************************************************************** * SHELL32_GetItemAttributes * * NOTES * Observed values: * folder: 0xE0000177 FILESYSTEM | HASSUBFOLDER | FOLDER * file: 0x40000177 FILESYSTEM * drive: 0xf0000144 FILESYSTEM | HASSUBFOLDER | FOLDER | FILESYSANCESTOR * mycomputer: 0xb0000154 HASSUBFOLDER | FOLDER | FILESYSANCESTOR * (seems to be default for shell extensions if no registry entry exists) * * win2k: * folder: 0xF0400177 FILESYSTEM | HASSUBFOLDER | FOLDER | FILESYSANCESTOR | CANMONIKER * file: 0x40400177 FILESYSTEM | CANMONIKER * drive 0xF0400154 FILESYSTEM | HASSUBFOLDER | FOLDER | FILESYSANCESTOR | CANMONIKER | CANRENAME (LABEL) * * According to the MSDN documentation this function should not set flags. It claims only to reset flags when necessary. * However it turns out the native shell32.dll _sets_ flags in several cases - so do we. */ HRESULT SHELL32_GetItemAttributes (IShellFolder * psf, LPCITEMIDLIST pidl, LPDWORD pdwAttributes) { DWORD dwAttributes; BOOL has_guid; static const DWORD dwSupportedAttr= SFGAO_CANCOPY | /*0x00000001 */ SFGAO_CANMOVE | /*0x00000002 */ SFGAO_CANLINK | /*0x00000004 */ SFGAO_CANRENAME | /*0x00000010 */ SFGAO_CANDELETE | /*0x00000020 */ SFGAO_HASPROPSHEET | /*0x00000040 */ SFGAO_DROPTARGET | /*0x00000100 */ SFGAO_LINK | /*0x00010000 */ SFGAO_READONLY | /*0x00040000 */ SFGAO_HIDDEN | /*0x00080000 */ SFGAO_FILESYSANCESTOR | /*0x10000000 */ SFGAO_FOLDER | /*0x20000000 */ SFGAO_FILESYSTEM | /*0x40000000 */ SFGAO_HASSUBFOLDER; /*0x80000000 */ TRACE ("0x%08x\n", *pdwAttributes); if (*pdwAttributes & ~dwSupportedAttr) { WARN ("attributes 0x%08x not implemented\n", (*pdwAttributes & ~dwSupportedAttr)); *pdwAttributes &= dwSupportedAttr; } has_guid = _ILGetGUIDPointer(pidl) != NULL; dwAttributes = *pdwAttributes; if (_ILIsDrive (pidl)) { *pdwAttributes &= SFGAO_HASSUBFOLDER|SFGAO_FILESYSTEM|SFGAO_FOLDER|SFGAO_FILESYSANCESTOR| SFGAO_DROPTARGET|SFGAO_HASPROPSHEET|SFGAO_CANLINK; } else if (has_guid && HCR_GetFolderAttributes(pidl, &dwAttributes)) { *pdwAttributes = dwAttributes; } else if (_ILGetDataPointer (pidl)) { dwAttributes = _ILGetFileAttributes (pidl, NULL, 0); if (!dwAttributes && has_guid) { WCHAR path[MAX_PATH]; STRRET strret; /* File attributes are not present in the internal PIDL structure, so get them from the file system. */ HRESULT hr = IShellFolder_GetDisplayNameOf(psf, pidl, SHGDN_FORPARSING, &strret); if (SUCCEEDED(hr)) { hr = StrRetToBufW(&strret, pidl, path, MAX_PATH); /* call GetFileAttributes() only for file system paths, not for parsing names like "::{...}" */ if (SUCCEEDED(hr) && path[0]!=':') dwAttributes = GetFileAttributesW(path); } } /* Set common attributes */ *pdwAttributes |= SFGAO_FILESYSTEM | SFGAO_DROPTARGET | SFGAO_HASPROPSHEET | SFGAO_CANDELETE | SFGAO_CANRENAME | SFGAO_CANLINK | SFGAO_CANMOVE | SFGAO_CANCOPY; if (dwAttributes & FILE_ATTRIBUTE_DIRECTORY) *pdwAttributes |= (SFGAO_FOLDER | SFGAO_HASSUBFOLDER | SFGAO_FILESYSANCESTOR); else *pdwAttributes &= ~(SFGAO_FOLDER | SFGAO_HASSUBFOLDER | SFGAO_FILESYSANCESTOR); if (dwAttributes & FILE_ATTRIBUTE_HIDDEN) *pdwAttributes |= SFGAO_HIDDEN; else *pdwAttributes &= ~SFGAO_HIDDEN; if (dwAttributes & FILE_ATTRIBUTE_READONLY) *pdwAttributes |= SFGAO_READONLY; else *pdwAttributes &= ~SFGAO_READONLY; if (SFGAO_LINK & *pdwAttributes) { char ext[MAX_PATH]; if (!_ILGetExtension(pidl, ext, MAX_PATH) || lstrcmpiA(ext, "lnk")) *pdwAttributes &= ~SFGAO_LINK; } } else { *pdwAttributes &= SFGAO_HASSUBFOLDER|SFGAO_FOLDER|SFGAO_FILESYSANCESTOR|SFGAO_DROPTARGET|SFGAO_HASPROPSHEET|SFGAO_CANRENAME|SFGAO_CANLINK; } TRACE ("-- 0x%08x\n", *pdwAttributes); return S_OK; }
STDMETHODIMP CLocateShellExtension::Initialize(LPCITEMIDLIST pIDFolder, LPDATAOBJECT pDataObj, HKEY hRegKey) { DebugFormatMessage("CLocateShellExtension::Initialize(%X,%X,%X)",pIDFolder,pDataObj,hRegKey); if (pDataObj==NULL) return E_INVALIDARG; FORMATETC FormatEtc; STGMEDIUM med; FormatEtc.cfFormat=RegisterClipboardFormat(CFSTR_SHELLIDLIST); FormatEtc.ptd=NULL; FormatEtc.dwAspect=DVASPECT_CONTENT; FormatEtc.lindex=-1; FormatEtc.tymed=TYMED_HGLOBAL; if (pDataObj->GetData(&FormatEtc,&med)==S_OK) { // May be computer? IShellFolder *psf; if (!SUCCEEDED(SHGetDesktopFolder(&psf))) { DebugMessage("No IShellFolder interface"); return E_FAIL; } // Retrieving data from item id list BYTE* pData=(BYTE*)GlobalLock(med.hGlobal); UINT nFiles=((int*)pData)[0]; UINT i,nLines=1,nSubIDListLen,nIDListLen; WCHAR szPath[_MAX_PATH]; nSubIDListLen=GetIDListSize((LPITEMIDLIST)(pData+((int*)pData)[1]))-2; for (i=0;i<nFiles;i++) { nIDListLen=GetIDListSize((LPITEMIDLIST)(pData+((int*)pData)[2+i])); // Constructing IDList from parent item and item LPITEMIDLIST pItemIDList=(LPITEMIDLIST)new BYTE[nSubIDListLen+nIDListLen+2]; CopyMemory((BYTE*)pItemIDList,(LPCSTR)(pData+((int*)pData)[1]),nSubIDListLen); CopyMemory((BYTE*)(pItemIDList)+nSubIDListLen,(LPCSTR)(pData+((int*)pData)[2+i]),nIDListLen); if (SHGetPathFromIDListW(pItemIDList,szPath)) { DebugFormatMessage(L"SHGetPathFromIDListW gives %s",szPath); if (IsDirectory(szPath)) { WCHAR szTarget[MAX_PATH]; switch (GetNethoodTarget(szPath,szTarget,MAX_PATH)) { case 1: m_aComputers.Add(alloccopy(szTarget)); break; case 2: m_aDirectories.Add(alloccopy(szTarget)); break; case 0: m_aDirectories.Add(alloccopy(szPath)); break; } } else m_aFiles.Add(alloccopy(szPath)); } else { DebugHexDump("idlist",(BYTE*)pItemIDList,nSubIDListLen+nIDListLen); STRRET str; if (SUCCEEDED(psf->GetDisplayNameOf(pItemIDList,SHGDN_NORMAL|SHGDN_FORPARSING,&str))) { if (SUCCEEDED(StrRetToBufW(&str,pItemIDList,szPath,MAX_PATH))) { if (szPath[0]!='\\' && szPath[1]!='\\') DebugFormatMessage("Cannot add item %s",szPath); else m_aComputers.Add(alloccopy(szPath)); } else DebugMessage("StrRetToStr failed"); } else DebugMessage("GetDisplayNameOf failed"); } delete[] (BYTE*)pItemIDList; } GlobalUnlock(med.hGlobal); if (med.pUnkForRelease==NULL) GlobalFree(med.hGlobal); else med.pUnkForRelease->Release(); psf->Release(); } else { FormatEtc.cfFormat=CF_HDROP; if (m_pDataObj->GetData(&FormatEtc,&med)==S_OK) { LPDROPFILES df=(LPDROPFILES)GlobalLock(med.hGlobal); if (df->fWide) { LPWSTR lpPtr=(LPWSTR)((BYTE*)df+df->pFiles); SIZE_T nLen; while (nLen=wcslen(lpPtr)) { DebugFormatMessage(L"HDROP contains file %s",(LPCSTR)(lpPtr)); if (IsDirectory(lpPtr)) { WCHAR szTarget[MAX_PATH]; switch (GetNethoodTarget(lpPtr,szTarget,MAX_PATH)) { case 1: m_aComputers.Add(alloccopy(szTarget)); break; case 2: m_aDirectories.Add(alloccopy(szTarget)); break; case 0: m_aDirectories.Add(alloccopy(lpPtr,nLen)); break; } } else m_aFiles.Add(alloccopy(lpPtr,nLen)); lpPtr+=nLen+1; } } else { LPSTR lpPtr=(LPSTR)df+df->pFiles; SIZE_T nLen; while (nLen=strlen(lpPtr)) { LPWSTR lpFile=alloccopyAtoW(lpPtr,nLen); if (IsDirectory(lpFile)) m_aDirectories.Add(lpFile); else m_aFiles.Add(lpFile); lpPtr+=nLen+1; } } GlobalUnlock(med.hGlobal); if (med.pUnkForRelease==NULL) GlobalFree(med.hGlobal); else med.pUnkForRelease->Release(); } } // Initialize can be called more than once if (m_pDataObj) m_pDataObj->Release(); // duplicate the object pointer and registry handle if (pDataObj) { m_pDataObj = pDataObj; pDataObj->AddRef(); } return NOERROR; }
static HRESULT WINAPI ISF_Desktop_ISFHelper_fnCopyItems (ISFHelper * iface, IShellFolder * pSFFrom, UINT cidl, LPCITEMIDLIST * apidl) { IPersistFolder2 *ppf2 = NULL; WCHAR szSrcPath[MAX_PATH]; WCHAR szTargetPath[MAX_PATH]; SHFILEOPSTRUCTW op; LPITEMIDLIST pidl; LPWSTR pszSrc, pszTarget, pszSrcList, pszTargetList, pszFileName; int res, length; STRRET strRet; IGenericSFImpl *This = impl_from_ISFHelper(iface); TRACE ("(%p)->(%p,%u,%p)\n", This, pSFFrom, cidl, apidl); IShellFolder_QueryInterface (pSFFrom, &IID_IPersistFolder2, (LPVOID *) & ppf2); if (ppf2) { if (FAILED(IPersistFolder2_GetCurFolder (ppf2, &pidl))) { IPersistFolder2_Release(ppf2); return E_FAIL; } IPersistFolder2_Release(ppf2); if (FAILED(IShellFolder_GetDisplayNameOf(pSFFrom, pidl, SHGDN_FORPARSING, &strRet))) { SHFree (pidl); return E_FAIL; } if (FAILED(StrRetToBufW(&strRet, pidl, szSrcPath, MAX_PATH))) { SHFree (pidl); return E_FAIL; } SHFree (pidl); pszSrc = PathAddBackslashW (szSrcPath); wcscpy(szTargetPath, This->sPathTarget); pszTarget = PathAddBackslashW (szTargetPath); pszSrcList = build_paths_list(szSrcPath, cidl, apidl); pszTargetList = build_paths_list(szTargetPath, cidl, apidl); if (!pszSrcList || !pszTargetList) { if (pszSrcList) HeapFree(GetProcessHeap(), 0, pszSrcList); if (pszTargetList) HeapFree(GetProcessHeap(), 0, pszTargetList); SHFree (pidl); IPersistFolder2_Release (ppf2); return E_OUTOFMEMORY; } ZeroMemory(&op, sizeof(op)); if (!pszSrcList[0]) { /* remove trailing backslash */ pszSrc--; pszSrc[0] = L'\0'; op.pFrom = szSrcPath; } else { op.pFrom = pszSrcList; } if (!pszTargetList[0]) { /* remove trailing backslash */ if (pszTarget - szTargetPath > 3) { pszTarget--; pszTarget[0] = L'\0'; } else { pszTarget[1] = L'\0'; } op.pTo = szTargetPath; } else { op.pTo = pszTargetList; } op.hwnd = GetActiveWindow(); op.wFunc = FO_COPY; op.fFlags = FOF_ALLOWUNDO | FOF_NOCONFIRMMKDIR; res = SHFileOperationW(&op); if (res == DE_SAMEFILE) { length = wcslen(szTargetPath); pszFileName = wcsrchr(pszSrcList, '\\'); pszFileName++; if (LoadStringW(shell32_hInstance, IDS_COPY_OF, pszTarget, MAX_PATH - length)) { wcscat(szTargetPath, L" "); } wcscat(szTargetPath, pszFileName); op.pTo = szTargetPath; res = SHFileOperationW(&op); } HeapFree(GetProcessHeap(), 0, pszSrcList); HeapFree(GetProcessHeap(), 0, pszTargetList); if (res) return E_FAIL; else return S_OK; } return E_FAIL; }
HRESULT STDMETHODCALLTYPE CAddressEditBox::Invoke(DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr) { CComPtr<IBrowserService> isb; CComPtr<IShellFolder> sf; HRESULT hr; INT indexClosed, indexOpen, itemExists, oldIndex; DWORD result; COMBOBOXEXITEMW item; PIDLIST_ABSOLUTE absolutePIDL; LPCITEMIDLIST pidlChild; LPITEMIDLIST pidlPrevious; STRRET ret; WCHAR buf[4096]; if (pDispParams == NULL) return E_INVALIDARG; switch (dispIdMember) { case DISPID_NAVIGATECOMPLETE2: case DISPID_DOCUMENTCOMPLETE: pidlLastParsed = NULL; oldIndex = fCombobox.SendMessage(CB_GETCURSEL, 0, 0); itemExists = FALSE; pidlPrevious = NULL; ZeroMemory(&item, sizeof(item)); item.mask = CBEIF_LPARAM; item.iItem = 0; if (fCombobox.SendMessage(CBEM_GETITEM, 0, reinterpret_cast<LPARAM>(&item))) { pidlPrevious = reinterpret_cast<LPITEMIDLIST>(item.lParam); if (pidlPrevious) itemExists = TRUE; } hr = IUnknown_QueryService(fSite, SID_STopLevelBrowser, IID_PPV_ARG(IBrowserService, &isb)); if (FAILED_UNEXPECTEDLY(hr)) return hr; hr = isb->GetPidl(&absolutePIDL); if (FAILED_UNEXPECTEDLY(hr)) return hr; hr = SHBindToParent(absolutePIDL, IID_PPV_ARG(IShellFolder, &sf), &pidlChild); if (FAILED_UNEXPECTEDLY(hr)) return hr; hr = sf->GetDisplayNameOf(pidlChild, SHGDN_FORADDRESSBAR | SHGDN_FORPARSING, &ret); if (FAILED_UNEXPECTEDLY(hr)) return hr; hr = StrRetToBufW(&ret, pidlChild, buf, 4095); if (FAILED_UNEXPECTEDLY(hr)) return hr; indexClosed = SHMapPIDLToSystemImageListIndex(sf, pidlChild, &indexOpen); item.mask = CBEIF_IMAGE | CBEIF_SELECTEDIMAGE | CBEIF_TEXT | CBEIF_LPARAM; item.iItem = 0; item.iImage = indexClosed; item.iSelectedImage = indexOpen; item.pszText = buf; item.lParam = reinterpret_cast<LPARAM>(absolutePIDL); if (itemExists) { result = fCombobox.SendMessage(CBEM_SETITEM, 0, reinterpret_cast<LPARAM>(&item)); oldIndex = 0; if (result) { ILFree(pidlPrevious); } } else { oldIndex = fCombobox.SendMessage(CBEM_INSERTITEM, 0, reinterpret_cast<LPARAM>(&item)); if (oldIndex < 0) DbgPrint("ERROR %d\n", GetLastError()); } fCombobox.SendMessage(CB_SETCURSEL, -1, 0); fCombobox.SendMessage(CB_SETCURSEL, oldIndex, 0); //fAddressEditBox->SetCurrentDir(index); } return S_OK; }