static void BrsFolder_CheckValidSelection( browse_info *info, LPTV_ITEMDATA lptvid ) { LPBROWSEINFOW lpBrowseInfo = info->lpBrowseInfo; LPCITEMIDLIST pidl = lptvid->lpi; BOOL bEnabled = TRUE; DWORD dwAttributes; HRESULT r; if ((lpBrowseInfo->ulFlags & BIF_BROWSEFORCOMPUTER) && !PIDLIsType(pidl, PT_COMP)) bEnabled = FALSE; if (lpBrowseInfo->ulFlags & BIF_RETURNFSANCESTORS) { dwAttributes = SFGAO_FILESYSANCESTOR | SFGAO_FILESYSTEM; r = IShellFolder_GetAttributesOf(lptvid->lpsfParent, 1, (LPCITEMIDLIST*)&lptvid->lpi, &dwAttributes); if (FAILED(r) || !(dwAttributes & (SFGAO_FILESYSANCESTOR|SFGAO_FILESYSTEM))) bEnabled = FALSE; } if (lpBrowseInfo->ulFlags & BIF_RETURNONLYFSDIRS) { dwAttributes = SFGAO_FOLDER | SFGAO_FILESYSTEM; r = IShellFolder_GetAttributesOf(lptvid->lpsfParent, 1, (LPCITEMIDLIST*)&lptvid->lpi, &dwAttributes); if (FAILED(r) || ((dwAttributes & (SFGAO_FOLDER|SFGAO_FILESYSTEM)) != (SFGAO_FOLDER|SFGAO_FILESYSTEM))) { bEnabled = FALSE; } } SendMessageW(info->hWnd, BFFM_ENABLEOK, 0, (LPARAM)bEnabled); }
static HRESULT WINAPI ShellItem_GetAttributes(IShellItem2 *iface, SFGAOF sfgaoMask, SFGAOF *psfgaoAttribs) { ShellItem *This = impl_from_IShellItem2(iface); IShellFolder *parent_folder; LPITEMIDLIST child_pidl; HRESULT ret; TRACE("(%p,%x,%p)\n", iface, sfgaoMask, psfgaoAttribs); if (_ILIsDesktop(This->pidl)) ret = SHGetDesktopFolder(&parent_folder); else ret = ShellItem_get_parent_shellfolder(This, &parent_folder); if (SUCCEEDED(ret)) { child_pidl = ILFindLastID(This->pidl); *psfgaoAttribs = sfgaoMask; ret = IShellFolder_GetAttributesOf(parent_folder, 1, (LPCITEMIDLIST*)&child_pidl, psfgaoAttribs); *psfgaoAttribs &= sfgaoMask; IShellFolder_Release(parent_folder); if (SUCCEEDED(ret)) { if(sfgaoMask == *psfgaoAttribs) return S_OK; else return S_FALSE; } } return ret; }
/****************************************************************************** * FillTreeView [Internal] * * For each child (given by lpe) of the parent shell folder, which is given by * lpsf and whose PIDL is pidl, insert a treeview-item right under hParent * * PARAMS * info [I] data for the dialog * lpsf [I] IShellFolder interface of the parent shell folder * pidl [I] ITEMIDLIST of the parent shell folder * hParent [I] The treeview item that represents the parent shell folder * lpe [I] An iterator for the children of the parent shell folder */ static void FillTreeView( browse_info *info, IShellFolder * lpsf, LPITEMIDLIST pidl, HTREEITEM hParent, IEnumIDList* lpe) { HTREEITEM hPrev = 0; LPITEMIDLIST pidlTemp = 0; ULONG ulFetched; HRESULT hr; HWND hwnd = GetParent( info->hwndTreeView ); TRACE("%p %p %p %p\n",lpsf, pidl, hParent, lpe); /* No IEnumIDList -> No children */ if (!lpe) return; SetCapture( hwnd ); SetCursor( LoadCursorA( 0, (LPSTR)IDC_WAIT ) ); while (NOERROR == IEnumIDList_Next(lpe,1,&pidlTemp,&ulFetched)) { ULONG ulAttrs = SFGAO_HASSUBFOLDER | SFGAO_FOLDER; IEnumIDList* pEnumIL = NULL; IShellFolder* pSFChild = NULL; IShellFolder_GetAttributesOf(lpsf, 1, (LPCITEMIDLIST*)&pidlTemp, &ulAttrs); if (ulAttrs & SFGAO_FOLDER) { hr = IShellFolder_BindToObject(lpsf,pidlTemp,NULL,&IID_IShellFolder,(LPVOID*)&pSFChild); if (SUCCEEDED(hr)) { DWORD flags = BrowseFlagsToSHCONTF(info->lpBrowseInfo->ulFlags); hr = IShellFolder_EnumObjects(pSFChild, hwnd, flags, &pEnumIL); if (hr == S_OK) { if ((IEnumIDList_Skip(pEnumIL, 1) != S_OK) || FAILED(IEnumIDList_Reset(pEnumIL))) { IEnumIDList_Release(pEnumIL); pEnumIL = NULL; } } IShellFolder_Release(pSFChild); } } if (!(hPrev = InsertTreeViewItem(info, lpsf, pidlTemp, pidl, pEnumIL, hParent))) goto done; SHFree(pidlTemp); /* Finally, free the pidl that the shell gave us... */ pidlTemp=NULL; } done: ReleaseCapture(); SetCursor(LoadCursorW(0, (LPWSTR)IDC_ARROW)); SHFree(pidlTemp); }
/************************************************************************** * ISvItemCm_CanRenameItems() */ static BOOL ISvItemCm_CanRenameItems(ItemCmImpl *This) { UINT i; DWORD dwAttributes; TRACE("(%p)->()\n",This); if(This->apidl) { for(i = 0; i < This->cidl; i++){} if(i > 1) return FALSE; /* can't rename more than one item at a time*/ dwAttributes = SFGAO_CANRENAME; IShellFolder_GetAttributesOf(This->pSFParent, 1, (LPCITEMIDLIST*)This->apidl, &dwAttributes); return dwAttributes & SFGAO_CANRENAME; } return FALSE; }
/************************************************************************** * IShellBrowserImpl_ICommDlgBrowser_IncludeObject */ static HRESULT WINAPI IShellBrowserImpl_ICommDlgBrowser_IncludeObject(ICommDlgBrowser *iface, IShellView * ppshv, LPCITEMIDLIST pidl) { FileOpenDlgInfos *fodInfos; ULONG ulAttr; STRRET str; WCHAR szPathW[MAX_PATH]; IShellBrowserImpl *This = impl_from_ICommDlgBrowser(iface); TRACE("(%p)\n", This); fodInfos = get_filedlg_infoptr(This->hwndOwner); ulAttr = SFGAO_HIDDEN | SFGAO_FOLDER | SFGAO_FILESYSTEM | SFGAO_FILESYSANCESTOR | SFGAO_LINK; IShellFolder_GetAttributesOf(fodInfos->Shell.FOIShellFolder, 1, &pidl, &ulAttr); if( (ulAttr & SFGAO_HIDDEN) || /* hidden */ !(ulAttr & (SFGAO_FILESYSTEM | SFGAO_FILESYSANCESTOR))) /* special folder */ return S_FALSE; /* always include directories and links */ if(ulAttr & (SFGAO_FOLDER | SFGAO_LINK)) return S_OK; /* if the application takes care of including the item we are done */ if(fodInfos->ofnInfos->Flags & OFN_ENABLEINCLUDENOTIFY && send_includeitem_notification(This->hwndOwner, pidl)) return S_OK; /* Check if there is a mask to apply if not */ if(!fodInfos->ShellInfos.lpstrCurrentFilter || !fodInfos->ShellInfos.lpstrCurrentFilter[0]) return S_OK; if (SUCCEEDED(IShellFolder_GetDisplayNameOf(fodInfos->Shell.FOIShellFolder, pidl, SHGDN_INFOLDER | SHGDN_FORPARSING, &str))) { if (COMDLG32_StrRetToStrNW(szPathW, MAX_PATH, &str, pidl)) { if (PathMatchSpecW(szPathW, fodInfos->ShellInfos.lpstrCurrentFilter)) return S_OK; } } return S_FALSE; }
/************************************************************************** * IShellBrowserImpl_ICommDlgBrowser_IncludeObject */ static HRESULT WINAPI IShellBrowserImpl_ICommDlgBrowser_IncludeObject(ICommDlgBrowser *iface, IShellView * ppshv, LPCITEMIDLIST pidl) { FileOpenDlgInfos *fodInfos; ULONG ulAttr; STRRET str; WCHAR szPathW[MAX_PATH]; IShellBrowserImpl *This = impl_from_ICommDlgBrowser(iface); TRACE("(%p)\n", This); fodInfos = (FileOpenDlgInfos *) GetPropA(This->hwndOwner,FileOpenDlgInfosStr); ulAttr = SFGAO_HIDDEN | SFGAO_FOLDER | SFGAO_FILESYSTEM | SFGAO_FILESYSANCESTOR | SFGAO_LINK; IShellFolder_GetAttributesOf(fodInfos->Shell.FOIShellFolder, 1, &pidl, &ulAttr); if( (ulAttr & SFGAO_HIDDEN) /* hidden */ | !(ulAttr & (SFGAO_FILESYSTEM | SFGAO_FILESYSANCESTOR))) /* special folder */ return S_FALSE; /* always include directories and links */ if(ulAttr & (SFGAO_FOLDER | SFGAO_LINK)) return S_OK; /* Check if there is a mask to apply if not */ if(!fodInfos->ShellInfos.lpstrCurrentFilter || !lstrlenW(fodInfos->ShellInfos.lpstrCurrentFilter)) return S_OK; if (SUCCEEDED(IShellFolder_GetDisplayNameOf(fodInfos->Shell.FOIShellFolder, pidl, SHGDN_INFOLDER | SHGDN_FORPARSING, &str))) { if (SUCCEEDED(COMDLG32_StrRetToStrNW(szPathW, MAX_PATH, &str, pidl))) { if (PathMatchSpecW(szPathW, fodInfos->ShellInfos.lpstrCurrentFilter)) return S_OK; } } return S_FALSE; }
/************************************************************************** * IShellBrowserImpl_ICommDlgBrowser_OnDefaultCommand * * Called when a user double-clicks in the view or presses the ENTER key */ static HRESULT WINAPI IShellBrowserImpl_ICommDlgBrowser_OnDefaultCommand(ICommDlgBrowser *iface, IShellView *ppshv) { LPITEMIDLIST pidl; FileOpenDlgInfos *fodInfos; IShellBrowserImpl *This = impl_from_ICommDlgBrowser(iface); TRACE("(%p)\n", This); fodInfos = get_filedlg_infoptr(This->hwndOwner); /* If the selected object is not a folder, send an IDOK command to parent window */ if((pidl = GetPidlFromDataObject(fodInfos->Shell.FOIDataObject, 1))) { HRESULT hRes; ULONG ulAttr = SFGAO_FOLDER | SFGAO_HASSUBFOLDER; IShellFolder_GetAttributesOf(fodInfos->Shell.FOIShellFolder, 1, (LPCITEMIDLIST *)&pidl, &ulAttr); if (ulAttr & (SFGAO_FOLDER | SFGAO_HASSUBFOLDER) ) { hRes = IShellBrowser_BrowseObject(&This->IShellBrowser_iface,pidl,SBSP_RELATIVE); if(fodInfos->ofnInfos->Flags & OFN_EXPLORER) SendCustomDlgNotificationMessage(This->hwndOwner, CDN_FOLDERCHANGE); } else { /* Tell the dialog that the user selected a file */ PostMessageA(This->hwndOwner, WM_COMMAND, IDOK, 0L); hRes = S_OK; } /* Free memory used by pidl */ COMDLG32_SHFree(pidl); return hRes; } return E_FAIL; }
/************************************************************************* * 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; }
/* add an individual file or folder to the menu, takes ownership of pidl */ static struct menu_item* add_shell_item(struct menu_item* parent, LPITEMIDLIST pidl) { struct menu_item* item; MENUITEMINFOW mii; HMENU parent_menu; int existing_item_count, i; BOOL match = FALSE; SFGAOF flags; item = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(struct menu_item)); if (parent->pidl == NULL) { pidl_to_shellfolder(pidl, &item->displayname, &item->folder); } else { STRRET strret; IShellFolder_GetDisplayNameOf(parent->folder, pidl, SHGDN_INFOLDER, &strret); StrRetToStrW(&strret, NULL, &item->displayname); flags = SFGAO_FOLDER; IShellFolder_GetAttributesOf(parent->folder, 1, (LPCITEMIDLIST*)&pidl, &flags); if (flags & SFGAO_FOLDER) IShellFolder_BindToObject(parent->folder, pidl, NULL, &IID_IShellFolder, (void *)&item->folder); } parent_menu = parent->menuhandle; item->parent = parent; item->pidl = pidl; existing_item_count = GetMenuItemCount(parent_menu); mii.cbSize = sizeof(mii); mii.fMask = MIIM_SUBMENU|MIIM_DATA; /* search for an existing menu item with this name or the spot to insert this item */ if (parent->pidl != NULL) { for (i=0; i<existing_item_count; i++) { struct menu_item* existing_item; int cmp; GetMenuItemInfoW(parent_menu, i, TRUE, &mii); existing_item = ((struct menu_item*)mii.dwItemData); if (!existing_item) continue; /* folders before files */ if (existing_item->folder && !item->folder) continue; if (!existing_item->folder && item->folder) break; cmp = CompareStringW(LOCALE_USER_DEFAULT, NORM_IGNORECASE, item->displayname, -1, existing_item->displayname, -1); if (cmp == CSTR_LESS_THAN) break; if (cmp == CSTR_EQUAL) { match = TRUE; break; } } } else /* This item manually added to the root menu, so put it at the end */ i = existing_item_count; if (!match) { /* no existing item with the same name; just add it */ mii.fMask = MIIM_STRING|MIIM_DATA; mii.dwTypeData = item->displayname; mii.dwItemData = (ULONG_PTR)item; if (item->folder) { MENUINFO mi; item->menuhandle = CreatePopupMenu(); mii.fMask |= MIIM_SUBMENU; mii.hSubMenu = item->menuhandle; mi.cbSize = sizeof(mi); mi.fMask = MIM_MENUDATA; mi.dwMenuData = (ULONG_PTR)item; SetMenuInfo(item->menuhandle, &mi); } InsertMenuItemW(parent->menuhandle, i, TRUE, &mii); list_add_tail(&items, &item->entry); } else if (item->folder) { /* there is an existing folder with the same name, combine them */ MENUINFO mi; item->base = (struct menu_item*)mii.dwItemData; item->menuhandle = item->base->menuhandle; mii.dwItemData = (ULONG_PTR)item; SetMenuItemInfoW(parent_menu, i, TRUE, &mii); mi.cbSize = sizeof(mi); mi.fMask = MIM_MENUDATA; mi.dwMenuData = (ULONG_PTR)item; SetMenuInfo(item->menuhandle, &mi); list_add_tail(&items, &item->entry); } else { /* duplicate shortcut, do nothing */ HeapFree(GetProcessHeap(), 0, item->displayname); HeapFree(GetProcessHeap(), 0, item); CoTaskMemFree(pidl); item = NULL; } return item; }
/****************************************************************************** * HCR_GetFolderAttributes [Internal] * * Query the registry for a shell folders' attributes * * PARAMS * pidlFolder [I] A simple pidl of type PT_GUID. * pdwAttributes [IO] In: Attributes to be queried, OUT: Resulting attributes. * * RETURNS * TRUE: Found information for the attributes in the registry * FALSE: No attribute information found * * NOTES * If queried for an attribute, which is set in the CallForAttributes registry * value, the function binds to the shellfolder objects and queries it. */ BOOL HCR_GetFolderAttributes(LPCITEMIDLIST pidlFolder, LPDWORD pdwAttributes) { HKEY hSFKey; LPOLESTR pwszCLSID; LONG lResult; DWORD dwTemp, dwLen; static const WCHAR wszAttributes[] = { 'A','t','t','r','i','b','u','t','e','s',0 }; static const WCHAR wszCallForAttributes[] = { 'C','a','l','l','F','o','r','A','t','t','r','i','b','u','t','e','s',0 }; WCHAR wszShellFolderKey[] = { 'C','L','S','I','D','\\','{','0','0','0','2','1','4','0','0','-', '0','0','0','0','-','0','0','0','0','-','C','0','0','0','-','0','0','0','0','0','0','0', '0','0','0','4','6','}','\\','S','h','e','l','l','F','o','l','d','e','r',0 }; TRACE("(pidlFolder=%p, pdwAttributes=%p)\n", pidlFolder, pdwAttributes); if (!_ILIsPidlSimple(pidlFolder)) { static BOOL firstHit = TRUE; if (firstHit) { ERR("should be called for simple PIDL's only!\n"); firstHit = FALSE; } return FALSE; } if (!_ILIsDesktop(pidlFolder)) { if (FAILED(StringFromCLSID(_ILGetGUIDPointer(pidlFolder), &pwszCLSID))) return FALSE; memcpy(&wszShellFolderKey[6], pwszCLSID, 38 * sizeof(WCHAR)); CoTaskMemFree(pwszCLSID); } lResult = RegOpenKeyExW(HKEY_CLASSES_ROOT, wszShellFolderKey, 0, KEY_READ, &hSFKey); #ifdef __REACTOS__ if (lResult != ERROR_SUCCESS) { ERR("Cannot open key: %ls\n", wszShellFolderKey); return FALSE; } #else if (lResult != ERROR_SUCCESS) return FALSE; #endif dwLen = sizeof(DWORD); lResult = RegQueryValueExW(hSFKey, wszCallForAttributes, 0, NULL, (LPBYTE)&dwTemp, &dwLen); if ((lResult == ERROR_SUCCESS) && (dwTemp & *pdwAttributes)) { LPSHELLFOLDER psfDesktop, psfFolder; HRESULT hr; RegCloseKey(hSFKey); hr = SHGetDesktopFolder(&psfDesktop); if (SUCCEEDED(hr)) { hr = IShellFolder_BindToObject(psfDesktop, pidlFolder, NULL, &IID_IShellFolder, (LPVOID*)&psfFolder); if (SUCCEEDED(hr)) { hr = IShellFolder_GetAttributesOf(psfFolder, 0, NULL, pdwAttributes); IShellFolder_Release(psfFolder); } IShellFolder_Release(psfDesktop); } if (FAILED(hr)) return FALSE; } else { lResult = RegQueryValueExW(hSFKey, wszAttributes, 0, NULL, (LPBYTE)&dwTemp, &dwLen); RegCloseKey(hSFKey); if (lResult == ERROR_SUCCESS) { *pdwAttributes &= dwTemp; } else { return FALSE; } } TRACE("-- *pdwAttributes == 0x%08x\n", *pdwAttributes); return TRUE; }
/************************************************************************* * FM_InitMenuPopup [internal] * */ static int FM_InitMenuPopup(HMENU hmenu, LPCITEMIDLIST pAlternatePidl) { IShellFolder *lpsf, *lpsf2; ULONG ulItemAttr = SFGAO_FOLDER; UINT uID, uEnumFlags; LPFNFMCALLBACK lpfnCallback; LPCITEMIDLIST pidl; WCHAR sTemp[MAX_PATH]; int NumberOfItems = 0, iIcon; MENUINFO MenuInfo; LPFMINFO menudata; TRACE("%p %p\n", hmenu, pAlternatePidl); MenuInfo.cbSize = sizeof(MENUINFO); MenuInfo.fMask = MIM_MENUDATA; if (! GetMenuInfo(hmenu, &MenuInfo)) return FALSE; menudata = (LPFMINFO)MenuInfo.dwMenuData; if ((menudata == 0) || (MenuInfo.cbSize != sizeof(MENUINFO))) { ERR("menudata corrupt: %p %u\n", menudata, MenuInfo.cbSize); return 0; } if (menudata->bInitialized) return 0; pidl = (pAlternatePidl? pAlternatePidl: menudata->pidl); if (!pidl) return 0; uID = menudata->uID; uEnumFlags = menudata->uEnumFlags; lpfnCallback = menudata->lpfnCallback; menudata->bInitialized = FALSE; SetMenuInfo(hmenu, &MenuInfo); if (SUCCEEDED (SHGetDesktopFolder(&lpsf))) { if (SUCCEEDED(IShellFolder_BindToObject(lpsf, pidl,0,(REFIID)&IID_IShellFolder,(LPVOID *)&lpsf2))) { IEnumIDList *lpe = NULL; if (SUCCEEDED (IShellFolder_EnumObjects(lpsf2, 0, uEnumFlags, &lpe ))) { LPITEMIDLIST pidlTemp = NULL; ULONG ulFetched; while ((!bAbortInit) && (NOERROR == IEnumIDList_Next(lpe,1,&pidlTemp,&ulFetched))) { if (SUCCEEDED (IShellFolder_GetAttributesOf(lpsf, 1, (LPCITEMIDLIST*)&pidlTemp, &ulItemAttr))) { ILGetDisplayNameExW(NULL, pidlTemp, sTemp, ILGDN_FORPARSING); if (! (PidlToSicIndex(lpsf, pidlTemp, FALSE, 0, &iIcon))) iIcon = FM_BLANK_ICON; if ( SFGAO_FOLDER & ulItemAttr) { LPFMINFO lpFmMi; MENUINFO MenuInfo; HMENU hMenuPopup = CreatePopupMenu(); lpFmMi = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(FMINFO)); lpFmMi->pidl = ILCombine(pidl, pidlTemp); lpFmMi->uEnumFlags = SHCONTF_FOLDERS | SHCONTF_NONFOLDERS; MenuInfo.cbSize = sizeof(MENUINFO); MenuInfo.fMask = MIM_MENUDATA; MenuInfo.dwMenuData = (ULONG_PTR) lpFmMi; SetMenuInfo (hMenuPopup, &MenuInfo); FileMenu_AppendItemW (hmenu, sTemp, uID, iIcon, hMenuPopup, FM_DEFAULT_HEIGHT); } else { LPWSTR pExt = PathFindExtensionW(sTemp); if (pExt) *pExt = 0; FileMenu_AppendItemW (hmenu, sTemp, uID, iIcon, 0, FM_DEFAULT_HEIGHT); } } if (lpfnCallback) { TRACE("enter callback\n"); lpfnCallback ( pidl, pidlTemp); TRACE("leave callback\n"); } NumberOfItems++; } IEnumIDList_Release (lpe); } IShellFolder_Release(lpsf2); } IShellFolder_Release(lpsf); } if ( GetMenuItemCount (hmenu) == 0 ) { static const WCHAR szEmpty[] = { '(','e','m','p','t','y',')',0 }; FileMenu_AppendItemW (hmenu, szEmpty, uID, FM_BLANK_ICON, 0, FM_DEFAULT_HEIGHT); NumberOfItems++; } menudata->bInitialized = TRUE; SetMenuInfo(hmenu, &MenuInfo); return NumberOfItems; }
static HRESULT WINAPI ItemMenu_QueryContextMenu( IContextMenu3 *iface, HMENU hmenu, UINT indexMenu, UINT idCmdFirst, UINT idCmdLast, UINT uFlags) { ContextMenu *This = impl_from_IContextMenu3(iface); INT uIDMax; TRACE("(%p)->(%p %d 0x%x 0x%x 0x%x )\n", This, hmenu, indexMenu, idCmdFirst, idCmdLast, uFlags); if(!(CMF_DEFAULTONLY & uFlags) && This->cidl > 0) { HMENU hmenures = LoadMenuW(shell32_hInstance, MAKEINTRESOURCEW(MENU_SHV_FILE)); if(uFlags & CMF_EXPLORE) RemoveMenu(hmenures, FCIDM_SHVIEW_OPEN, MF_BYCOMMAND); uIDMax = Shell_MergeMenus(hmenu, GetSubMenu(hmenures, 0), indexMenu, idCmdFirst, idCmdLast, MM_SUBMENUSHAVEIDS); DestroyMenu(hmenures); if(This->allvalues) { MENUITEMINFOW mi; WCHAR str[255]; mi.cbSize = sizeof(mi); mi.fMask = MIIM_ID | MIIM_STRING | MIIM_FTYPE; mi.dwTypeData = str; mi.cch = 255; GetMenuItemInfoW(hmenu, FCIDM_SHVIEW_EXPLORE, MF_BYCOMMAND, &mi); RemoveMenu(hmenu, FCIDM_SHVIEW_EXPLORE + idCmdFirst, MF_BYCOMMAND); mi.cbSize = sizeof(mi); mi.fMask = MIIM_ID | MIIM_TYPE | MIIM_STATE | MIIM_STRING; mi.dwTypeData = str; mi.fState = MFS_ENABLED; mi.wID = FCIDM_SHVIEW_EXPLORE; mi.fType = MFT_STRING; InsertMenuItemW(hmenu, (uFlags & CMF_EXPLORE) ? 1 : 2, MF_BYPOSITION, &mi); } SetMenuDefaultItem(hmenu, 0, MF_BYPOSITION); if(uFlags & ~CMF_CANRENAME) RemoveMenu(hmenu, FCIDM_SHVIEW_RENAME, MF_BYCOMMAND); else { UINT enable = MF_BYCOMMAND; /* can't rename more than one item at a time*/ if (!This->apidl || This->cidl > 1) enable |= MFS_DISABLED; else { DWORD attr = SFGAO_CANRENAME; IShellFolder_GetAttributesOf(This->parent, 1, (LPCITEMIDLIST*)This->apidl, &attr); enable |= (attr & SFGAO_CANRENAME) ? MFS_ENABLED : MFS_DISABLED; } EnableMenuItem(hmenu, FCIDM_SHVIEW_RENAME, enable); } return MAKE_HRESULT(SEVERITY_SUCCESS, 0, uIDMax-idCmdFirst); } return MAKE_HRESULT(SEVERITY_SUCCESS, 0, 0); }