shell32: Implement SHGetNameFromIDList and IShellItem::GetDisplayName.
This commit is contained in:
parent
0d18e35b28
commit
b43bcdf524
@ -1347,6 +1347,68 @@ HRESULT WINAPI SHParseDisplayName(LPCWSTR name, IBindCtx *bindctx, LPITEMIDLIST
|
|||||||
return hr;
|
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
|
* internal functions
|
||||||
|
@ -360,6 +360,7 @@
|
|||||||
@ stdcall SHGetInstanceExplorer(long)
|
@ stdcall SHGetInstanceExplorer(long)
|
||||||
@ stdcall SHGetLocalizedName(wstr ptr long ptr)
|
@ stdcall SHGetLocalizedName(wstr ptr long ptr)
|
||||||
@ stdcall SHGetMalloc(ptr)
|
@ stdcall SHGetMalloc(ptr)
|
||||||
|
@ stdcall SHGetNameFromIDList(ptr long ptr)
|
||||||
@ stdcall SHGetNewLinkInfo(str str ptr long long) SHGetNewLinkInfoA
|
@ stdcall SHGetNewLinkInfo(str str ptr long long) SHGetNewLinkInfoA
|
||||||
@ stdcall SHGetPathFromIDList(ptr ptr) SHGetPathFromIDListA
|
@ stdcall SHGetPathFromIDList(ptr ptr) SHGetPathFromIDListA
|
||||||
@ stdcall SHGetPathFromIDListA(ptr ptr)
|
@ stdcall SHGetPathFromIDListA(ptr ptr)
|
||||||
|
@ -178,11 +178,10 @@ static HRESULT WINAPI ShellItem_GetParent(IShellItem *iface, IShellItem **ppsi)
|
|||||||
static HRESULT WINAPI ShellItem_GetDisplayName(IShellItem *iface, SIGDN sigdnName,
|
static HRESULT WINAPI ShellItem_GetDisplayName(IShellItem *iface, SIGDN sigdnName,
|
||||||
LPWSTR *ppszName)
|
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 SHGetNameFromIDList(This->pidl, sigdnName, ppszName);
|
||||||
|
|
||||||
return E_NOTIMPL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT WINAPI ShellItem_GetAttributes(IShellItem *iface, SFGAOF sfgaoMask,
|
static HRESULT WINAPI ShellItem_GetAttributes(IShellItem *iface, SFGAOF sfgaoMask,
|
||||||
|
@ -46,6 +46,7 @@ static HRESULT (WINAPI *pSHBindToParent)(LPCITEMIDLIST, REFIID, LPVOID*, LPCITEM
|
|||||||
static HRESULT (WINAPI *pSHGetFolderPathA)(HWND, int, HANDLE, DWORD, LPSTR);
|
static HRESULT (WINAPI *pSHGetFolderPathA)(HWND, int, HANDLE, DWORD, LPSTR);
|
||||||
static HRESULT (WINAPI *pSHGetFolderPathAndSubDirA)(HWND, int, HANDLE, DWORD, LPCSTR, LPSTR);
|
static HRESULT (WINAPI *pSHGetFolderPathAndSubDirA)(HWND, int, HANDLE, DWORD, LPCSTR, LPSTR);
|
||||||
static BOOL (WINAPI *pSHGetPathFromIDListW)(LPCITEMIDLIST,LPWSTR);
|
static BOOL (WINAPI *pSHGetPathFromIDListW)(LPCITEMIDLIST,LPWSTR);
|
||||||
|
static HRESULT (WINAPI *pSHGetSpecialFolderLocation)(HWND, int, LPITEMIDLIST *);
|
||||||
static BOOL (WINAPI *pSHGetSpecialFolderPathA)(HWND, LPSTR, int, BOOL);
|
static BOOL (WINAPI *pSHGetSpecialFolderPathA)(HWND, LPSTR, int, BOOL);
|
||||||
static BOOL (WINAPI *pSHGetSpecialFolderPathW)(HWND, LPWSTR, int, BOOL);
|
static BOOL (WINAPI *pSHGetSpecialFolderPathW)(HWND, LPWSTR, int, BOOL);
|
||||||
static HRESULT (WINAPI *pStrRetToBufW)(STRRET*,LPCITEMIDLIST,LPWSTR,UINT);
|
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 LPITEMIDLIST (WINAPI *pILCombine)(LPCITEMIDLIST,LPCITEMIDLIST);
|
||||||
static HRESULT (WINAPI *pSHParseDisplayName)(LPCWSTR,IBindCtx*,LPITEMIDLIST*,SFGAOF,SFGAOF*);
|
static HRESULT (WINAPI *pSHParseDisplayName)(LPCWSTR,IBindCtx*,LPITEMIDLIST*,SFGAOF,SFGAOF*);
|
||||||
static LPITEMIDLIST (WINAPI *pSHSimpleIDListFromPathAW)(LPCVOID);
|
static LPITEMIDLIST (WINAPI *pSHSimpleIDListFromPathAW)(LPCVOID);
|
||||||
|
static HRESULT (WINAPI *pSHGetNameFromIDList)(PCIDLIST_ABSOLUTE,SIGDN,PWSTR*);
|
||||||
|
|
||||||
static void init_function_pointers(void)
|
static void init_function_pointers(void)
|
||||||
{
|
{
|
||||||
@ -73,7 +75,9 @@ static void init_function_pointers(void)
|
|||||||
MAKEFUNC(SHGetPathFromIDListW);
|
MAKEFUNC(SHGetPathFromIDListW);
|
||||||
MAKEFUNC(SHGetSpecialFolderPathA);
|
MAKEFUNC(SHGetSpecialFolderPathA);
|
||||||
MAKEFUNC(SHGetSpecialFolderPathW);
|
MAKEFUNC(SHGetSpecialFolderPathW);
|
||||||
|
MAKEFUNC(SHGetSpecialFolderLocation);
|
||||||
MAKEFUNC(SHParseDisplayName);
|
MAKEFUNC(SHParseDisplayName);
|
||||||
|
MAKEFUNC(SHGetNameFromIDList);
|
||||||
#undef MAKEFUNC
|
#undef MAKEFUNC
|
||||||
|
|
||||||
#define MAKEFUNC_ORD(f, ord) (p##f = (void*)GetProcAddress(hmod, (LPSTR)(ord)))
|
#define MAKEFUNC_ORD(f, ord) (p##f = (void*)GetProcAddress(hmod, (LPSTR)(ord)))
|
||||||
@ -987,8 +991,6 @@ static void test_SHGetPathFromIDList(void)
|
|||||||
STRRET strret;
|
STRRET strret;
|
||||||
static WCHAR wszTestFile[] = {
|
static WCHAR wszTestFile[] = {
|
||||||
'w','i','n','e','t','e','s','t','.','f','o','o',0 };
|
'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)
|
if(!pSHGetPathFromIDListW || !pSHGetSpecialFolderPathW)
|
||||||
@ -1102,9 +1104,6 @@ static void test_SHGetPathFromIDList(void)
|
|||||||
|
|
||||||
|
|
||||||
/* Test if we can get the path from the start menu "program files" PIDL. */
|
/* Test if we can get the path from the start menu "program files" PIDL. */
|
||||||
hShell32 = GetModuleHandleA("shell32");
|
|
||||||
pSHGetSpecialFolderLocation = (void *)GetProcAddress(hShell32, "SHGetSpecialFolderLocation");
|
|
||||||
|
|
||||||
hr = pSHGetSpecialFolderLocation(NULL, CSIDL_PROGRAM_FILES, &pidlPrograms);
|
hr = pSHGetSpecialFolderLocation(NULL, CSIDL_PROGRAM_FILES, &pidlPrograms);
|
||||||
ok(hr == S_OK, "SHGetFolderLocation failed: 0x%08x\n", hr);
|
ok(hr == S_OK, "SHGetFolderLocation failed: 0x%08x\n", hr);
|
||||||
|
|
||||||
@ -2044,6 +2043,154 @@ static void test_SHCreateShellItem(void)
|
|||||||
IShellFolder_Release(desktopfolder);
|
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)
|
static void test_SHParseDisplayName(void)
|
||||||
{
|
{
|
||||||
LPITEMIDLIST pidl1, pidl2;
|
LPITEMIDLIST pidl1, pidl2;
|
||||||
@ -2549,6 +2696,7 @@ START_TEST(shlfolder)
|
|||||||
test_GetUIObject();
|
test_GetUIObject();
|
||||||
test_SHSimpleIDListFromPath();
|
test_SHSimpleIDListFromPath();
|
||||||
test_ParseDisplayNamePBC();
|
test_ParseDisplayNamePBC();
|
||||||
|
test_SHGetNameFromIDList();
|
||||||
|
|
||||||
OleUninitialize();
|
OleUninitialize();
|
||||||
}
|
}
|
||||||
|
@ -494,6 +494,8 @@ interface IShellItemArray : IUnknown
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cpp_quote("HRESULT WINAPI SHGetNameFromIDList(PCIDLIST_ABSOLUTE pidl, SIGDN sigdnName, PWSTR *ppszName);")
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* IShellItemFilter interface
|
* IShellItemFilter interface
|
||||||
*/
|
*/
|
||||||
|
Loading…
x
Reference in New Issue
Block a user