[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
This commit is contained in:
Giannis Adamopoulos 2015-09-02 13:14:46 +00:00
parent 1ac43d0e3f
commit b228db061a
3 changed files with 96 additions and 94 deletions

View file

@ -38,6 +38,9 @@ CNewMenu::CNewMenu()
CNewMenu::~CNewMenu() CNewMenu::~CNewMenu()
{ {
UnloadAllItems(); UnloadAllItems();
if (m_pidlFolder)
ILFree(m_pidlFolder);
} }
void CNewMenu::UnloadItem(SHELLNEW_ITEM *pItem) void CNewMenu::UnloadItem(SHELLNEW_ITEM *pItem)
@ -296,93 +299,82 @@ CNewMenu::SHELLNEW_ITEM *CNewMenu::FindItemFromIdOffset(UINT IdOffset)
return pItem; return pItem;
} }
HRESULT CNewMenu::CreateNewFolder(IShellView *psv) HRESULT CNewMenu::SelectNewItem(LPCMINVOKECOMMANDINFO lpici, LONG wEventId, UINT uFlags, LPWSTR pszName)
{ {
WCHAR wszName[MAX_PATH]; CComPtr<IShellBrowser> lpSB;
CComPtr<ISFHelper> psfhlp; CComPtr<IShellView> lpSV;
CComPtr<IFolderView> pFolderView; HRESULT hr = E_FAIL;
CComPtr<IShellFolder> 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;
LPITEMIDLIST pidl; LPITEMIDLIST pidl;
PITEMID_CHILD pidlNewItem;
/* Get unique name and create a folder */ /* Notify the view object about the new item */
hr = psfhlp->GetUniqueName(wszName, _countof(wszName)); SHChangeNotify(wEventId, uFlags, (LPCVOID) pszName, NULL);
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;
}
/* Do a labeledit */ /* FIXME: I think that this can be implemented using callbacks to the shell folder */
psv->Refresh();
psv->SelectItem(pidl, SVSI_DESELECTOTHERS | SVSI_EDIT | SVSI_ENSUREVISIBLE | /* Note: CWM_GETISHELLBROWSER returns shell browser without adding reference */
SVSI_FOCUSED | SVSI_SELECT); 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); 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; 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 wszBuf[MAX_PATH];
WCHAR wszPath[MAX_PATH]; WCHAR wszPath[MAX_PATH];
CComPtr<IFolderView> pFolderView;
CComPtr<IShellFolder> pParentFolder;
CComPtr<IPersistFolder2> psf;
HRESULT hr; 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 */ /* Get folder path */
if (pParentFolder == NULL || pParentFolder->GetDisplayNameOf(pidl, SHGDN_FORPARSING, &strTemp) != S_OK) hr = SHGetPathFromIDListW(m_pidlFolder, wszPath);
{ if (FAILED_UNEXPECTEDLY(hr))
ERR("IShellFolder_GetDisplayNameOf failed\n"); return hr;
return E_FAIL;
}
StrRetToBufW(&strTemp, pidl, wszPath, _countof(wszPath));
switch (pItem->Type) switch (pItem->Type)
{ {
@ -468,16 +460,7 @@ HRESULT CNewMenu::CreateNewItem(SHELLNEW_ITEM *pItem, LPCMINVOKECOMMANDINFO lpcm
if (bSuccess) if (bSuccess)
{ {
TRACE("Notifying fs %s\n", debugstr_w(wszPath)); TRACE("Notifying fs %s\n", debugstr_w(wszPath));
SHChangeNotify(SHCNE_CREATE, SHCNF_PATHW, (LPCVOID)wszPath, NULL); SelectNewItem(lpcmi, SHCNE_CREATE, SHCNF_PATHW, wszPath);
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);
}
} }
else else
{ {
@ -551,22 +534,15 @@ HRESULT
WINAPI WINAPI
CNewMenu::InvokeCommand(LPCMINVOKECOMMANDINFO lpici) CNewMenu::InvokeCommand(LPCMINVOKECOMMANDINFO lpici)
{ {
CComPtr<IShellBrowser> lpSB;
CComPtr<IShellView> lpSV;
HRESULT hr = E_FAIL; 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) if (LOWORD(lpici->lpVerb) == 0)
hr = CreateNewFolder(lpSV); hr = CreateNewFolder(lpici);
else else
{ {
SHELLNEW_ITEM *pItem = FindItemFromIdOffset(LOWORD(lpici->lpVerb)); SHELLNEW_ITEM *pItem = FindItemFromIdOffset(LOWORD(lpici->lpVerb));
if (pItem) if (pItem)
hr = CreateNewItem(pItem, lpici, lpSV); hr = CreateNewItem(pItem, lpici);
} }
TRACE("CNewMenu::InvokeCommand %x\n", hr); TRACE("CNewMenu::InvokeCommand %x\n", hr);
@ -657,6 +633,8 @@ HRESULT WINAPI
CNewMenu::Initialize(LPCITEMIDLIST pidlFolder, CNewMenu::Initialize(LPCITEMIDLIST pidlFolder,
IDataObject *pdtobj, HKEY hkeyProgID) IDataObject *pdtobj, HKEY hkeyProgID)
{ {
m_pidlFolder = ILClone(pidlFolder);
/* Load folder and shortcut icons */ /* Load folder and shortcut icons */
m_hiconFolder = (HICON)LoadImage(shell32_hInstance, MAKEINTRESOURCE(IDI_SHELL_FOLDER), IMAGE_ICON, 16, 16, LR_SHARED); 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); m_hiconLink = (HICON)LoadImage(shell32_hInstance, MAKEINTRESOURCE(IDI_SHELL_SHORTCUT), IMAGE_ICON, 16, 16, LR_SHARED);

View file

@ -51,6 +51,7 @@ private:
SHELLNEW_ITEM *pNext; SHELLNEW_ITEM *pNext;
}; };
LPITEMIDLIST m_pidlFolder;
LPWSTR m_wszPath; LPWSTR m_wszPath;
SHELLNEW_ITEM *m_pItems; SHELLNEW_ITEM *m_pItems;
SHELLNEW_ITEM *m_pLinkItem; SHELLNEW_ITEM *m_pLinkItem;
@ -65,8 +66,9 @@ private:
BOOL LoadAllItems(); BOOL LoadAllItems();
UINT InsertShellNewItems(HMENU hMenu, UINT idFirst, UINT idMenu); UINT InsertShellNewItems(HMENU hMenu, UINT idFirst, UINT idMenu);
SHELLNEW_ITEM *FindItemFromIdOffset(UINT IdOffset); SHELLNEW_ITEM *FindItemFromIdOffset(UINT IdOffset);
HRESULT CreateNewFolder(IShellView *psv); HRESULT CreateNewFolder(LPCMINVOKECOMMANDINFO lpici);
HRESULT CreateNewItem(SHELLNEW_ITEM *pItem, LPCMINVOKECOMMANDINFO lpcmi, IShellView *psv); HRESULT CreateNewItem(SHELLNEW_ITEM *pItem, LPCMINVOKECOMMANDINFO lpcmi);
HRESULT SelectNewItem(LPCMINVOKECOMMANDINFO lpici, LONG wEventId, UINT uFlags, LPWSTR pszName);
public: public:
CNewMenu(); CNewMenu();

View file

@ -735,7 +735,12 @@ static HRESULT BrsFolder_NewFolder(browse_info *info)
{ {
DWORD flags = BrowseFlagsToSHCONTF(info->lpBrowseInfo->ulFlags); DWORD flags = BrowseFlagsToSHCONTF(info->lpBrowseInfo->ulFlags);
IShellFolder *desktop, *cur; IShellFolder *desktop, *cur;
#ifdef __REACTOS__
WCHAR wszNewFolder[25];
WCHAR path[25];
#else
ISFHelper *sfhelper; ISFHelper *sfhelper;
#endif
WCHAR name[MAX_PATH]; WCHAR name[MAX_PATH];
HTREEITEM parent, added; HTREEITEM parent, added;
LPTV_ITEMDATA item_data; LPTV_ITEMDATA item_data;
@ -758,6 +763,22 @@ static HRESULT BrsFolder_NewFolder(browse_info *info)
if(FAILED(hr)) if(FAILED(hr))
return hr; return hr;
#ifdef __REACTOS__
hr = SHGetPathFromIDListW(info->pidlRet, path);
if(FAILED(hr))
return hr;
len = strlenW(name);
if(len<MAX_PATH)
len++;
if (!LoadStringW(shell32_hInstance, IDS_NEWFOLDER, wszNewFolder, _countof(wszNewFolder)))
return E_FAIL;
if (!PathYetAnotherMakeUniqueName(name, path, NULL, wszNewFolder))
return E_FAIL;
#else
hr = IShellFolder_QueryInterface(cur, &IID_ISFHelper, (void**)&sfhelper); hr = IShellFolder_QueryInterface(cur, &IID_ISFHelper, (void**)&sfhelper);
if(FAILED(hr)) if(FAILED(hr))
return hr; return hr;
@ -765,7 +786,7 @@ static HRESULT BrsFolder_NewFolder(browse_info *info)
hr = SHGetPathFromIDListW(info->pidlRet, name); hr = SHGetPathFromIDListW(info->pidlRet, name);
if(FAILED(hr)) if(FAILED(hr))
goto cleanup; goto cleanup;
len = strlenW(name); len = strlenW(name);
if(len<MAX_PATH) if(len<MAX_PATH)
name[len++] = '\\'; name[len++] = '\\';
@ -773,6 +794,7 @@ static HRESULT BrsFolder_NewFolder(browse_info *info)
ISFHelper_Release(sfhelper); ISFHelper_Release(sfhelper);
if(FAILED(hr)) if(FAILED(hr))
goto cleanup; goto cleanup;
#endif
hr = E_FAIL; hr = E_FAIL;
if(!CreateDirectoryW(name, NULL)) if(!CreateDirectoryW(name, NULL))