- Fix several bugs in printer ' IShellFolder implementation

- Partly implement IShellFolder::GetAttributesOf
- Implement IShellFolder::GetDisplayNameOf for root pidl
- Implement ISF_ControlPanel_fnParseDisplayName to parse display names
<spoiler>Gets rid of the annoying message box when clicking on the printer folder in the start menu</spoiler>

svn path=/trunk/; revision=43094
This commit is contained in:
Johannes Anderwald 2009-09-20 04:21:29 +00:00
parent 3aee3165e0
commit ba7067eafa
4 changed files with 90 additions and 9 deletions

View file

@ -1654,6 +1654,17 @@ BOOL _ILIsMyComputer(LPCITEMIDLIST pidl)
return FALSE; return FALSE;
} }
BOOL _ILIsPrinter(LPCITEMIDLIST pidl)
{
REFIID iid = _ILGetGUIDPointer(pidl);
TRACE("(%p)\n",pidl);
if (iid)
return IsEqualIID(iid, &CLSID_Printers);
return FALSE;
}
BOOL _ILIsBitBucket(LPCITEMIDLIST pidl) BOOL _ILIsBitBucket(LPCITEMIDLIST pidl)
{ {
REFIID iid = _ILGetGUIDPointer(pidl); REFIID iid = _ILGetGUIDPointer(pidl);

View file

@ -232,6 +232,7 @@ DWORD _ILGetDrive (LPCITEMIDLIST, LPSTR, UINT);
BOOL _ILIsUnicode (LPCITEMIDLIST pidl); BOOL _ILIsUnicode (LPCITEMIDLIST pidl);
BOOL _ILIsDesktop (LPCITEMIDLIST pidl); BOOL _ILIsDesktop (LPCITEMIDLIST pidl);
BOOL _ILIsMyComputer (LPCITEMIDLIST pidl); BOOL _ILIsMyComputer (LPCITEMIDLIST pidl);
BOOL _ILIsPrinter (LPCITEMIDLIST pidl);
BOOL _ILIsMyDocuments (LPCITEMIDLIST pidl); BOOL _ILIsMyDocuments (LPCITEMIDLIST pidl);
BOOL _ILIsControlPanel (LPCITEMIDLIST pidl); BOOL _ILIsControlPanel (LPCITEMIDLIST pidl);
BOOL _ILIsBitBucket (LPCITEMIDLIST pidl); BOOL _ILIsBitBucket (LPCITEMIDLIST pidl);

View file

@ -204,17 +204,55 @@ ISF_ControlPanel_fnParseDisplayName(IShellFolder2 * iface,
DWORD * pchEaten, LPITEMIDLIST * ppidl, DWORD * pdwAttributes) DWORD * pchEaten, LPITEMIDLIST * ppidl, DWORD * pdwAttributes)
{ {
ICPanelImpl *This = (ICPanelImpl *)iface; ICPanelImpl *This = (ICPanelImpl *)iface;
WCHAR szElement[MAX_PATH];
LPCWSTR szNext = NULL;
LPITEMIDLIST pidlTemp = NULL;
HRESULT hr = S_OK;
CLSID clsid;
HRESULT hr = E_INVALIDARG; TRACE ("(%p)->(HWND=%p,%p,%p=%s,%p,pidl=%p,%p)\n",
This, hwndOwner, pbc, lpszDisplayName, debugstr_w(lpszDisplayName),
pchEaten, ppidl, pdwAttributes);
FIXME("(%p)->(HWND=%p,%p,%p=%s,%p,pidl=%p,%p)\n", if (!lpszDisplayName || !ppidl)
This, hwndOwner, pbc, lpszDisplayName, debugstr_w(lpszDisplayName), pchEaten, ppidl, pdwAttributes); return E_INVALIDARG;
*ppidl = 0; *ppidl = 0;
if (pchEaten)
*pchEaten = 0;
TRACE("(%p)->(-- ret=0x%08x)\n", This, hr); if (pchEaten)
*pchEaten = 0; /* strange but like the original */
if (lpszDisplayName[0] == ':' && lpszDisplayName[1] == ':')
{
szNext = GetNextElementW (lpszDisplayName, szElement, MAX_PATH);
TRACE ("-- element: %s\n", debugstr_w (szElement));
CLSIDFromString (szElement + 2, &clsid);
pidlTemp = _ILCreateGuid (PT_GUID, &clsid);
}
else if( (pidlTemp = SHELL32_CreatePidlFromBindCtx(pbc, lpszDisplayName)) )
{
*ppidl = pidlTemp;
return S_OK;
}
if (SUCCEEDED(hr) && pidlTemp)
{
if (szNext && *szNext)
{
hr = SHELL32_ParseNextElement(iface, hwndOwner, pbc,
&pidlTemp, (LPOLESTR) szNext, pchEaten, pdwAttributes);
}
else
{
if (pdwAttributes && *pdwAttributes)
hr = SHELL32_GetItemAttributes(_IShellFolder_ (This),
pidlTemp, pdwAttributes);
}
}
*ppidl = pidlTemp;
TRACE ("(%p)->(-- ret=0x%08x)\n", This, hr);
return hr; return hr;
} }

View file

@ -333,7 +333,7 @@ static HRESULT WINAPI ISF_Printers_fnQueryInterface(
IsEqualIID (riid, &IID_IShellFolder) || IsEqualIID (riid, &IID_IShellFolder) ||
IsEqualIID (riid, &IID_IShellFolder2)) IsEqualIID (riid, &IID_IShellFolder2))
{ {
*ppvObj = This; *ppvObj = _IShellFolder_(This);
} }
else if (IsEqualIID (riid, &IID_IPersist) || else if (IsEqualIID (riid, &IID_IPersist) ||
@ -609,12 +609,20 @@ static HRESULT WINAPI ISF_Printers_fnCreateViewObject (IShellFolder2 * iface,
static HRESULT WINAPI ISF_Printers_fnGetAttributesOf (IShellFolder2 * iface, static HRESULT WINAPI ISF_Printers_fnGetAttributesOf (IShellFolder2 * iface,
UINT cidl, LPCITEMIDLIST * apidl, DWORD * rgfInOut) UINT cidl, LPCITEMIDLIST * apidl, DWORD * rgfInOut)
{ {
static const DWORD dwPrintersAttributes =
SFGAO_HASPROPSHEET | SFGAO_STORAGEANCESTOR | SFGAO_FILESYSANCESTOR | SFGAO_FOLDER | SFGAO_CANRENAME | SFGAO_CANDELETE;
HRESULT hr = S_OK;
IGenericSFImpl *This = (IGenericSFImpl *)iface; IGenericSFImpl *This = (IGenericSFImpl *)iface;
FIXME ("(%p)->(cidl=%d apidl=%p mask=0x%08lx): stub\n", FIXME ("(%p)->(cidl=%d apidl=%p mask=0x%08lx): stub\n",
This, cidl, apidl, *rgfInOut); This, cidl, apidl, *rgfInOut);
return E_NOTIMPL; *rgfInOut &= dwPrintersAttributes;
*rgfInOut &= ~SFGAO_VALIDATE;
TRACE ("-- result=0x%08x\n", *rgfInOut);
return hr;
} }
/************************************************************************** /**************************************************************************
@ -669,6 +677,7 @@ static HRESULT WINAPI ISF_Printers_fnGetUIObjectOf (IShellFolder2 * iface,
static HRESULT WINAPI ISF_Printers_fnGetDisplayNameOf (IShellFolder2 * iface, static HRESULT WINAPI ISF_Printers_fnGetDisplayNameOf (IShellFolder2 * iface,
LPCITEMIDLIST pidl, DWORD dwFlags, LPSTRRET strRet) LPCITEMIDLIST pidl, DWORD dwFlags, LPSTRRET strRet)
{ {
LPWSTR pszName;
IGenericSFImpl *This = (IGenericSFImpl *)iface; IGenericSFImpl *This = (IGenericSFImpl *)iface;
PIDLPrinterStruct * p; PIDLPrinterStruct * p;
@ -676,12 +685,34 @@ static HRESULT WINAPI ISF_Printers_fnGetDisplayNameOf (IShellFolder2 * iface,
pdump (pidl); pdump (pidl);
if (!strRet) if (!strRet)
{
WARN("no strRet\n");
return E_INVALIDARG; return E_INVALIDARG;
}
if (_ILIsPrinter(pidl))
{
pszName = CoTaskMemAlloc(MAX_PATH * sizeof(WCHAR));
if (!pszName)
return E_OUTOFMEMORY;
if (LoadStringW(shell32_hInstance, IDS_PRINTERS, pszName, MAX_PATH))
{
pszName[MAX_PATH-1] = L'\0';
strRet->uType = STRRET_WSTR;
strRet->u.pOleStr = pszName;
return S_OK;
}
CoTaskMemFree(pszName);
return E_FAIL;
}
p = _ILGetPrinterStruct(pidl); p = _ILGetPrinterStruct(pidl);
if (!p) if (!p)
{
WARN("no printer struct\n");
return E_INVALIDARG; return E_INVALIDARG;
}
strRet->u.pOleStr = SHAlloc(p->offsServer * sizeof(WCHAR)); strRet->u.pOleStr = SHAlloc(p->offsServer * sizeof(WCHAR));
if (!strRet->u.pOleStr) if (!strRet->u.pOleStr)
return E_OUTOFMEMORY; return E_OUTOFMEMORY;