shell32: Implement SHGetNameFromIDList and IShellItem::GetDisplayName.

This commit is contained in:
David Hedberg 2010-07-22 20:17:02 +02:00 committed by Alexandre Julliard
parent 0d18e35b28
commit b43bcdf524
5 changed files with 223 additions and 11 deletions

View File

@ -1347,6 +1347,68 @@ HRESULT WINAPI SHParseDisplayName(LPCWSTR name, IBindCtx *bindctx, LPITEMIDLIST
return hr;
}
/*************************************************************************
* SHGetNameFromIDList [SHELL32.@]
*/
HRESULT WINAPI SHGetNameFromIDList(PCIDLIST_ABSOLUTE pidl, SIGDN sigdnName, PWSTR *ppszName)
{
IShellFolder *psfparent;
LPCITEMIDLIST child_pidl;
STRRET disp_name;
HRESULT ret;
TRACE("%p %d %p\n", pidl, sigdnName, ppszName);
*ppszName = NULL;
ret = SHBindToParent(pidl, &IID_IShellFolder, (void**)&psfparent, &child_pidl);
if(SUCCEEDED(ret))
{
switch(sigdnName)
{
/* sigdnName & 0xffff */
case SIGDN_NORMALDISPLAY: /* SHGDN_NORMAL */
case SIGDN_PARENTRELATIVEPARSING: /* SHGDN_INFOLDER | SHGDN_FORPARSING */
case SIGDN_PARENTRELATIVEEDITING: /* SHGDN_INFOLDER | SHGDN_FOREDITING */
case SIGDN_DESKTOPABSOLUTEPARSING: /* SHGDN_FORPARSING */
case SIGDN_DESKTOPABSOLUTEEDITING: /* SHGDN_FOREDITING | SHGDN_FORADDRESSBAR*/
case SIGDN_PARENTRELATIVEFORADDRESSBAR: /* SIGDN_INFOLDER | SHGDN_FORADDRESSBAR */
case SIGDN_PARENTRELATIVE: /* SIGDN_INFOLDER */
disp_name.uType = STRRET_WSTR;
ret = IShellFolder_GetDisplayNameOf(psfparent, child_pidl,
sigdnName & 0xffff,
&disp_name);
if(SUCCEEDED(ret))
ret = StrRetToStrW(&disp_name, pidl, ppszName);
break;
case SIGDN_FILESYSPATH:
*ppszName = CoTaskMemAlloc(sizeof(WCHAR)*MAX_PATH);
if(SHGetPathFromIDListW(pidl, *ppszName))
{
TRACE("Got string %s\n", debugstr_w(*ppszName));
ret = S_OK;
}
else
{
CoTaskMemFree(*ppszName);
ret = E_INVALIDARG;
}
break;
case SIGDN_URL:
default:
FIXME("Unsupported SIGDN %x\n", sigdnName);
ret = E_FAIL;
}
IShellFolder_Release(psfparent);
}
return ret;
}
/**************************************************************************
*
* internal functions

View File

@ -360,6 +360,7 @@
@ stdcall SHGetInstanceExplorer(long)
@ stdcall SHGetLocalizedName(wstr ptr long ptr)
@ stdcall SHGetMalloc(ptr)
@ stdcall SHGetNameFromIDList(ptr long ptr)
@ stdcall SHGetNewLinkInfo(str str ptr long long) SHGetNewLinkInfoA
@ stdcall SHGetPathFromIDList(ptr ptr) SHGetPathFromIDListA
@ stdcall SHGetPathFromIDListA(ptr ptr)

View File

@ -178,11 +178,10 @@ static HRESULT WINAPI ShellItem_GetParent(IShellItem *iface, IShellItem **ppsi)
static HRESULT WINAPI ShellItem_GetDisplayName(IShellItem *iface, SIGDN sigdnName,
LPWSTR *ppszName)
{
FIXME("(%p,%x,%p)\n", iface, sigdnName, ppszName);
ShellItem *This = (ShellItem*)iface;
TRACE("(%p,%x,%p)\n", iface, sigdnName, ppszName);
*ppszName = NULL;
return E_NOTIMPL;
return SHGetNameFromIDList(This->pidl, sigdnName, ppszName);
}
static HRESULT WINAPI ShellItem_GetAttributes(IShellItem *iface, SFGAOF sfgaoMask,

View File

@ -46,6 +46,7 @@ static HRESULT (WINAPI *pSHBindToParent)(LPCITEMIDLIST, REFIID, LPVOID*, LPCITEM
static HRESULT (WINAPI *pSHGetFolderPathA)(HWND, int, HANDLE, DWORD, LPSTR);
static HRESULT (WINAPI *pSHGetFolderPathAndSubDirA)(HWND, int, HANDLE, DWORD, LPCSTR, LPSTR);
static BOOL (WINAPI *pSHGetPathFromIDListW)(LPCITEMIDLIST,LPWSTR);
static HRESULT (WINAPI *pSHGetSpecialFolderLocation)(HWND, int, LPITEMIDLIST *);
static BOOL (WINAPI *pSHGetSpecialFolderPathA)(HWND, LPSTR, int, BOOL);
static BOOL (WINAPI *pSHGetSpecialFolderPathW)(HWND, LPWSTR, int, BOOL);
static HRESULT (WINAPI *pStrRetToBufW)(STRRET*,LPCITEMIDLIST,LPWSTR,UINT);
@ -56,6 +57,7 @@ static HRESULT (WINAPI *pSHCreateShellItem)(LPCITEMIDLIST,IShellFolder*,LPCITEMI
static LPITEMIDLIST (WINAPI *pILCombine)(LPCITEMIDLIST,LPCITEMIDLIST);
static HRESULT (WINAPI *pSHParseDisplayName)(LPCWSTR,IBindCtx*,LPITEMIDLIST*,SFGAOF,SFGAOF*);
static LPITEMIDLIST (WINAPI *pSHSimpleIDListFromPathAW)(LPCVOID);
static HRESULT (WINAPI *pSHGetNameFromIDList)(PCIDLIST_ABSOLUTE,SIGDN,PWSTR*);
static void init_function_pointers(void)
{
@ -73,7 +75,9 @@ static void init_function_pointers(void)
MAKEFUNC(SHGetPathFromIDListW);
MAKEFUNC(SHGetSpecialFolderPathA);
MAKEFUNC(SHGetSpecialFolderPathW);
MAKEFUNC(SHGetSpecialFolderLocation);
MAKEFUNC(SHParseDisplayName);
MAKEFUNC(SHGetNameFromIDList);
#undef MAKEFUNC
#define MAKEFUNC_ORD(f, ord) (p##f = (void*)GetProcAddress(hmod, (LPSTR)(ord)))
@ -987,9 +991,7 @@ static void test_SHGetPathFromIDList(void)
STRRET strret;
static WCHAR wszTestFile[] = {
'w','i','n','e','t','e','s','t','.','f','o','o',0 };
HRESULT (WINAPI *pSHGetSpecialFolderLocation)(HWND, int, LPITEMIDLIST *);
HMODULE hShell32;
LPITEMIDLIST pidlPrograms;
LPITEMIDLIST pidlPrograms;
if(!pSHGetPathFromIDListW || !pSHGetSpecialFolderPathW)
{
@ -1101,10 +1103,7 @@ static void test_SHGetPathFromIDList(void)
ok(0 == lstrcmpW(wszFileName, wszPath), "SHGetPathFromIDListW returned incorrect path for file placed on desktop\n");
/* Test if we can get the path from the start menu "program files" PIDL. */
hShell32 = GetModuleHandleA("shell32");
pSHGetSpecialFolderLocation = (void *)GetProcAddress(hShell32, "SHGetSpecialFolderLocation");
/* Test if we can get the path from the start menu "program files" PIDL. */
hr = pSHGetSpecialFolderLocation(NULL, CSIDL_PROGRAM_FILES, &pidlPrograms);
ok(hr == S_OK, "SHGetFolderLocation failed: 0x%08x\n", hr);
@ -2044,6 +2043,154 @@ static void test_SHCreateShellItem(void)
IShellFolder_Release(desktopfolder);
}
static void test_SHGetNameFromIDList(void)
{
IShellItem *shellitem;
LPITEMIDLIST pidl;
LPWSTR name_string;
HRESULT hres;
UINT i;
static const DWORD flags[] = {
SIGDN_NORMALDISPLAY, SIGDN_PARENTRELATIVEPARSING,
SIGDN_DESKTOPABSOLUTEPARSING,SIGDN_PARENTRELATIVEEDITING,
SIGDN_DESKTOPABSOLUTEEDITING, /*SIGDN_FILESYSPATH, SIGDN_URL, */
SIGDN_PARENTRELATIVEFORADDRESSBAR,SIGDN_PARENTRELATIVE, -1234};
if(!pSHGetNameFromIDList)
{
win_skip("SHGetNameFromIDList missing.\n");
return;
}
/* These should be available on any platform that passed the above test. */
ok(pSHCreateShellItem != NULL, "SHCreateShellItem missing.\n");
ok(pSHBindToParent != NULL, "SHBindToParent missing.\n");
ok(pSHGetSpecialFolderLocation != NULL, "SHGetSpecialFolderLocation missing.\n");
ok(pStrRetToBufW != NULL, "StrRetToBufW missing.\n");
if(0)
{
/* Crashes under win7 */
hres = pSHGetNameFromIDList(NULL, 0, NULL);
}
hres = pSHGetNameFromIDList(NULL, 0, &name_string);
ok(hres == E_INVALIDARG, "Got 0x%08x\n", hres);
/* Test the desktop */
hres = pSHGetSpecialFolderLocation(NULL, CSIDL_DESKTOP, &pidl);
ok(hres == S_OK, "Got 0x%08x\n", hres);
hres = pSHCreateShellItem(NULL, NULL, pidl, &shellitem);
ok(hres == S_OK, "Got 0x%08x\n", hres);
if(SUCCEEDED(hres))
{
WCHAR *nameSI, *nameSH;
WCHAR buf[MAX_PATH];
HRESULT hrSI, hrSH, hrSF;
STRRET strret;
IShellFolder *psf;
BOOL res;
SHGetDesktopFolder(&psf);
for(i = 0; flags[i] != -1234; i++)
{
hrSI = IShellItem_GetDisplayName(shellitem, flags[i], &nameSI);
ok(hrSI == S_OK, "Got 0x%08x\n", hrSI);
hrSH = pSHGetNameFromIDList(pidl, flags[i], &nameSH);
ok(hrSH == S_OK, "Got 0x%08x\n", hrSH);
hrSF = IShellFolder_GetDisplayNameOf(psf, pidl, flags[i] & 0xffff, &strret);
ok(hrSF == S_OK, "Got 0x%08x\n", hrSF);
if(SUCCEEDED(hrSI) && SUCCEEDED(hrSH))
ok(!lstrcmpW(nameSI, nameSH), "Strings differ.\n");
if(SUCCEEDED(hrSF))
{
pStrRetToBufW(&strret, NULL, buf, MAX_PATH);
if(SUCCEEDED(hrSI))
ok(!lstrcmpW(nameSI, buf), "Strings differ.\n");
if(SUCCEEDED(hrSF))
ok(!lstrcmpW(nameSI, buf), "Strings differ.\n");
}
if(SUCCEEDED(hrSI)) CoTaskMemFree(nameSI);
if(SUCCEEDED(hrSH)) CoTaskMemFree(nameSH);
}
IShellFolder_Release(psf);
hrSI = pSHGetNameFromIDList(pidl, SIGDN_FILESYSPATH, &nameSI);
ok(hrSI == S_OK, "Got 0x%08x\n", hrSI);
res = SHGetPathFromIDListW(pidl, buf);
ok(res == TRUE, "Got %d\n", res);
if(SUCCEEDED(hrSI) && res)
ok(!lstrcmpW(nameSI, buf), "Strings differ.\n");
if(SUCCEEDED(hrSI)) CoTaskMemFree(nameSI);
hres = pSHGetNameFromIDList(pidl, SIGDN_URL, &name_string);
todo_wine ok(hres == S_OK, "Got 0x%08x\n", hres);
if(SUCCEEDED(hres)) CoTaskMemFree(name_string);
IShellItem_Release(shellitem);
}
pILFree(pidl);
/* Test the control panel */
hres = pSHGetSpecialFolderLocation(NULL, CSIDL_CONTROLS, &pidl);
ok(hres == S_OK, "Got 0x%08x\n", hres);
hres = pSHCreateShellItem(NULL, NULL, pidl, &shellitem);
ok(hres == S_OK, "Got 0x%08x\n", hres);
if(SUCCEEDED(hres))
{
WCHAR *nameSI, *nameSH;
WCHAR buf[MAX_PATH];
HRESULT hrSI, hrSH, hrSF;
STRRET strret;
IShellFolder *psf;
BOOL res;
SHGetDesktopFolder(&psf);
for(i = 0; flags[i] != -1234; i++)
{
hrSI = IShellItem_GetDisplayName(shellitem, flags[i], &nameSI);
ok(hrSI == S_OK, "Got 0x%08x\n", hrSI);
hrSH = pSHGetNameFromIDList(pidl, flags[i], &nameSH);
ok(hrSH == S_OK, "Got 0x%08x\n", hrSH);
hrSF = IShellFolder_GetDisplayNameOf(psf, pidl, flags[i] & 0xffff, &strret);
ok(hrSF == S_OK, "Got 0x%08x\n", hrSF);
if(SUCCEEDED(hrSI) && SUCCEEDED(hrSH))
ok(!lstrcmpW(nameSI, nameSH), "Strings differ.\n");
if(SUCCEEDED(hrSF))
{
pStrRetToBufW(&strret, NULL, buf, MAX_PATH);
if(SUCCEEDED(hrSI))
ok(!lstrcmpW(nameSI, buf), "Strings differ.\n");
if(SUCCEEDED(hrSF))
ok(!lstrcmpW(nameSI, buf), "Strings differ.\n");
}
if(SUCCEEDED(hrSI)) CoTaskMemFree(nameSI);
if(SUCCEEDED(hrSH)) CoTaskMemFree(nameSH);
}
IShellFolder_Release(psf);
hrSI = pSHGetNameFromIDList(pidl, SIGDN_FILESYSPATH, &nameSI);
ok(hrSI == E_INVALIDARG, "Got 0x%08x\n", hrSI);
res = SHGetPathFromIDListW(pidl, buf);
ok(res == FALSE, "Got %d\n", res);
if(SUCCEEDED(hrSI) && res)
ok(!lstrcmpW(nameSI, buf), "Strings differ.\n");
if(SUCCEEDED(hrSI)) CoTaskMemFree(nameSI);
hres = pSHGetNameFromIDList(pidl, SIGDN_URL, &name_string);
todo_wine ok(hres == E_NOTIMPL /* Win7 */ || hres == S_OK /* Vista */,
"Got 0x%08x\n", hres);
if(SUCCEEDED(hres)) CoTaskMemFree(name_string);
IShellItem_Release(shellitem);
}
pILFree(pidl);
}
static void test_SHParseDisplayName(void)
{
LPITEMIDLIST pidl1, pidl2;
@ -2549,6 +2696,7 @@ START_TEST(shlfolder)
test_GetUIObject();
test_SHSimpleIDListFromPath();
test_ParseDisplayNamePBC();
test_SHGetNameFromIDList();
OleUninitialize();
}

View File

@ -494,6 +494,8 @@ interface IShellItemArray : IUnknown
}
cpp_quote("HRESULT WINAPI SHGetNameFromIDList(PCIDLIST_ABSOLUTE pidl, SIGDN sigdnName, PWSTR *ppszName);")
/*****************************************************************************
* IShellItemFilter interface
*/