static LRESULT BrsFolder_Treeview_Expand( browse_info *info, NMTREEVIEWW *pnmtv ) { IShellFolder *lpsf2 = NULL; LPTV_ITEMDATA lptvid = (LPTV_ITEMDATA) pnmtv->itemNew.lParam; HRESULT r; TRACE("TVN_ITEMEXPANDINGA/W\n"); if ((pnmtv->itemNew.state & TVIS_EXPANDEDONCE)) return 0; if (lptvid->lpi && lptvid->lpi->mkid.cb) { r = IShellFolder_BindToObject( lptvid->lpsfParent, lptvid->lpi, 0, (REFIID)&IID_IShellFolder, (LPVOID *)&lpsf2 ); } else { lpsf2 = lptvid->lpsfParent; r = IShellFolder_AddRef(lpsf2); } if (SUCCEEDED(r)) FillTreeView( info, lpsf2, lptvid->lpifq, pnmtv->itemNew.hItem, lptvid->pEnumIL); /* My Computer is already sorted and trying to do a simple text * sort will only mess things up */ if (!_ILIsMyComputer(lptvid->lpi)) SendMessageW( info->hwndTreeView, TVM_SORTCHILDREN, FALSE, (LPARAM)pnmtv->itemNew.hItem ); return 0; }
/************************************************************************** * ISvItemCm_Constructor() */ IContextMenu2 *ISvItemCm_Constructor(LPSHELLFOLDER pSFParent, LPCITEMIDLIST pidl, const LPCITEMIDLIST *apidl, UINT cidl) { ItemCmImpl* cm; UINT u; cm = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(ItemCmImpl)); cm->IContextMenu2_iface.lpVtbl = &cmvt; cm->ref = 1; cm->pidl = ILClone(pidl); cm->pSFParent = pSFParent; if(pSFParent) IShellFolder_AddRef(pSFParent); cm->apidl = _ILCopyaPidl(apidl, cidl); cm->cidl = cidl; cm->bAllValues = 1; for(u = 0; u < cidl; u++) { cm->bAllValues &= (_ILIsValue(apidl[u]) ? 1 : 0); } TRACE("(%p)->()\n",cm); return &cm->IContextMenu2_iface; }
HRESULT BackgroundMenu_Constructor(IShellFolder *parent, BOOL desktop, REFIID riid, void **pObj) { ContextMenu *This; HRESULT hr; This = HeapAlloc(GetProcessHeap(), 0, sizeof(*This)); if (!This) return E_OUTOFMEMORY; This->IContextMenu3_iface.lpVtbl = &BackgroundContextMenuVtbl; This->ref = 1; This->parent = parent; This->pidl = NULL; This->apidl = NULL; This->cidl = 0; This->allvalues = FALSE; This->desktop = desktop; if (parent) IShellFolder_AddRef(parent); hr = IContextMenu3_QueryInterface(&This->IContextMenu3_iface, riid, pObj); IContextMenu3_Release(&This->IContextMenu3_iface); return hr; }
HRESULT ItemMenu_Constructor(IShellFolder *parent, LPCITEMIDLIST pidl, const LPCITEMIDLIST *apidl, UINT cidl, REFIID riid, void **pObj) { ContextMenu* This; HRESULT hr; UINT i; This = HeapAlloc(GetProcessHeap(), 0, sizeof(*This)); if (!This) return E_OUTOFMEMORY; This->IContextMenu3_iface.lpVtbl = &ItemContextMenuVtbl; This->ref = 1; This->parent = parent; if (parent) IShellFolder_AddRef(parent); This->pidl = ILClone(pidl); This->apidl = _ILCopyaPidl(apidl, cidl); This->cidl = cidl; This->allvalues = TRUE; This->desktop = FALSE; for (i = 0; i < cidl; i++) This->allvalues &= (_ILIsValue(apidl[i]) ? 1 : 0); hr = IContextMenu3_QueryInterface(&This->IContextMenu3_iface, riid, pObj); IContextMenu3_Release(&This->IContextMenu3_iface); return hr; }
/****************************************************************************** * InsertTreeViewItem [Internal] * * PARAMS * info [I] data for the dialog * lpsf [I] IShellFolder interface of the item's parent shell folder * pidl [I] ITEMIDLIST of the child to insert, relative to parent * pidlParent [I] ITEMIDLIST of the parent shell folder * pEnumIL [I] Iterator for the children of the item to be inserted * hParent [I] The treeview-item that represents the parent shell folder * * RETURNS * Success: Handle to the created and inserted treeview-item * Failure: NULL */ static HTREEITEM InsertTreeViewItem( browse_info *info, IShellFolder * lpsf, LPCITEMIDLIST pidl, LPCITEMIDLIST pidlParent, IEnumIDList* pEnumIL, HTREEITEM hParent) { TVITEMW tvi; TVINSERTSTRUCTW tvins; WCHAR szBuff[MAX_PATH]; LPTV_ITEMDATA lptvid=0; tvi.mask = TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_PARAM; tvi.cChildren= pEnumIL ? 1 : 0; tvi.mask |= TVIF_CHILDREN; lptvid = SHAlloc( sizeof(TV_ITEMDATA) ); if (!lptvid) return NULL; if (!GetName(lpsf, pidl, SHGDN_NORMAL, szBuff)) return NULL; tvi.pszText = szBuff; tvi.cchTextMax = MAX_PATH; tvi.lParam = (LPARAM)lptvid; IShellFolder_AddRef(lpsf); lptvid->lpsfParent = lpsf; lptvid->lpi = ILClone(pidl); lptvid->lpifq = pidlParent ? ILCombine(pidlParent, pidl) : ILClone(pidl); lptvid->pEnumIL = pEnumIL; GetNormalAndSelectedIcons(lptvid->lpifq, &tvi); tvins.u.item = tvi; tvins.hInsertAfter = NULL; tvins.hParent = hParent; return (HTREEITEM)SendMessageW(info->hwndTreeView, TVM_INSERTITEM, 0, (LPARAM)&tvins ); }
static HRESULT ShellItem_get_shellfolder(ShellItem *This, IBindCtx *pbc, IShellFolder **ppsf) { IShellFolder *desktop; HRESULT ret; ret = SHGetDesktopFolder(&desktop); if (SUCCEEDED(ret)) { if (_ILIsDesktop(This->pidl)) { *ppsf = desktop; IShellFolder_AddRef(*ppsf); } else { ret = IShellFolder_BindToObject(desktop, This->pidl, pbc, &IID_IShellFolder, (void**)ppsf); } IShellFolder_Release(desktop); } return ret; }
/****************************************************************************** * InitializeTreeView [Internal] * * Called from WM_INITDIALOG handler. * * PARAMS * hwndParent [I] The BrowseForFolder dialog * root [I] ITEMIDLIST of the root shell folder */ static void InitializeTreeView( browse_info *info ) { LPITEMIDLIST pidlParent, pidlChild; HIMAGELIST hImageList; HRESULT hr; IShellFolder *lpsfParent, *lpsfRoot; IEnumIDList * pEnumChildren = NULL; HTREEITEM item; DWORD flags; LPCITEMIDLIST root = info->lpBrowseInfo->pidlRoot; TRACE("%p\n", info ); Shell_GetImageLists(NULL, &hImageList); if (hImageList) SendMessageW( info->hwndTreeView, TVM_SETIMAGELIST, 0, (LPARAM)hImageList ); /* We want to call InsertTreeViewItem down the code, in order to insert * the root item of the treeview. Due to InsertTreeViewItem's signature, * we need the following to do this: * * + An ITEMIDLIST corresponding to _the parent_ of root. * + An ITEMIDLIST, which is a relative path from root's parent to root * (containing a single SHITEMID). * + An IShellFolder interface pointer of root's parent folder. * * If root is 'Desktop', then root's parent is also 'Desktop'. */ pidlParent = ILClone(root); ILRemoveLastID(pidlParent); pidlChild = ILClone(ILFindLastID(root)); if (_ILIsDesktop(pidlParent)) { hr = SHGetDesktopFolder(&lpsfParent); } else { IShellFolder *lpsfDesktop; hr = SHGetDesktopFolder(&lpsfDesktop); if (!SUCCEEDED(hr)) { WARN("SHGetDesktopFolder failed! hr = %08x\n", hr); return; } hr = IShellFolder_BindToObject(lpsfDesktop, pidlParent, 0, &IID_IShellFolder, (LPVOID*)&lpsfParent); IShellFolder_Release(lpsfDesktop); } if (!SUCCEEDED(hr)) { WARN("Could not bind to parent shell folder! hr = %08x\n", hr); return; } if (pidlChild && pidlChild->mkid.cb) { hr = IShellFolder_BindToObject(lpsfParent, pidlChild, 0, &IID_IShellFolder, (LPVOID*)&lpsfRoot); } else { lpsfRoot = lpsfParent; hr = IShellFolder_AddRef(lpsfParent); } if (!SUCCEEDED(hr)) { WARN("Could not bind to root shell folder! hr = %08x\n", hr); IShellFolder_Release(lpsfParent); return; } flags = BrowseFlagsToSHCONTF( info->lpBrowseInfo->ulFlags ); hr = IShellFolder_EnumObjects( lpsfRoot, info->hWnd, flags, &pEnumChildren ); if (!SUCCEEDED(hr)) { WARN("Could not get child iterator! hr = %08x\n", hr); IShellFolder_Release(lpsfParent); IShellFolder_Release(lpsfRoot); return; } SendMessageW( info->hwndTreeView, TVM_DELETEITEM, 0, (LPARAM)TVI_ROOT ); item = InsertTreeViewItem( info, lpsfParent, pidlChild, pidlParent, pEnumChildren, TVI_ROOT ); SendMessageW( info->hwndTreeView, TVM_EXPAND, TVE_EXPAND, (LPARAM)item ); IShellFolder_Release(lpsfRoot); IShellFolder_Release(lpsfParent); }
static void test_IFolderView(void) { IShellFolder *desktop, *folder; FOLDERSETTINGS settings; IShellView *view; IShellBrowser *browser; IFolderView *fv; HWND hwnd_view, hwnd_list; PITEMID_CHILD pidl; HRESULT hr; INT ret, count; POINT pt; LONG ref1, ref2; RECT r; hr = SHGetDesktopFolder(&desktop); ok(hr == S_OK, "got (0x%08x)\n", hr); hr = IShellFolder_CreateViewObject(desktop, NULL, &IID_IShellView, (void**)&view); ok(hr == S_OK, "got (0x%08x)\n", hr); hr = IShellView_QueryInterface(view, &IID_IFolderView, (void**)&fv); if (hr != S_OK) { win_skip("IFolderView not supported by desktop folder\n"); IShellView_Release(view); IShellFolder_Release(desktop); return; } /* call methods before window creation */ hr = IFolderView_GetSpacing(fv, NULL); ok(hr == S_FALSE || broken(hr == S_OK) /* win7 */, "got (0x%08x)\n", hr); pidl = (void*)0xdeadbeef; hr = IFolderView_Item(fv, 0, &pidl); ok(hr == E_INVALIDARG || broken(hr == E_FAIL) /* < Vista */, "got (0x%08x)\n", hr); ok(pidl == 0 || broken(pidl == (void*)0xdeadbeef) /* < Vista */, "got %p\n", pidl); if (0) { /* crashes on Vista and Win2k8 - List not created yet case */ hr = IFolderView_GetSpacing(fv, &pt); /* crashes on XP */ hr = IFolderView_GetSelectionMarkedItem(fv, NULL); hr = IFolderView_GetFocusedItem(fv, NULL); /* crashes on Vista+ */ hr = IFolderView_Item(fv, 0, NULL); } browser = IShellBrowserImpl_Construct(); settings.ViewMode = FVM_ICON; settings.fFlags = 0; hwnd_view = (HWND)0xdeadbeef; r.left = r.top = 0; r.right = r.bottom = 100; hr = IShellView_CreateViewWindow(view, NULL, &settings, browser, &r, &hwnd_view); ok(hr == S_OK, "got (0x%08x)\n", hr); ok(IsWindow(hwnd_view), "got %p\n", hwnd_view); hwnd_list = subclass_listview(hwnd_view); if (!hwnd_list) { win_skip("Failed to subclass ListView control\n"); IShellBrowser_Release(browser); IFolderView_Release(fv); IShellView_Release(view); IShellFolder_Release(desktop); return; } /* IFolderView::GetSpacing */ flush_sequences(sequences, NUM_MSG_SEQUENCES); hr = IFolderView_GetSpacing(fv, NULL); ok(hr == S_OK, "got (0x%08x)\n", hr); ok_sequence(sequences, LISTVIEW_SEQ_INDEX, empty_seq, "IFolderView::GetSpacing, empty", FALSE); flush_sequences(sequences, NUM_MSG_SEQUENCES); hr = IFolderView_GetSpacing(fv, &pt); ok(hr == S_OK, "got (0x%08x)\n", hr); /* fails with empty sequence on win7 for unknown reason */ if (sequences[LISTVIEW_SEQ_INDEX]->count) { ok_sequence(sequences, LISTVIEW_SEQ_INDEX, folderview_getspacing_seq, "IFolderView::GetSpacing", FALSE); ok(pt.x > 0, "got %d\n", pt.x); ok(pt.y > 0, "got %d\n", pt.y); ret = SendMessageA(hwnd_list, LVM_GETITEMSPACING, 0, 0); ok(pt.x == LOWORD(ret) && pt.y == HIWORD(ret), "got (%d, %d)\n", LOWORD(ret), HIWORD(ret)); } /* IFolderView::ItemCount */ if (0) { /* crashes on XP */ hr = IFolderView_ItemCount(fv, SVGIO_ALLVIEW, NULL); } flush_sequences(sequences, NUM_MSG_SEQUENCES); hr = IFolderView_ItemCount(fv, SVGIO_ALLVIEW, &count); ok(hr == S_OK, "got (0x%08x)\n", hr); ok_sequence(sequences, LISTVIEW_SEQ_INDEX, count ? folderview_itemcount_seq : empty_seq, "IFolderView::ItemCount", FALSE); /* IFolderView::GetSelectionMarkedItem */ if (0) { /* crashes on XP */ hr = IFolderView_GetSelectionMarkedItem(fv, NULL); } flush_sequences(sequences, NUM_MSG_SEQUENCES); hr = IFolderView_GetSelectionMarkedItem(fv, &ret); if (count) ok(hr == S_OK, "got (0x%08x)\n", hr); else ok(hr == S_FALSE, "got (0x%08x)\n", hr); ok_sequence(sequences, LISTVIEW_SEQ_INDEX, folderview_getselectionmarked_seq, "IFolderView::GetSelectionMarkedItem", FALSE); /* IFolderView::GetFocusedItem */ flush_sequences(sequences, NUM_MSG_SEQUENCES); hr = IFolderView_GetFocusedItem(fv, &ret); if (count) ok(hr == S_OK, "got (0x%08x)\n", hr); else ok(hr == S_FALSE, "got (0x%08x)\n", hr); ok_sequence(sequences, LISTVIEW_SEQ_INDEX, folderview_getfocused_seq, "IFolderView::GetFocusedItem", FALSE); /* IFolderView::GetFolder, just return pointer */ if (0) { /* crashes on XP */ hr = IFolderView_GetFolder(fv, NULL, (void**)&folder); hr = IFolderView_GetFolder(fv, NULL, NULL); } hr = IFolderView_GetFolder(fv, &IID_IShellFolder, NULL); ok(hr == E_POINTER, "got (0x%08x)\n", hr); ref1 = IShellFolder_AddRef(desktop); IShellFolder_Release(desktop); hr = IFolderView_GetFolder(fv, &IID_IShellFolder, (void**)&folder); ok(hr == S_OK, "got (0x%08x)\n", hr); ref2 = IShellFolder_AddRef(desktop); IShellFolder_Release(desktop); ok(ref1 == ref2 || ref1 + 1 == ref2, /* >= vista */ "expected same refcount, got %d\n", ref2); ok(desktop == folder, "\n"); IShellBrowser_Release(browser); IFolderView_Release(fv); IShellView_Release(view); IShellFolder_Release(desktop); }