static HRESULT ShellItem_get_parent_shellfolder(ShellItem *This, IShellFolder **ppsf) { LPITEMIDLIST parent_pidl; IShellFolder *desktop; HRESULT ret; ret = ShellItem_get_parent_pidl(This, &parent_pidl); if (SUCCEEDED(ret)) { ret = SHGetDesktopFolder(&desktop); if (SUCCEEDED(ret)) { if (_ILIsDesktop(parent_pidl)) { *ppsf = desktop; } else { ret = IShellFolder_BindToObject(desktop, parent_pidl, NULL, &IID_IShellFolder, (void**)ppsf); IShellFolder_Release(desktop); } } ILFree(parent_pidl); } return ret; }
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; }
static IShellFolder* get_starting_shell_folder(parameters_struct* params) { IShellFolder* desktop,*folder; LPITEMIDLIST root_pidl; HRESULT hres; SHGetDesktopFolder(&desktop); if (!params->root[0]) { return desktop; } hres = IShellFolder_ParseDisplayName(desktop,NULL,NULL, params->root,NULL, &root_pidl,NULL); if(FAILED(hres)) { return desktop; } hres = IShellFolder_BindToObject(desktop,root_pidl,NULL, &IID_IShellFolder, (void**)&folder); if(FAILED(hres)) { return desktop; } IShellFolder_Release(desktop); return folder; }
static HRESULT pidl_to_shellfolder(LPITEMIDLIST pidl, LPWSTR *displayname, IShellFolder **out_folder) { IShellFolder* parent_folder=NULL; LPCITEMIDLIST relative_pidl=NULL; STRRET strret; HRESULT hr; hr = SHBindToParent(pidl, &IID_IShellFolder, (void**)&parent_folder, &relative_pidl); if (displayname) { if (SUCCEEDED(hr)) hr = IShellFolder_GetDisplayNameOf(parent_folder, relative_pidl, SHGDN_INFOLDER, &strret); if (SUCCEEDED(hr)) hr = StrRetToStrW(&strret, NULL, displayname); } if (SUCCEEDED(hr)) hr = IShellFolder_BindToObject(parent_folder, relative_pidl, NULL, &IID_IShellFolder, (void**)out_folder); if (parent_folder) IShellFolder_Release(parent_folder); return hr; }
/****************************************************************************** * 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); }
static HRESULT create_folder(NewMenuImpl *This, IShellView *view) { IFolderView *folder_view = NULL; IShellFolder *desktop = NULL; IShellFolder *parent = NULL; ISFHelper *helper = NULL; LPITEMIDLIST pidl = NULL; WCHAR nameW[MAX_PATH]; HRESULT hr; if (view) { hr = IShellView_QueryInterface(view, &IID_IFolderView, (void **)&folder_view); if (FAILED(hr)) return hr; hr = IFolderView_GetFolder(folder_view, &IID_IShellFolder, (void **)&parent); if (FAILED(hr)) goto out; } else { hr = SHGetDesktopFolder(&desktop); if (FAILED(hr)) goto out; hr = IShellFolder_BindToObject(desktop, This->pidl, NULL, &IID_IShellFolder, (void **)&parent); if (FAILED(hr)) goto out; } IShellFolder_QueryInterface(parent, &IID_ISFHelper, (void **)&helper); if (FAILED(hr)) goto out; hr = ISFHelper_GetUniqueName(helper, nameW, MAX_PATH); if (FAILED(hr)) goto out; hr = ISFHelper_AddFolder(helper, 0, nameW, &pidl); if (FAILED(hr)) goto out; if (view) { IShellView_SelectItem(view, pidl, SVSI_DESELECTOTHERS | SVSI_EDIT | SVSI_ENSUREVISIBLE | SVSI_FOCUSED | SVSI_SELECT); } out: if (pidl) SHFree(pidl); if (helper) ISFHelper_Release(helper); if (parent) IShellFolder_Release(parent); if (desktop) IShellFolder_Release(desktop); if (folder_view) IFolderView_Release(folder_view); return hr; }
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; }
/****************************************************************************** * 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; }
/****************************************************************************** * 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); }
/************************************************************************* * 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; }
/* 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; }
static HRESULT BrsFolder_NewFolder(browse_info *info) { DWORD flags = BrowseFlagsToSHCONTF(info->lpBrowseInfo->ulFlags); IShellFolder *desktop, *cur; ISFHelper *sfhelper; WCHAR name[MAX_PATH]; HTREEITEM parent, added; LPTV_ITEMDATA item_data; LPITEMIDLIST new_item; TVITEMW item; HRESULT hr; int len; if(!info->pidlRet) { ERR("Make new folder button should be disabled\n"); return E_FAIL; } /* Create new directory */ hr = SHGetDesktopFolder(&desktop); if(FAILED(hr)) return hr; hr = IShellFolder_BindToObject(desktop, info->pidlRet, 0, &IID_IShellFolder, (void**)&cur); IShellFolder_Release(desktop); if(FAILED(hr)) return hr; hr = IShellFolder_QueryInterface(cur, &IID_ISFHelper, (void**)&sfhelper); if(FAILED(hr)) return hr; hr = SHGetPathFromIDListW(info->pidlRet, name); if(FAILED(hr)) goto cleanup; len = strlenW(name); if(len<MAX_PATH) name[len++] = '\\'; hr = ISFHelper_GetUniqueName(sfhelper, &name[len], MAX_PATH-len); ISFHelper_Release(sfhelper); if(FAILED(hr)) goto cleanup; hr = E_FAIL; if(!CreateDirectoryW(name, NULL)) goto cleanup; /* Update parent of newly created directory */ parent = (HTREEITEM)SendMessageW(info->hwndTreeView, TVM_GETNEXTITEM, TVGN_CARET, 0); if(!parent) goto cleanup; SendMessageW(info->hwndTreeView, TVM_EXPAND, TVE_EXPAND, (LPARAM)parent); memset(&item, 0, sizeof(TVITEMW)); item.mask = TVIF_PARAM|TVIF_STATE; item.hItem = parent; SendMessageW(info->hwndTreeView, TVM_GETITEMW, 0, (LPARAM)&item); item_data = (LPTV_ITEMDATA)item.lParam; if(!item_data) goto cleanup; if(item_data->pEnumIL) IEnumIDList_Release(item_data->pEnumIL); hr = IShellFolder_EnumObjects(cur, info->hwndTreeView, flags, &item_data->pEnumIL); if(FAILED(hr)) goto cleanup; /* Update treeview */ if(!(item.state&TVIS_EXPANDEDONCE)) { item.mask = TVIF_STATE; item.state = TVIS_EXPANDEDONCE; item.stateMask = TVIS_EXPANDEDONCE; SendMessageW(info->hwndTreeView, TVM_SETITEMW, 0, (LPARAM)&item); } hr = IShellFolder_ParseDisplayName(cur, NULL, NULL, name+len, NULL, &new_item, NULL); if(FAILED(hr)) goto cleanup; added = InsertTreeViewItem(info, cur, new_item, item_data->lpifq, NULL, parent); IShellFolder_Release(cur); SHFree(new_item); SendMessageW(info->hwndTreeView, TVM_SORTCHILDREN, FALSE, (LPARAM)parent); return BrsFolder_Rename(info, added); cleanup: return hr; }
static void test_ShortcutFolder(void) { LPSHELLFOLDER pDesktopFolder, pWineTestFolder; IPersistFolder3 *pWineTestPersistFolder; LPITEMIDLIST pidlWineTestFolder, pidlCurFolder; HRESULT hr; CLSID clsid; const CLSID CLSID_WineTest = { 0x9b352ebf, 0x2765, 0x45c1, { 0xb4, 0xc6, 0x85, 0xcc, 0x7f, 0x7a, 0xbc, 0x64 } }; WCHAR wszWineTestFolder[] = { ':',':','{','9','B','3','5','2','E','B','F','-','2','7','6','5','-','4','5','C','1','-', 'B','4','C','6','-','8','5','C','C','7','F','7','A','B','C','6','4','}',0 }; /* First, we register all the necessary registry keys/values for our 'WineTest' * shell object. */ register_keys(HKEY_CLASSES_ROOT, HKEY_CLASSES_ROOT_keys, 1); hr = SHGetDesktopFolder(&pDesktopFolder); ok (SUCCEEDED(hr), "SHGetDesktopFolder failed! hr = %08x\n", hr); if (FAILED(hr)) goto cleanup; /* Convert the wszWineTestFolder string to an ITEMIDLIST. */ hr = IShellFolder_ParseDisplayName(pDesktopFolder, NULL, NULL, wszWineTestFolder, NULL, &pidlWineTestFolder, NULL); todo_wine { ok (hr == HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER), "Expected %08x, got %08x\n", HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER), hr); } if (FAILED(hr)) { IShellFolder_Release(pDesktopFolder); goto cleanup; } /* FIXME: these tests are never run */ /* Bind to a WineTest folder object. There has to be some support for this in shdocvw.dll. * This isn't implemented in wine yet.*/ hr = IShellFolder_BindToObject(pDesktopFolder, pidlWineTestFolder, NULL, &IID_IShellFolder, (LPVOID*)&pWineTestFolder); IShellFolder_Release(pDesktopFolder); ILFree(pidlWineTestFolder); ok (SUCCEEDED(hr), "IShellFolder::BindToObject(WineTestFolder) failed! hr = %08x\n", hr); if (FAILED(hr)) goto cleanup; hr = IShellFolder_QueryInterface(pWineTestFolder, &IID_IPersistFolder3, (LPVOID*)&pWineTestPersistFolder); ok (SUCCEEDED(hr), "IShellFolder::QueryInterface(IPersistFolder3) failed! hr = %08x\n", hr); IShellFolder_Release(pWineTestFolder); if (FAILED(hr)) goto cleanup; /* The resulting folder object has the FolderShortcut CLSID, instead of it's own. */ hr = IPersistFolder3_GetClassID(pWineTestPersistFolder, &clsid); ok (SUCCEEDED(hr), "IPersist::GetClassID failed! hr = %08x\n", hr); ok (IsEqualCLSID(&CLSID_FolderShortcut, &clsid), "GetClassId returned wrong CLSID!\n"); pidlCurFolder = (LPITEMIDLIST)0xdeadbeef; hr = IPersistFolder3_GetCurFolder(pWineTestPersistFolder, &pidlCurFolder); ok (SUCCEEDED(hr), "IPersistFolder3::GetCurFolder failed! hr = %08x\n", hr); ok (pidlCurFolder->mkid.cb == 20 && ((LPSHITEMID)((BYTE*)pidlCurFolder+20))->cb == 0 && IsEqualCLSID(&CLSID_WineTest, (REFCLSID)((LPBYTE)pidlCurFolder+4)), "GetCurFolder returned unexpected pidl!\n"); ILFree(pidlCurFolder); IPersistFolder3_Release(pWineTestPersistFolder); cleanup: unregister_keys(HKEY_CLASSES_ROOT, HKEY_CLASSES_ROOT_keys, 1); }
/*********************************************************************** * SHELL32_BindToChild [Internal] * * Common code for IShellFolder_BindToObject. * * PARAMS * pidlRoot [I] The parent shell folder's absolute pidl. * pathRoot [I] Absolute dos path of the parent shell folder. * pidlComplete [I] PIDL of the child. Relative to pidlRoot. * riid [I] GUID of the interface, which ppvOut shall be bound to. * ppvOut [O] A reference to the child's interface (riid). * * NOTES * pidlComplete has to contain at least one non empty SHITEMID. * This function makes special assumptions on the shell namespace, which * means you probably can't use it for your IShellFolder implementation. */ HRESULT SHELL32_BindToChild (LPCITEMIDLIST pidlRoot, LPCWSTR pathRoot, LPCITEMIDLIST pidlComplete, REFIID riid, LPVOID * ppvOut) { GUID const *clsid; IShellFolder *pSF; HRESULT hr; LPITEMIDLIST pidlChild; TRACE("(%p %s %p %s %p)\n", pidlRoot, debugstr_w(pathRoot), pidlComplete, debugstr_guid(riid), ppvOut); if (!pidlRoot || !ppvOut || _ILIsEmpty(pidlComplete)) return E_INVALIDARG; *ppvOut = NULL; pidlChild = ILCloneFirst (pidlComplete); if ((clsid = _ILGetGUIDPointer (pidlChild))) { /* virtual folder */ hr = SHELL32_CoCreateInitSF (pidlRoot, pathRoot, pidlChild, clsid, (LPVOID *)&pSF); } else if (_ILIsValue(pidlChild)) { /* Don't bind to files */ hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND); } else { /* file system folder */ CLSID clsidFolder = CLSID_ShellFSFolder; static const WCHAR wszCLSID[] = {'C','L','S','I','D',0}; WCHAR wszCLSIDValue[CHARS_IN_GUID], wszFolderPath[MAX_PATH], *pwszPathTail = wszFolderPath; /* see if folder CLSID should be overridden by desktop.ini file */ if (pathRoot) { lstrcpynW(wszFolderPath, pathRoot, MAX_PATH); pwszPathTail = PathAddBackslashW(wszFolderPath); } _ILSimpleGetTextW(pidlChild,pwszPathTail,MAX_PATH - (int)(pwszPathTail - wszFolderPath)); if (SHELL32_GetCustomFolderAttributeFromPath (wszFolderPath, wszDotShellClassInfo, wszCLSID, wszCLSIDValue, CHARS_IN_GUID)) CLSIDFromString (wszCLSIDValue, &clsidFolder); hr = SHELL32_CoCreateInitSF (pidlRoot, pathRoot, pidlChild, &clsidFolder, (LPVOID *)&pSF); } ILFree (pidlChild); if (SUCCEEDED (hr)) { if (_ILIsPidlSimple (pidlComplete)) { /* no sub folders */ hr = IShellFolder_QueryInterface (pSF, riid, ppvOut); } else { /* go deeper */ hr = IShellFolder_BindToObject (pSF, ILGetNext (pidlComplete), NULL, riid, ppvOut); } IShellFolder_Release (pSF); } TRACE ("-- returning (%p) 0x%08x\n", *ppvOut, hr); return hr; }
static void update_path_box(explorer_info *info) { COMBOBOXEXITEMW item; COMBOBOXEXITEMW main_item; IShellFolder *desktop; IPersistFolder2 *persist; LPITEMIDLIST desktop_pidl; IEnumIDList *ids; ImageList_Remove((HIMAGELIST)info->icon_list,-1); SendMessageW(info->path_box,CB_RESETCONTENT,0,0); SHGetDesktopFolder(&desktop); IShellFolder_QueryInterface(desktop,&IID_IPersistFolder2,(void**)&persist); IPersistFolder2_GetCurFolder(persist,&desktop_pidl); IPersistFolder2_Release(persist); persist = NULL; /*Add Desktop*/ item.iItem = -1; item.mask = CBEIF_TEXT | CBEIF_INDENT | CBEIF_LPARAM; item.iIndent = 0; create_combobox_item(desktop,desktop_pidl,info->icon_list,&item); item.lParam = (LPARAM)desktop_pidl; SendMessageW(info->path_box,CBEM_INSERTITEMW,0,(LPARAM)&item); if(ILIsEqual(info->pidl,desktop_pidl)) main_item = item; else CoTaskMemFree(item.pszText); /*Add all direct subfolders of Desktop*/ if(SUCCEEDED(IShellFolder_EnumObjects(desktop,NULL,SHCONTF_FOLDERS,&ids)) && ids!=NULL) { LPITEMIDLIST curr_pidl=NULL; HRESULT hres; item.iIndent = 1; while(1) { ILFree(curr_pidl); curr_pidl=NULL; hres = IEnumIDList_Next(ids,1,&curr_pidl,NULL); if(FAILED(hres) || hres == S_FALSE) break; if(!create_combobox_item(desktop,curr_pidl,info->icon_list,&item)) WINE_WARN("Could not create a combobox item\n"); else { LPITEMIDLIST full_pidl = ILCombine(desktop_pidl,curr_pidl); item.lParam = (LPARAM)full_pidl; SendMessageW(info->path_box,CBEM_INSERTITEMW,0,(LPARAM)&item); if(ILIsEqual(full_pidl,info->pidl)) main_item = item; else if(ILIsParent(full_pidl,info->pidl,FALSE)) { /*add all parents of the pidl passed in*/ LPITEMIDLIST next_pidl = ILFindChild(full_pidl,info->pidl); IShellFolder *curr_folder = NULL, *temp; hres = IShellFolder_BindToObject(desktop,curr_pidl,NULL, &IID_IShellFolder, (void**)&curr_folder); if(FAILED(hres)) WINE_WARN("Could not get an IShellFolder\n"); while(!ILIsEmpty(next_pidl)) { LPITEMIDLIST first = ILCloneFirst(next_pidl); CoTaskMemFree(item.pszText); if(!create_combobox_item(curr_folder,first, info->icon_list,&item)) { WINE_WARN("Could not create a combobox item\n"); break; } ++item.iIndent; full_pidl = ILCombine(full_pidl,first); item.lParam = (LPARAM)full_pidl; SendMessageW(info->path_box,CBEM_INSERTITEMW,0,(LPARAM)&item); temp=NULL; hres = IShellFolder_BindToObject(curr_folder,first,NULL, &IID_IShellFolder, (void**)&temp); if(FAILED(hres)) { WINE_WARN("Could not get an IShellFolder\n"); break; } IShellFolder_Release(curr_folder); curr_folder = temp; ILFree(first); next_pidl = ILGetNext(next_pidl); } memcpy(&main_item,&item,sizeof(item)); if(curr_folder) IShellFolder_Release(curr_folder); item.iIndent = 1; } else CoTaskMemFree(item.pszText); } } ILFree(curr_pidl); IEnumIDList_Release(ids); } else WINE_WARN("Could not enumerate the desktop\n"); SendMessageW(info->path_box,CBEM_SETITEMW,0,(LPARAM)&main_item); CoTaskMemFree(main_item.pszText); }
static void test_ShellFolderViewDual(void) { static const IID *shelldisp_riids[] = { &IID_IShellDispatch6, &IID_IShellDispatch5, &IID_IShellDispatch4, &IID_NULL }; IShellFolderViewDual *viewdual; IShellFolder *desktop, *tmpdir; IShellView *view, *view2; IDispatch *disp, *disp2; WCHAR pathW[MAX_PATH]; LPITEMIDLIST pidl; HRESULT hr; /* IShellFolderViewDual is not an IShellView extension */ 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_IShellFolderViewDual, (void**)&viewdual); ok(hr == E_NOINTERFACE, "got 0x%08x\n", hr); hr = IShellView_GetItemObject(view, SVGIO_BACKGROUND, &IID_IDispatch, (void**)&disp); ok(hr == S_OK, "got 0x%08x\n", hr); hr = IShellView_GetItemObject(view, SVGIO_BACKGROUND, &IID_IDispatch, (void**)&disp2); ok(hr == S_OK, "got 0x%08x\n", hr); ok(disp2 == disp, "got %p, %p\n", disp2, disp); IDispatch_Release(disp2); hr = IDispatch_QueryInterface(disp, &IID_IShellFolderViewDual, (void**)&viewdual); ok(hr == S_OK, "got 0x%08x\n", hr); ok(disp == (IDispatch*)viewdual, "got %p, expected %p\n", viewdual, disp); hr = IShellFolderViewDual_QueryInterface(viewdual, &IID_IShellView, (void**)&view2); ok(hr == E_NOINTERFACE, "got 0x%08x\n", hr); /* get_Application() */ if (0) { /* crashes on pre-vista */ hr = IShellFolderViewDual_get_Application(viewdual, NULL); ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); } hr = IShellFolderViewDual_get_Application(viewdual, &disp2); ok(hr == S_OK, "got 0x%08x\n", hr); ok(disp2 != (IDispatch*)viewdual, "got %p, %p\n", disp2, viewdual); test_dispatch_typeinfo(disp2, shelldisp_riids); IDispatch_Release(disp2); IShellFolderViewDual_Release(viewdual); IDispatch_Release(disp); disp = (void*)0xdeadbeef; hr = IShellView_GetItemObject(view, SVGIO_BACKGROUND, &IID_IShellFolderViewDual, (void**)&disp); ok(hr == E_NOINTERFACE, "got 0x%08x\n", hr); ok(disp == NULL, "got %p\n", disp); IShellView_Release(view); /* Try with some other folder, that's not a desktop */ GetTempPathW(sizeof(pathW)/sizeof(pathW[0]), pathW); hr = IShellFolder_ParseDisplayName(desktop, NULL, NULL, pathW, NULL, &pidl, NULL); ok(hr == S_OK, "got 0x%08x\n", hr); hr = IShellFolder_BindToObject(desktop, pidl, NULL, &IID_IShellFolder, (void**)&tmpdir); ok(hr == S_OK, "got 0x%08x\n", hr); CoTaskMemFree(pidl); hr = IShellFolder_CreateViewObject(desktop, NULL, &IID_IShellView, (void**)&view); ok(hr == S_OK, "got 0x%08x\n", hr); hr = IShellView_QueryInterface(view, &IID_IShellFolderViewDual, (void**)&viewdual); ok(hr == E_NOINTERFACE, "got 0x%08x\n", hr); hr = IShellView_GetItemObject(view, SVGIO_BACKGROUND, &IID_IDispatch, (void**)&disp); ok(hr == S_OK, "got 0x%08x\n", hr); IDispatch_Release(disp); IShellView_Release(view); IShellFolder_Release(tmpdir); IShellFolder_Release(desktop); }
/* 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; }
/************************************************************************** * DoOpenProperties */ static void DoOpenProperties(ItemCmImpl *This, HWND hwnd) { static const UINT MAX_PROP_PAGES = 99; static const WCHAR wszFolder[] = {'F','o','l','d','e','r', 0}; static const WCHAR wszFiletypeAll[] = {'*',0}; LPSHELLFOLDER lpDesktopSF; LPSHELLFOLDER lpSF; LPDATAOBJECT lpDo; WCHAR wszFiletype[MAX_PATH]; WCHAR wszFilename[MAX_PATH]; PROPSHEETHEADERW psh; HPROPSHEETPAGE hpages[MAX_PROP_PAGES]; HPSXA hpsxa; UINT ret; TRACE("(%p)->(wnd=%p)\n", This, hwnd); ZeroMemory(&psh, sizeof(PROPSHEETHEADERW)); psh.dwSize = sizeof (PROPSHEETHEADERW); psh.hwndParent = hwnd; psh.dwFlags = PSH_PROPTITLE; psh.nPages = 0; psh.u3.phpage = hpages; psh.u2.nStartPage = 0; _ILSimpleGetTextW(This->apidl[0], (LPVOID)&wszFilename, MAX_PATH); psh.pszCaption = (LPCWSTR)&wszFilename; /* Find out where to look for the shell extensions */ if (_ILIsValue(This->apidl[0])) { char sTemp[64]; sTemp[0] = 0; if (_ILGetExtension(This->apidl[0], sTemp, 64)) { HCR_MapTypeToValueA(sTemp, sTemp, 64, TRUE); MultiByteToWideChar(CP_ACP, 0, sTemp, -1, wszFiletype, MAX_PATH); } else { wszFiletype[0] = 0; } } else if (_ILIsFolder(This->apidl[0])) { lstrcpynW(wszFiletype, wszFolder, 64); } else if (_ILIsSpecialFolder(This->apidl[0])) { LPGUID folderGUID; static const WCHAR wszclsid[] = {'C','L','S','I','D','\\', 0}; folderGUID = _ILGetGUIDPointer(This->apidl[0]); lstrcpyW(wszFiletype, wszclsid); StringFromGUID2(folderGUID, &wszFiletype[6], MAX_PATH - 6); } else { FIXME("Requested properties for unknown type.\n"); return; } /* Get a suitable DataObject for accessing the files */ SHGetDesktopFolder(&lpDesktopSF); if (_ILIsPidlSimple(This->pidl)) { ret = IShellFolder_GetUIObjectOf(lpDesktopSF, hwnd, This->cidl, (LPCITEMIDLIST*)This->apidl, &IID_IDataObject, NULL, (LPVOID *)&lpDo); IShellFolder_Release(lpDesktopSF); } else { IShellFolder_BindToObject(lpDesktopSF, This->pidl, NULL, &IID_IShellFolder, (LPVOID*) &lpSF); ret = IShellFolder_GetUIObjectOf(lpSF, hwnd, This->cidl, (LPCITEMIDLIST*)This->apidl, &IID_IDataObject, NULL, (LPVOID *)&lpDo); IShellFolder_Release(lpSF); IShellFolder_Release(lpDesktopSF); } if (SUCCEEDED(ret)) { hpsxa = SHCreatePropSheetExtArrayEx(HKEY_CLASSES_ROOT, wszFiletype, MAX_PROP_PAGES - psh.nPages, lpDo); if (hpsxa != NULL) { SHAddFromPropSheetExtArray(hpsxa, Properties_AddPropSheetCallback, (LPARAM)&psh); SHDestroyPropSheetExtArray(hpsxa); } hpsxa = SHCreatePropSheetExtArrayEx(HKEY_CLASSES_ROOT, wszFiletypeAll, MAX_PROP_PAGES - psh.nPages, lpDo); if (hpsxa != NULL) { SHAddFromPropSheetExtArray(hpsxa, Properties_AddPropSheetCallback, (LPARAM)&psh); SHDestroyPropSheetExtArray(hpsxa); } IDataObject_Release(lpDo); } if (psh.nPages) PropertySheetW(&psh); else FIXME("No property pages found.\n"); }
/************************************************************************** * IShellBrowserImpl_BrowseObject * * See Windows documentation on IShellBrowser::BrowseObject for more details * * This function will override user specified flags and will always * use SBSP_DEFBROWSER and SBSP_DEFMODE. */ static HRESULT WINAPI IShellBrowserImpl_BrowseObject(IShellBrowser *iface, LPCITEMIDLIST pidl, UINT wFlags) { HRESULT hRes; IShellFolder *psfTmp; IShellView *psvTmp; FileOpenDlgInfos *fodInfos; LPITEMIDLIST pidlTmp; HWND hwndView; HWND hDlgWnd; BOOL bViewHasFocus; RECT rectView; IShellBrowserImpl *This = impl_from_IShellBrowser(iface); TRACE("(%p)(pidl=%p,flags=0x%08x)\n", This, pidl, wFlags); COMDLG32_DumpSBSPFlags(wFlags); fodInfos = get_filedlg_infoptr(This->hwndOwner); /* Format the pidl according to its parameter's category */ if(wFlags & SBSP_RELATIVE) { /* SBSP_RELATIVE A relative pidl (relative from the current folder) */ if(FAILED(hRes = IShellFolder_BindToObject(fodInfos->Shell.FOIShellFolder, pidl, NULL, &IID_IShellFolder, (LPVOID *)&psfTmp))) { ERR("bind to object failed\n"); return hRes; } /* create an absolute pidl */ pidlTmp = COMDLG32_PIDL_ILCombine(fodInfos->ShellInfos.pidlAbsCurrent, pidl); } else if(wFlags & SBSP_PARENT) { /* Browse the parent folder (ignores the pidl) */ pidlTmp = GetParentPidl(fodInfos->ShellInfos.pidlAbsCurrent); psfTmp = GetShellFolderFromPidl(pidlTmp); } else /* SBSP_ABSOLUTE is 0x0000 */ { /* An absolute pidl (relative from the desktop) */ pidlTmp = COMDLG32_PIDL_ILClone(pidl); psfTmp = GetShellFolderFromPidl(pidlTmp); } if(!psfTmp) { ERR("could not browse to folder\n"); return E_FAIL; } /* If the pidl to browse to is equal to the actual pidl ... do nothing and pretend you did it*/ if(COMDLG32_PIDL_ILIsEqual(pidlTmp,fodInfos->ShellInfos.pidlAbsCurrent)) { IShellFolder_Release(psfTmp); COMDLG32_SHFree(pidlTmp); TRACE("keep current folder\n"); return NOERROR; } /* Release the current DataObject */ if (fodInfos->Shell.FOIDataObject) { IDataObject_Release(fodInfos->Shell.FOIDataObject); fodInfos->Shell.FOIDataObject = NULL; } /* Create the associated view */ TRACE("create view object\n"); if(FAILED(hRes = IShellFolder_CreateViewObject(psfTmp, fodInfos->ShellInfos.hwndOwner, &IID_IShellView, (LPVOID *)&psvTmp))) goto error; /* Check if listview has focus */ bViewHasFocus = IsChild(fodInfos->ShellInfos.hwndView,GetFocus()); /* Get the foldersettings from the old view */ if(fodInfos->Shell.FOIShellView) IShellView_GetCurrentInfo(fodInfos->Shell.FOIShellView, &fodInfos->ShellInfos.folderSettings); /* Release the old fodInfos->Shell.FOIShellView and update its value. We have to update this early since ShellView_CreateViewWindow of native shell32 calls OnStateChange and needs the correct view here.*/ if(fodInfos->Shell.FOIShellView) { IShellView_DestroyViewWindow(fodInfos->Shell.FOIShellView); IShellView_Release(fodInfos->Shell.FOIShellView); } fodInfos->Shell.FOIShellView = psvTmp; /* Release old FOIShellFolder and update its value */ if (fodInfos->Shell.FOIShellFolder) IShellFolder_Release(fodInfos->Shell.FOIShellFolder); fodInfos->Shell.FOIShellFolder = psfTmp; /* Release old pidlAbsCurrent and update its value */ COMDLG32_SHFree(fodInfos->ShellInfos.pidlAbsCurrent); fodInfos->ShellInfos.pidlAbsCurrent = pidlTmp; COMDLG32_UpdateCurrentDir(fodInfos); GetWindowRect(GetDlgItem(This->hwndOwner, IDC_SHELLSTATIC), &rectView); MapWindowPoints(0, This->hwndOwner, (LPPOINT)&rectView, 2); /* Create the window */ TRACE("create view window\n"); if(FAILED(hRes = IShellView_CreateViewWindow(psvTmp, NULL, &fodInfos->ShellInfos.folderSettings, fodInfos->Shell.FOIShellBrowser, &rectView, &hwndView))) goto error; fodInfos->ShellInfos.hwndView = hwndView; /* Set view window control id to 5002 */ SetWindowLongPtrW(hwndView, GWLP_ID, lst2); SendMessageW( hwndView, WM_SETFONT, SendMessageW( GetParent(hwndView), WM_GETFONT, 0, 0 ), FALSE ); /* Select the new folder in the Look In combo box of the Open file dialog */ FILEDLG95_LOOKIN_SelectItem(fodInfos->DlgInfos.hwndLookInCB,fodInfos->ShellInfos.pidlAbsCurrent); /* changes the tab order of the ListView to reflect the window's File Dialog */ hDlgWnd = GetDlgItem(GetParent(hwndView), IDC_LOOKIN); SetWindowPos(hwndView, hDlgWnd, 0,0,0,0, SWP_NOMOVE | SWP_NOSIZE); /* Since we destroyed the old view if it had focus set focus to the newly created view */ if (bViewHasFocus) SetFocus(fodInfos->ShellInfos.hwndView); return hRes; error: ERR("Failed with error 0x%08x\n", hRes); return hRes; }
static BOOL DoPaste(ContextMenu *This) { BOOL bSuccess = FALSE; IDataObject * pda; TRACE("\n"); if(SUCCEEDED(OleGetClipboard(&pda))) { STGMEDIUM medium; FORMATETC formatetc; TRACE("pda=%p\n", pda); /* Set the FORMATETC structure*/ InitFormatEtc(formatetc, RegisterClipboardFormatW(CFSTR_SHELLIDLISTW), TYMED_HGLOBAL); /* Get the pidls from IDataObject */ if(SUCCEEDED(IDataObject_GetData(pda,&formatetc,&medium))) { LPITEMIDLIST * apidl; LPITEMIDLIST pidl; IShellFolder *psfFrom = NULL, *psfDesktop; LPIDA lpcida = GlobalLock(medium.u.hGlobal); TRACE("cida=%p\n", lpcida); apidl = _ILCopyCidaToaPidl(&pidl, lpcida); /* bind to the source shellfolder */ SHGetDesktopFolder(&psfDesktop); if(psfDesktop) { IShellFolder_BindToObject(psfDesktop, pidl, NULL, &IID_IShellFolder, (LPVOID*)&psfFrom); IShellFolder_Release(psfDesktop); } if (psfFrom) { /* get source and destination shellfolder */ ISFHelper *psfhlpdst, *psfhlpsrc; IShellFolder_QueryInterface(This->parent, &IID_ISFHelper, (void**)&psfhlpdst); IShellFolder_QueryInterface(psfFrom, &IID_ISFHelper, (void**)&psfhlpsrc); /* do the copy/move */ if (psfhlpdst && psfhlpsrc) { ISFHelper_CopyItems(psfhlpdst, psfFrom, lpcida->cidl, (LPCITEMIDLIST*)apidl); /* FIXME handle move ISFHelper_DeleteItems(psfhlpsrc, lpcida->cidl, apidl); */ } if(psfhlpdst) ISFHelper_Release(psfhlpdst); if(psfhlpsrc) ISFHelper_Release(psfhlpsrc); IShellFolder_Release(psfFrom); } _ILFreeaPidl(apidl, lpcida->cidl); SHFree(pidl); /* release the medium*/ ReleaseStgMedium(&medium); } IDataObject_Release(pda); } #if 0 HGLOBAL hMem; OpenClipboard(NULL); hMem = GetClipboardData(CF_HDROP); if(hMem) { char * pDropFiles = GlobalLock(hMem); if(pDropFiles) { int len, offset = sizeof(DROPFILESTRUCT); while( pDropFiles[offset] != 0) { len = strlen(pDropFiles + offset); TRACE("%s\n", pDropFiles + offset); offset += len+1; } } GlobalUnlock(hMem); } CloseClipboard(); #endif return bSuccess; }