From b228db061ac7474524bf1a0da9297146347a8991 Mon Sep 17 00:00:00 2001 From: Giannis Adamopoulos Date: Wed, 2 Sep 2015 13:14:46 +0000 Subject: [PATCH] [SHELL32] - CNewMenu: Get the folder path from the pidl passed in the Initialize method. No need to query the defview for that. - Dont use a reactos only interface to create a new directory. Prefer to do it with less code using exported functions. - Add a new SelectNewItem method that is used when creating a new file or directory. - Apply same fix for browse for folder dialog. svn path=/trunk/; revision=68915 --- reactos/dll/win32/shell32/CNewMenu.cpp | 160 +++++++++------------ reactos/dll/win32/shell32/CNewMenu.h | 6 +- reactos/dll/win32/shell32/wine/brsfolder.c | 24 +++- 3 files changed, 96 insertions(+), 94 deletions(-) diff --git a/reactos/dll/win32/shell32/CNewMenu.cpp b/reactos/dll/win32/shell32/CNewMenu.cpp index ec5e52be7c1..2bdeb456075 100644 --- a/reactos/dll/win32/shell32/CNewMenu.cpp +++ b/reactos/dll/win32/shell32/CNewMenu.cpp @@ -38,6 +38,9 @@ CNewMenu::CNewMenu() CNewMenu::~CNewMenu() { UnloadAllItems(); + + if (m_pidlFolder) + ILFree(m_pidlFolder); } void CNewMenu::UnloadItem(SHELLNEW_ITEM *pItem) @@ -296,93 +299,82 @@ CNewMenu::SHELLNEW_ITEM *CNewMenu::FindItemFromIdOffset(UINT IdOffset) return pItem; } -HRESULT CNewMenu::CreateNewFolder(IShellView *psv) +HRESULT CNewMenu::SelectNewItem(LPCMINVOKECOMMANDINFO lpici, LONG wEventId, UINT uFlags, LPWSTR pszName) { - WCHAR wszName[MAX_PATH]; - CComPtr psfhlp; - CComPtr pFolderView; - CComPtr pParentFolder; - HRESULT hr; - - //if (m_pSite == NULL) - // return E_FAIL; - - /* Get current folder */ - hr = IUnknown_QueryService(psv, SID_IFolderView, IID_PPV_ARG(IFolderView, &pFolderView)); - if (FAILED(hr)) - return hr; - - hr = pFolderView->GetFolder(IID_PPV_ARG(IShellFolder, &pParentFolder)); - if (FAILED(hr)) - return hr; - - hr = pParentFolder->QueryInterface(IID_PPV_ARG(ISFHelper, &psfhlp)); - if (FAILED(hr)) - return hr; - + CComPtr lpSB; + CComPtr lpSV; + HRESULT hr = E_FAIL; LPITEMIDLIST pidl; + PITEMID_CHILD pidlNewItem; - /* Get unique name and create a folder */ - hr = psfhlp->GetUniqueName(wszName, _countof(wszName)); - if (hr != S_OK) - return hr; - hr = psfhlp->AddFolder(0, wszName, &pidl); - if (hr != S_OK) - { - WCHAR wszBuf[256]; - StringCbPrintfW(wszBuf, sizeof(wszBuf), L"Cannot create folder: %s", wszName); - MessageBoxW(NULL, wszBuf, L"Cannot create folder", MB_OK|MB_ICONERROR); - return hr; - } + /* Notify the view object about the new item */ + SHChangeNotify(wEventId, uFlags, (LPCVOID) pszName, NULL); - /* Do a labeledit */ - psv->Refresh(); - psv->SelectItem(pidl, SVSI_DESELECTOTHERS | SVSI_EDIT | SVSI_ENSUREVISIBLE | - SVSI_FOCUSED | SVSI_SELECT); + /* 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; +} + +HRESULT CNewMenu::CreateNewFolder(LPCMINVOKECOMMANDINFO lpici) +{ + WCHAR wszPath[MAX_PATH]; + WCHAR wszName[MAX_PATH]; + WCHAR wszNewFolder[25]; + HRESULT hr; + + /* Get folder path */ + hr = SHGetPathFromIDListW(m_pidlFolder, wszPath); + if (FAILED_UNEXPECTEDLY(hr)) + return hr; + + if (!LoadStringW(shell32_hInstance, IDS_NEWFOLDER, wszNewFolder, _countof(wszNewFolder))) + return E_FAIL; + + /* Create the name of the new directory */ + if (!PathYetAnotherMakeUniqueName(wszName, wszPath, NULL, wszNewFolder)) + return E_FAIL; + + /* Create the new directory and show the appropriate dialog in case of error */ + if (SHCreateDirectory (lpici->hwnd, wszName) != ERROR_SUCCESS) + return E_FAIL; + + /* Show and select the new item in the def view */ + SelectNewItem(lpici, SHCNE_MKDIR, SHCNF_PATHW, wszName); + return S_OK; } -HRESULT CNewMenu::CreateNewItem(SHELLNEW_ITEM *pItem, LPCMINVOKECOMMANDINFO lpcmi, IShellView *psv) +HRESULT CNewMenu::CreateNewItem(SHELLNEW_ITEM *pItem, LPCMINVOKECOMMANDINFO lpcmi) { - LPITEMIDLIST pidl; - STRRET strTemp; WCHAR wszBuf[MAX_PATH]; WCHAR wszPath[MAX_PATH]; - CComPtr pFolderView; - CComPtr pParentFolder; - CComPtr psf; HRESULT hr; - /* Get current folder */ - hr = IUnknown_QueryService(psv, SID_IFolderView, IID_PPV_ARG(IFolderView, &pFolderView)); - if (FAILED(hr)) - return hr; - - hr = pFolderView->GetFolder(IID_PPV_ARG(IShellFolder, &pParentFolder)); - if (FAILED(hr)) - return hr; - - if (pParentFolder->QueryInterface(IID_PPV_ARG(IPersistFolder2, &psf)) != S_OK) - { - ERR("Failed to get interface IID_IPersistFolder2\n"); - return E_FAIL; - } - - if (psf->GetCurFolder(&pidl) != S_OK) - { - ERR("IPersistFolder2_GetCurFolder failed\n"); - return E_FAIL; - } - /* Get folder path */ - if (pParentFolder == NULL || pParentFolder->GetDisplayNameOf(pidl, SHGDN_FORPARSING, &strTemp) != S_OK) - { - ERR("IShellFolder_GetDisplayNameOf failed\n"); - return E_FAIL; - } - StrRetToBufW(&strTemp, pidl, wszPath, _countof(wszPath)); + hr = SHGetPathFromIDListW(m_pidlFolder, wszPath); + if (FAILED_UNEXPECTEDLY(hr)) + return hr; switch (pItem->Type) { @@ -468,16 +460,7 @@ HRESULT CNewMenu::CreateNewItem(SHELLNEW_ITEM *pItem, LPCMINVOKECOMMANDINFO lpcm if (bSuccess) { TRACE("Notifying fs %s\n", debugstr_w(wszPath)); - SHChangeNotify(SHCNE_CREATE, SHCNF_PATHW, (LPCVOID)wszPath, NULL); - psv->Refresh(); - - LPITEMIDLIST pidl; - hr = _ILCreateFromPathW(wszPath, &pidl); - if (SUCCEEDED(hr)) - { - psv->SelectItem(pidl, SVSI_DESELECTOTHERS|SVSI_EDIT|SVSI_ENSUREVISIBLE|SVSI_FOCUSED|SVSI_SELECT); - ILFree(pidl); - } + SelectNewItem(lpcmi, SHCNE_CREATE, SHCNF_PATHW, wszPath); } else { @@ -551,22 +534,15 @@ HRESULT WINAPI CNewMenu::InvokeCommand(LPCMINVOKECOMMANDINFO lpici) { - CComPtr lpSB; - CComPtr lpSV; HRESULT hr = E_FAIL; - /* Note: CWM_GETISHELLBROWSER returns shell browser without adding reference */ - lpSB = (LPSHELLBROWSER)SendMessageA(lpici->hwnd, CWM_GETISHELLBROWSER, 0, 0); - if (lpSB) - lpSB->QueryActiveShellView(&lpSV); - if (LOWORD(lpici->lpVerb) == 0) - hr = CreateNewFolder(lpSV); + hr = CreateNewFolder(lpici); else { SHELLNEW_ITEM *pItem = FindItemFromIdOffset(LOWORD(lpici->lpVerb)); if (pItem) - hr = CreateNewItem(pItem, lpici, lpSV); + hr = CreateNewItem(pItem, lpici); } TRACE("CNewMenu::InvokeCommand %x\n", hr); @@ -657,6 +633,8 @@ HRESULT WINAPI CNewMenu::Initialize(LPCITEMIDLIST pidlFolder, IDataObject *pdtobj, HKEY hkeyProgID) { + m_pidlFolder = ILClone(pidlFolder); + /* Load folder and shortcut icons */ m_hiconFolder = (HICON)LoadImage(shell32_hInstance, MAKEINTRESOURCE(IDI_SHELL_FOLDER), IMAGE_ICON, 16, 16, LR_SHARED); m_hiconLink = (HICON)LoadImage(shell32_hInstance, MAKEINTRESOURCE(IDI_SHELL_SHORTCUT), IMAGE_ICON, 16, 16, LR_SHARED); diff --git a/reactos/dll/win32/shell32/CNewMenu.h b/reactos/dll/win32/shell32/CNewMenu.h index 63538343efd..d68e4da3d9d 100644 --- a/reactos/dll/win32/shell32/CNewMenu.h +++ b/reactos/dll/win32/shell32/CNewMenu.h @@ -51,6 +51,7 @@ private: SHELLNEW_ITEM *pNext; }; + LPITEMIDLIST m_pidlFolder; LPWSTR m_wszPath; SHELLNEW_ITEM *m_pItems; SHELLNEW_ITEM *m_pLinkItem; @@ -65,8 +66,9 @@ private: BOOL LoadAllItems(); UINT InsertShellNewItems(HMENU hMenu, UINT idFirst, UINT idMenu); SHELLNEW_ITEM *FindItemFromIdOffset(UINT IdOffset); - HRESULT CreateNewFolder(IShellView *psv); - HRESULT CreateNewItem(SHELLNEW_ITEM *pItem, LPCMINVOKECOMMANDINFO lpcmi, IShellView *psv); + HRESULT CreateNewFolder(LPCMINVOKECOMMANDINFO lpici); + HRESULT CreateNewItem(SHELLNEW_ITEM *pItem, LPCMINVOKECOMMANDINFO lpcmi); + HRESULT SelectNewItem(LPCMINVOKECOMMANDINFO lpici, LONG wEventId, UINT uFlags, LPWSTR pszName); public: CNewMenu(); diff --git a/reactos/dll/win32/shell32/wine/brsfolder.c b/reactos/dll/win32/shell32/wine/brsfolder.c index aea6f2c0d6a..96636a33611 100644 --- a/reactos/dll/win32/shell32/wine/brsfolder.c +++ b/reactos/dll/win32/shell32/wine/brsfolder.c @@ -735,7 +735,12 @@ static HRESULT BrsFolder_NewFolder(browse_info *info) { DWORD flags = BrowseFlagsToSHCONTF(info->lpBrowseInfo->ulFlags); IShellFolder *desktop, *cur; +#ifdef __REACTOS__ + WCHAR wszNewFolder[25]; + WCHAR path[25]; +#else ISFHelper *sfhelper; +#endif WCHAR name[MAX_PATH]; HTREEITEM parent, added; LPTV_ITEMDATA item_data; @@ -758,6 +763,22 @@ static HRESULT BrsFolder_NewFolder(browse_info *info) if(FAILED(hr)) return hr; +#ifdef __REACTOS__ + hr = SHGetPathFromIDListW(info->pidlRet, path); + if(FAILED(hr)) + return hr; + + len = strlenW(name); + if(lenpidlRet, name); if(FAILED(hr)) goto cleanup; - + len = strlenW(name); if(len