HRESULT VariantToIdlist(VARIANT* var, LPITEMIDLIST* idlist) { HRESULT hr = S_FALSE; if(V_VT(var) == VT_I4) { hr = SHGetSpecialFolderLocation(NULL, V_I4(var), idlist); } else if(V_VT(var) == VT_BSTR) { hr = SHILCreateFromPathW(V_BSTR(var), idlist, NULL); } return hr; }
HRESULT CNewMenu::SelectNewItem(LPCMINVOKECOMMANDINFO lpici, LONG wEventId, UINT uFlags, LPWSTR pszName) { CComPtr<IShellBrowser> lpSB; CComPtr<IShellView> lpSV; HRESULT hr = E_FAIL; LPITEMIDLIST pidl; PITEMID_CHILD pidlNewItem; /* Notify the view object about the new item */ SHChangeNotify(wEventId, uFlags, (LPCVOID) pszName, NULL); /* FIXME: I think that this can be implemented using callbacks to the shell folder */ /* Note: CWM_GETISHELLBROWSER returns shell browser without adding reference */ lpSB = (LPSHELLBROWSER)SendMessageA(lpici->hwnd, CWM_GETISHELLBROWSER, 0, 0); if (!lpSB) return E_FAIL; hr = lpSB->QueryActiveShellView(&lpSV); if (FAILED(hr)) return hr; /* Attempt to get the pidl of the new item */ hr = SHILCreateFromPathW(pszName, &pidl, NULL); if (FAILED_UNEXPECTEDLY(hr)) return hr; pidlNewItem = ILFindLastID(pidl); hr = lpSV->SelectItem(pidlNewItem, SVSI_DESELECTOTHERS | SVSI_EDIT | SVSI_ENSUREVISIBLE | SVSI_FOCUSED | SVSI_SELECT); SHFree(pidl); return hr; }
/************************************************************************* * SHGetFileInfoW [SHELL32.@] * */ DWORD_PTR WINAPI SHGetFileInfoW(LPCWSTR path,DWORD dwFileAttributes, SHFILEINFOW *psfi, UINT sizeofpsfi, UINT flags ) { WCHAR szLocation[MAX_PATH], szFullPath[MAX_PATH]; int iIndex; DWORD_PTR ret = TRUE; DWORD dwAttributes = 0; IShellFolder * psfParent = NULL; IExtractIconW * pei = NULL; LPITEMIDLIST pidlLast = NULL, pidl = NULL; HRESULT hr = S_OK; BOOL IconNotYetLoaded=TRUE; UINT uGilFlags = 0; HIMAGELIST big_icons, small_icons; TRACE("%s fattr=0x%x sfi=%p(attr=0x%08x) size=0x%x flags=0x%x\n", (flags & SHGFI_PIDL)? "pidl" : debugstr_w(path), dwFileAttributes, psfi, psfi->dwAttributes, sizeofpsfi, flags); if (!path) return FALSE; /* windows initializes these values regardless of the flags */ if (psfi != NULL) { psfi->szDisplayName[0] = '\0'; psfi->szTypeName[0] = '\0'; psfi->iIcon = 0; } if (!(flags & SHGFI_PIDL)) { /* SHGetFileInfo should work with absolute and relative paths */ if (PathIsRelativeW(path)) { GetCurrentDirectoryW(MAX_PATH, szLocation); PathCombineW(szFullPath, szLocation, path); } else { lstrcpynW(szFullPath, path, MAX_PATH); } } if (flags & SHGFI_EXETYPE) { if (flags != SHGFI_EXETYPE) return 0; return shgfi_get_exe_type(szFullPath); } /* * psfi is NULL normally to query EXE type. If it is NULL, none of the * below makes sense anyway. Windows allows this and just returns FALSE */ if (psfi == NULL) return FALSE; /* * translate the path into a pidl only when SHGFI_USEFILEATTRIBUTES * is not specified. * The pidl functions fail on not existing file names */ if (flags & SHGFI_PIDL) { pidl = ILClone((LPCITEMIDLIST)path); } else if (!(flags & SHGFI_USEFILEATTRIBUTES)) { hr = SHILCreateFromPathW(szFullPath, &pidl, &dwAttributes); } if ((flags & SHGFI_PIDL) || !(flags & SHGFI_USEFILEATTRIBUTES)) { /* get the parent shellfolder */ if (pidl) { hr = SHBindToParent( pidl, &IID_IShellFolder, (LPVOID*)&psfParent, (LPCITEMIDLIST*)&pidlLast ); if (SUCCEEDED(hr)) pidlLast = ILClone(pidlLast); ILFree(pidl); } else { ERR("pidl is null!\n"); return FALSE; } } /* get the attributes of the child */ if (SUCCEEDED(hr) && (flags & SHGFI_ATTRIBUTES)) { if (!(flags & SHGFI_ATTR_SPECIFIED)) { psfi->dwAttributes = 0xffffffff; } if (psfParent) IShellFolder_GetAttributesOf( psfParent, 1, (LPCITEMIDLIST*)&pidlLast, &(psfi->dwAttributes) ); } /* get the displayname */ if (SUCCEEDED(hr) && (flags & SHGFI_DISPLAYNAME)) { if (flags & SHGFI_USEFILEATTRIBUTES && !(flags & SHGFI_PIDL)) { lstrcpyW (psfi->szDisplayName, PathFindFileNameW(szFullPath)); } else { STRRET str; hr = IShellFolder_GetDisplayNameOf( psfParent, pidlLast, SHGDN_INFOLDER, &str); StrRetToStrNW (psfi->szDisplayName, MAX_PATH, &str, pidlLast); } } /* get the type name */ if (SUCCEEDED(hr) && (flags & SHGFI_TYPENAME)) { static const WCHAR szFile[] = { 'F','i','l','e',0 }; static const WCHAR szDashFile[] = { '-','f','i','l','e',0 }; if (!(flags & SHGFI_USEFILEATTRIBUTES) || (flags & SHGFI_PIDL)) { char ftype[80]; _ILGetFileType(pidlLast, ftype, 80); MultiByteToWideChar(CP_ACP, 0, ftype, -1, psfi->szTypeName, 80 ); } else { if (dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) strcatW (psfi->szTypeName, szFile); else { WCHAR sTemp[64]; lstrcpyW(sTemp,PathFindExtensionW(szFullPath)); if (!( HCR_MapTypeToValueW(sTemp, sTemp, 64, TRUE) && HCR_MapTypeToValueW(sTemp, psfi->szTypeName, 80, FALSE ))) { lstrcpynW (psfi->szTypeName, sTemp, 64); strcatW (psfi->szTypeName, szDashFile); } } } } /* ### icons ###*/ Shell_GetImageLists( &big_icons, &small_icons ); if (flags & SHGFI_OPENICON) uGilFlags |= GIL_OPENICON; if (flags & SHGFI_LINKOVERLAY) uGilFlags |= GIL_FORSHORTCUT; else if ((flags&SHGFI_ADDOVERLAYS) || (flags&(SHGFI_ICON|SHGFI_SMALLICON))==SHGFI_ICON) { if (SHELL_IsShortcut(pidlLast)) uGilFlags |= GIL_FORSHORTCUT; } if (flags & SHGFI_OVERLAYINDEX) FIXME("SHGFI_OVERLAYINDEX unhandled\n"); if (flags & SHGFI_SELECTED) FIXME("set icon to selected, stub\n"); if (flags & SHGFI_SHELLICONSIZE) FIXME("set icon to shell size, stub\n"); /* get the iconlocation */ if (SUCCEEDED(hr) && (flags & SHGFI_ICONLOCATION )) { UINT uDummy,uFlags; if (flags & SHGFI_USEFILEATTRIBUTES && !(flags & SHGFI_PIDL)) { if (dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { lstrcpyW(psfi->szDisplayName, swShell32Name); psfi->iIcon = -IDI_SHELL_FOLDER; } else { WCHAR* szExt; static const WCHAR p1W[] = {'%','1',0}; WCHAR sTemp [MAX_PATH]; szExt = PathFindExtensionW(szFullPath); TRACE("szExt=%s\n", debugstr_w(szExt)); if ( szExt && HCR_MapTypeToValueW(szExt, sTemp, MAX_PATH, TRUE) && HCR_GetDefaultIconW(sTemp, sTemp, MAX_PATH, &psfi->iIcon)) { if (lstrcmpW(p1W, sTemp)) strcpyW(psfi->szDisplayName, sTemp); else { /* the icon is in the file */ strcpyW(psfi->szDisplayName, szFullPath); } } else ret = FALSE; } } else { hr = IShellFolder_GetUIObjectOf(psfParent, 0, 1, (LPCITEMIDLIST*)&pidlLast, &IID_IExtractIconW, &uDummy, (LPVOID*)&pei); if (SUCCEEDED(hr)) { hr = IExtractIconW_GetIconLocation(pei, uGilFlags, szLocation, MAX_PATH, &iIndex, &uFlags); if (uFlags & GIL_NOTFILENAME) ret = FALSE; else { lstrcpyW (psfi->szDisplayName, szLocation); psfi->iIcon = iIndex; } IExtractIconW_Release(pei); } } } /* get icon index (or load icon)*/ if (SUCCEEDED(hr) && (flags & (SHGFI_ICON | SHGFI_SYSICONINDEX))) { if (flags & SHGFI_USEFILEATTRIBUTES && !(flags & SHGFI_PIDL)) { WCHAR sTemp [MAX_PATH]; WCHAR * szExt; int icon_idx=0; lstrcpynW(sTemp, szFullPath, MAX_PATH); if (dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) psfi->iIcon = SIC_GetIconIndex(swShell32Name, -IDI_SHELL_FOLDER, 0); else { static const WCHAR p1W[] = {'%','1',0}; psfi->iIcon = 0; szExt = PathFindExtensionW(sTemp); if ( szExt && HCR_MapTypeToValueW(szExt, sTemp, MAX_PATH, TRUE) && HCR_GetDefaultIconW(sTemp, sTemp, MAX_PATH, &icon_idx)) { if (!lstrcmpW(p1W,sTemp)) /* icon is in the file */ strcpyW(sTemp, szFullPath); if (flags & SHGFI_SYSICONINDEX) { psfi->iIcon = SIC_GetIconIndex(sTemp,icon_idx,0); if (psfi->iIcon == -1) psfi->iIcon = 0; } else { UINT ret; if (flags & SHGFI_SMALLICON) ret = PrivateExtractIconsW( sTemp,icon_idx, GetSystemMetrics( SM_CXSMICON ), GetSystemMetrics( SM_CYSMICON ), &psfi->hIcon, 0, 1, 0); else ret = PrivateExtractIconsW( sTemp, icon_idx, GetSystemMetrics( SM_CXICON), GetSystemMetrics( SM_CYICON), &psfi->hIcon, 0, 1, 0); if (ret != 0 && ret != (UINT)-1) { IconNotYetLoaded=FALSE; psfi->iIcon = icon_idx; } } } } } else { if (!(PidlToSicIndex(psfParent, pidlLast, !(flags & SHGFI_SMALLICON), uGilFlags, &(psfi->iIcon)))) { ret = FALSE; } } if (ret && (flags & SHGFI_SYSICONINDEX)) { if (flags & SHGFI_SMALLICON) ret = (DWORD_PTR)small_icons; else ret = (DWORD_PTR)big_icons; } } /* icon handle */ if (SUCCEEDED(hr) && (flags & SHGFI_ICON) && IconNotYetLoaded) { if (flags & SHGFI_SMALLICON) psfi->hIcon = ImageList_GetIcon( small_icons, psfi->iIcon, ILD_NORMAL); else psfi->hIcon = ImageList_GetIcon( big_icons, psfi->iIcon, ILD_NORMAL); } if (flags & ~SHGFI_KNOWN_FLAGS) FIXME("unknown flags %08x\n", flags & ~SHGFI_KNOWN_FLAGS); if (psfParent) IShellFolder_Release(psfParent); if (hr != S_OK) ret = FALSE; SHFree(pidlLast); TRACE ("icon=%p index=0x%08x attr=0x%08x name=%s type=%s ret=0x%08lx\n", psfi->hIcon, psfi->iIcon, psfi->dwAttributes, debugstr_w(psfi->szDisplayName), debugstr_w(psfi->szTypeName), ret); return ret; }