4 * Copyright 1997 Marcus Meissner
5 * Copyright 1998 Juergen Schmied
19 #include "wine/obj_base.h"
20 #include "wine/obj_dragdrop.h"
21 #include "wine/obj_shellfolder.h"
22 #include "shell32_main.h"
24 DEFAULT_DEBUG_CHANNEL(shell
)
26 /***************************************************************************
27 * IDropTarget interface definition for the ShellFolder
31 { ICOM_VTABLE(IDropTarget
)* lpvtbl
;
35 static struct ICOM_VTABLE(IDropTarget
) dtvt
;
38 /****************************************************************************
39 * ISFDropTarget implementation
42 static IDropTarget
* WINAPI
ISFDropTarget_Constructor(void)
46 sf
= HeapAlloc(GetProcessHeap(), 0, sizeof(ISFDropTarget
));
53 return (IDropTarget
*)sf
;
56 static HRESULT WINAPI
ISFDropTarget_QueryInterface(
61 ICOM_THIS(ISFDropTarget
,iface
);
64 WINE_StringFromCLSID((LPCLSID
)riid
,xriid
);
66 TRACE(shell
,"(%p)->(\n\tIID:\t%s,%p)\n",This
,xriid
,ppvObj
);
68 if ( !This
|| !ppvObj
)
73 if(IsEqualIID(riid
, &IID_IUnknown
)) /*IUnknown*/
76 else if(IsEqualIID(riid
, &IID_IDropTarget
)) /*IShellFolder*/
77 { *ppvObj
= (ISFDropTarget
*)This
;
81 { IDropTarget_AddRef((IDropTarget
*)*ppvObj
);
82 TRACE(shell
,"-- Interface: (%p)->(%p)\n",ppvObj
,*ppvObj
);
86 TRACE(shell
,"-- Interface: E_NOINTERFACE\n");
91 static ULONG WINAPI
ISFDropTarget_AddRef( IDropTarget
*iface
)
93 ICOM_THIS(ISFDropTarget
,iface
);
95 TRACE(shell
,"(%p)->(count=%lu)\n",This
,This
->ref
);
102 static ULONG WINAPI
ISFDropTarget_Release( IDropTarget
*iface
)
104 ICOM_THIS(ISFDropTarget
,iface
);
109 { TRACE(shell
,"-- destroying ISFDropTarget (%p)\n",This
);
110 HeapFree(GetProcessHeap(),0,This
);
116 static HRESULT WINAPI
ISFDropTarget_DragEnter(
118 IDataObject
*pDataObject
,
124 ICOM_THIS(ISFDropTarget
,iface
);
126 FIXME(shell
, "Stub: This=%p, DataObject=%p\n",This
,pDataObject
);
131 static HRESULT WINAPI
ISFDropTarget_DragOver(
137 ICOM_THIS(ISFDropTarget
,iface
);
139 FIXME(shell
, "Stub: This=%p\n",This
);
144 static HRESULT WINAPI
ISFDropTarget_DragLeave(
147 ICOM_THIS(ISFDropTarget
,iface
);
149 FIXME(shell
, "Stub: This=%p\n",This
);
154 static HRESULT WINAPI
ISFDropTarget_Drop(
156 IDataObject
* pDataObject
,
161 ICOM_THIS(ISFDropTarget
,iface
);
163 FIXME(shell
, "Stub: This=%p\n",This
);
168 static struct ICOM_VTABLE(IDropTarget
) dtvt
=
170 ISFDropTarget_QueryInterface
,
171 ISFDropTarget_AddRef
,
172 ISFDropTarget_Release
,
173 ISFDropTarget_DragEnter
,
174 ISFDropTarget_DragOver
,
175 ISFDropTarget_DragLeave
,
179 /***************************************************************************
180 * GetNextElement (internal function)
182 * gets a part of a string till the first backslash
185 * pszNext [IN] string to get the element from
186 * pszOut [IN] pointer to buffer whitch receives string
187 * dwOut [IN] length of pszOut
190 * LPSTR pointer to first, not yet parsed char
192 LPSTR
GetNextElement(LPSTR pszNext
,LPSTR pszOut
,DWORD dwOut
)
193 { LPSTR pszTail
= pszNext
;
195 TRACE(shell
,"(%s %p 0x%08lx)\n",debugstr_a(pszNext
),pszOut
,dwOut
);
197 if(!pszNext
|| !*pszNext
)
200 while(*pszTail
&& (*pszTail
!= '\\'))
203 dwCopy
=((LPBYTE
)pszTail
-(LPBYTE
)pszNext
)/sizeof(CHAR
)+1;
204 lstrcpynA(pszOut
, pszNext
, (dwOut
<dwCopy
)? dwOut
: dwCopy
);
210 TRACE(shell
,"--(%s %s 0x%08lx)\n",debugstr_a(pszNext
),debugstr_a(pszOut
),dwOut
);
214 /***********************************************************************
215 * IShellFolder implementation
218 static struct ICOM_VTABLE(IShellFolder
) sfvt
;
219 static struct ICOM_VTABLE(IPersistFolder
) psfvt
;
221 #define _IPersistFolder_Offset ((int)(&(((IGenericSFImpl*)0)->lpvtblPersistFolder)))
222 #define _ICOM_THIS_From_IPersistFolder(class, name) class* This = (class*)(((void*)name)-_IPersistFolder_Offset);
224 /**************************************************************************
225 * IShellFolder_Constructor
228 IShellFolder
* IShellFolder_Constructor(
229 IGenericSFImpl
* pParent
,
235 sf
=(IGenericSFImpl
*)HeapAlloc(GetProcessHeap(),0,sizeof(IGenericSFImpl
));
238 sf
->lpvtblPersistFolder
=&psfvt
;
239 sf
->sMyPath
=NULL
; /* path of the folder */
240 sf
->pMyPidl
=NULL
; /* my qualified pidl */
242 TRACE(shell
,"(%p)->(parent=%p, pidl=%p)\n",sf
,pParent
, pidl
);
245 /* keep a copy of the pidl in the instance*/
246 sf
->mpidl
= ILClone(pidl
); /* my short pidl */
248 if(sf
->mpidl
) /* do we have a pidl? */
250 if(pParent
->sMyPath
) /* get the size of the parents path */
251 { dwSize
+= strlen(pParent
->sMyPath
) ;
252 TRACE(shell
,"-- (%p)->(parent's path=%s)\n",sf
, debugstr_a(pParent
->sMyPath
));
254 dwSize
+= _ILGetFolderText(sf
->mpidl
,NULL
,0); /* add the size of the foldername*/
255 sf
->sMyPath
= SHAlloc(dwSize
+2); /* '\0' and backslash */
259 if(pParent
->sMyPath
) /* if the parent has a path, get it*/
260 { strcpy(sf
->sMyPath
, pParent
->sMyPath
);
261 PathAddBackslashA (sf
->sMyPath
);
263 sf
->pMyPidl
= ILCombine(pParent
->pMyPidl
, pidl
);
264 len
= strlen(sf
->sMyPath
);
265 _ILGetFolderText(sf
->mpidl
, sf
->sMyPath
+len
, dwSize
-len
);
266 TRACE(shell
,"-- (%p)->(my pidl=%p, my path=%s)\n",sf
, sf
->pMyPidl
,debugstr_a(sf
->sMyPath
));
271 return (IShellFolder
*)sf
;
273 /**************************************************************************
274 * IShellFolder_fnQueryInterface
277 * REFIID riid [in ] Requested InterfaceID
278 * LPVOID* ppvObject [out] Interface* to hold the result
280 static HRESULT WINAPI
IShellFolder_fnQueryInterface(
281 IShellFolder
* iface
,
285 ICOM_THIS(IGenericSFImpl
, iface
);
288 WINE_StringFromCLSID((LPCLSID
)riid
,xriid
);
289 TRACE(shell
,"(%p)->(\n\tIID:\t%s,%p)\n",This
,xriid
,ppvObj
);
293 if(IsEqualIID(riid
, &IID_IUnknown
)) /*IUnknown*/
296 else if(IsEqualIID(riid
, &IID_IShellFolder
)) /*IShellFolder*/
297 { *ppvObj
= (IShellFolder
*)This
;
299 else if(IsEqualIID(riid
, &IID_IPersistFolder
)) /*IPersistFolder*/
300 { *ppvObj
= (IPersistFolder
*)&(This
->lpvtblPersistFolder
);
304 { IShellFolder_AddRef((IShellFolder
*)*ppvObj
);
305 TRACE(shell
,"-- Interface: (%p)->(%p)\n",ppvObj
,*ppvObj
);
308 TRACE(shell
,"-- Interface: E_NOINTERFACE\n");
309 return E_NOINTERFACE
;
312 /**************************************************************************
313 * IShellFolder::AddRef
316 static ULONG WINAPI
IShellFolder_fnAddRef(IShellFolder
* iface
)
318 ICOM_THIS(IGenericSFImpl
, iface
);
320 TRACE(shell
,"(%p)->(count=%lu)\n",This
,This
->ref
);
323 return ++(This
->ref
);
326 /**************************************************************************
327 * IShellFolder_fnRelease
329 static ULONG WINAPI
IShellFolder_fnRelease(IShellFolder
* iface
)
331 ICOM_THIS(IGenericSFImpl
, iface
);
333 TRACE(shell
,"(%p)->(count=%lu)\n",This
,This
->ref
);
337 { TRACE(shell
,"-- destroying IShellFolder(%p)\n",This
);
339 if (pdesktopfolder
== iface
)
340 { pdesktopfolder
=NULL
;
341 TRACE(shell
,"-- destroyed IShellFolder(%p) was Desktopfolder\n",This
);
344 { SHFree(This
->pMyPidl
);
347 { SHFree(This
->mpidl
);
350 { SHFree(This
->sMyPath
);
353 HeapFree(GetProcessHeap(),0,This
);
359 /**************************************************************************
360 * IShellFolder_fnParseDisplayName
362 * HWND hwndOwner, //[in ] Parent window for any message's
363 * LPBC pbc, //[in ] reserved
364 * LPOLESTR lpszDisplayName,//[in ] "Unicode" displayname.
365 * ULONG* pchEaten, //[out] (unicode) characters processed
366 * LPITEMIDLIST* ppidl, //[out] complex pidl to item
367 * ULONG* pdwAttributes //[out] items attributes
370 * pdwAttributes: not used
372 static HRESULT WINAPI
IShellFolder_fnParseDisplayName(
373 IShellFolder
* iface
,
376 LPOLESTR lpszDisplayName
,
379 DWORD
*pdwAttributes
)
381 ICOM_THIS(IGenericSFImpl
, iface
);
383 HRESULT hr
=E_OUTOFMEMORY
;
384 LPITEMIDLIST pidlFull
=NULL
, pidlTemp
= NULL
, pidlOld
= NULL
;
386 CHAR szTemp
[MAX_PATH
],szElement
[MAX_PATH
];
389 TRACE(shell
,"(%p)->(HWND=0x%08x,%p,%p=%s,%p,pidl=%p,%p)\n",
390 This
,hwndOwner
,pbcReserved
,lpszDisplayName
,
391 debugstr_w(lpszDisplayName
),pchEaten
,ppidl
,pdwAttributes
);
394 WideCharToLocal(szTemp
, lpszDisplayName
, lstrlenW(lpszDisplayName
) + 1);
396 { if (strcmp(szTemp
,"Desktop")==0)
397 { pidlFull
= _ILCreateDesktop();
399 else if (strcmp(szTemp
,"My Computer")==0)
400 { pidlFull
= _ILCreateMyComputer();
403 { if (!PathIsRootA(szTemp
))
404 { if (This
->sMyPath
&& strlen (This
->sMyPath
))
405 { if (strcmp(This
->sMyPath
,"My Computer"))
406 { strcpy (szElement
,This
->sMyPath
);
407 PathAddBackslashA (szElement
);
408 strcat (szElement
, szTemp
);
409 strcpy (szTemp
, szElement
);
414 /* check if the lpszDisplayName is Folder or File*/
415 bIsFile
= ! (GetFileAttributesA(szTemp
) & FILE_ATTRIBUTE_DIRECTORY
);
416 pszNext
= GetNextElement(szTemp
, szElement
, MAX_PATH
);
418 pidlFull
= _ILCreateMyComputer();
419 pidlTemp
= _ILCreateDrive(szElement
);
421 pidlFull
= ILCombine(pidlFull
,pidlTemp
);
425 { while((pszNext
=GetNextElement(pszNext
, szElement
, MAX_PATH
)))
426 { if(!*pszNext
&& bIsFile
)
427 { pidlTemp
= _ILCreateValue(NULL
, szElement
); /* FIXME: shortname */
430 { pidlTemp
= _ILCreateFolder(NULL
, szElement
); /* FIXME: shortname */
433 pidlFull
= ILCombine(pidlFull
,pidlTemp
);
445 /**************************************************************************
446 * IShellFolder_fnEnumObjects
448 * HWND hwndOwner, //[in ] Parent Window
449 * DWORD grfFlags, //[in ] SHCONTF enumeration mask
450 * LPENUMIDLIST* ppenumIDList //[out] IEnumIDList interface
452 static HRESULT WINAPI
IShellFolder_fnEnumObjects(
453 IShellFolder
* iface
,
456 LPENUMIDLIST
* ppEnumIDList
)
458 ICOM_THIS(IGenericSFImpl
, iface
);
460 TRACE(shell
,"(%p)->(HWND=0x%08x flags=0x%08lx pplist=%p)\n",This
,hwndOwner
,dwFlags
,ppEnumIDList
);
462 *ppEnumIDList
= NULL
;
463 *ppEnumIDList
= IEnumIDList_Constructor (This
->sMyPath
, dwFlags
);
464 TRACE(shell
,"-- (%p)->(new ID List: %p)\n",This
,*ppEnumIDList
);
466 { return E_OUTOFMEMORY
;
471 /**************************************************************************
472 * IShellFolder_fnBindToObject
474 * LPCITEMIDLIST pidl, //[in ] complex pidl to open
475 * LPBC pbc, //[in ] reserved
476 * REFIID riid, //[in ] Initial Interface
477 * LPVOID* ppvObject //[out] Interface*
479 static HRESULT WINAPI
IShellFolder_fnBindToObject( IShellFolder
* iface
, LPCITEMIDLIST pidl
,
480 LPBC pbcReserved
, REFIID riid
, LPVOID
* ppvOut
)
482 ICOM_THIS(IGenericSFImpl
, iface
);
486 LPSHELLFOLDER pShellFolder
;
488 WINE_StringFromCLSID(riid
,xriid
);
490 TRACE(shell
,"(%p)->(pidl=%p,%p,\n\tIID:%s,%p)\n",This
,pidl
,pbcReserved
,xriid
,ppvOut
);
494 pShellFolder
= IShellFolder_Constructor(This
, pidl
);
497 return E_OUTOFMEMORY
;
499 hr
= pShellFolder
->lpvtbl
->fnQueryInterface(pShellFolder
, riid
, ppvOut
);
500 pShellFolder
->lpvtbl
->fnRelease(pShellFolder
);
501 TRACE(shell
,"-- (%p)->(interface=%p)\n",This
, ppvOut
);
505 /**************************************************************************
506 * IShellFolder_fnBindToStorage
508 * LPCITEMIDLIST pidl, //[in ] complex pidl to store
509 * LPBC pbc, //[in ] reserved
510 * REFIID riid, //[in ] Initial storage interface
511 * LPVOID* ppvObject //[out] Interface* returned
513 static HRESULT WINAPI
IShellFolder_fnBindToStorage(
514 IShellFolder
* iface
,
520 ICOM_THIS(IGenericSFImpl
, iface
);
523 WINE_StringFromCLSID(riid
,xriid
);
525 FIXME(shell
,"(%p)->(pidl=%p,%p,\n\tIID:%s,%p) stub\n",This
,pidl
,pbcReserved
,xriid
,ppvOut
);
531 /**************************************************************************
532 * IShellFolder_fnCompareIDs
535 * LPARAM lParam, //[in ] Column?
536 * LPCITEMIDLIST pidl1, //[in ] simple pidl
537 * LPCITEMIDLIST pidl2) //[in ] simple pidl
540 * Special case - If one of the items is a Path and the other is a File,
541 * always make the Path come before the File.
544 * we have to handle simple pidl's only (?)
546 static HRESULT WINAPI
IShellFolder_fnCompareIDs(
547 IShellFolder
* iface
,
552 ICOM_THIS(IGenericSFImpl
, iface
);
554 CHAR szString1
[MAX_PATH
] = "";
555 CHAR szString2
[MAX_PATH
] = "";
557 LPCITEMIDLIST pidlTemp1
= pidl1
, pidlTemp2
= pidl2
;
559 TRACE(shell
,"(%p)->(0x%08lx,pidl1=%p,pidl2=%p)\n",This
,lParam
,pidl1
,pidl2
);
563 if (!pidl1
&& !pidl2
)
565 if (!pidl1
) /* Desktop < anything */
570 /* get the last item in each list */
571 while((ILGetNext(pidlTemp1
))->mkid
.cb
)
572 pidlTemp1
= ILGetNext(pidlTemp1
);
573 while((ILGetNext(pidlTemp2
))->mkid
.cb
)
574 pidlTemp2
= ILGetNext(pidlTemp2
);
576 /* at This point, both pidlTemp1 and pidlTemp2 point to the last item in the list */
577 if(_ILIsValue(pidlTemp1
) != _ILIsValue(pidlTemp2
))
578 { if(_ILIsValue(pidlTemp1
))
583 _ILGetDrive( pidl1
,szString1
,sizeof(szString1
));
584 _ILGetDrive( pidl2
,szString2
,sizeof(szString2
));
585 nReturn
= strcasecmp(szString2
, szString1
);
590 _ILGetFolderText( pidl1
,szString1
,sizeof(szString1
));
591 _ILGetFolderText( pidl2
,szString2
,sizeof(szString2
));
592 nReturn
= strcasecmp(szString2
, szString1
);
597 _ILGetValueText(pidl1
,szString1
,sizeof(szString1
));
598 _ILGetValueText(pidl2
,szString2
,sizeof(szString2
));
599 return strcasecmp(szString1
, szString2
);
602 /**************************************************************************
603 * IShellFolder_fnCreateViewObject
604 * Creates an View Object representing the ShellFolder
605 * IShellView / IShellBrowser / IContextMenu
608 * HWND hwndOwner, // Handle of owner window
609 * REFIID riid, // Requested initial interface
610 * LPVOID* ppvObject) // Resultant interface*
613 * the same as SHCreateShellFolderViewEx ???
615 static HRESULT WINAPI
IShellFolder_fnCreateViewObject( IShellFolder
* iface
,
616 HWND hwndOwner
, REFIID riid
, LPVOID
*ppvOut
)
618 ICOM_THIS(IGenericSFImpl
, iface
);
620 LPSHELLVIEW pShellView
;
624 WINE_StringFromCLSID(riid
,xriid
);
625 TRACE(shell
,"(%p)->(hwnd=0x%x,\n\tIID:\t%s,%p)\n",This
,hwndOwner
,xriid
,ppvOut
);
629 pShellView
= IShellView_Constructor((IShellFolder
*) This
, This
->mpidl
);
632 return E_OUTOFMEMORY
;
634 hr
= pShellView
->lpvtbl
->fnQueryInterface(pShellView
, riid
, ppvOut
);
635 pShellView
->lpvtbl
->fnRelease(pShellView
);
636 TRACE(shell
,"-- (%p)->(interface=%p)\n",This
, ppvOut
);
640 /**************************************************************************
641 * IShellFolder_fnGetAttributesOf
644 * UINT cidl, //[in ] num elements in pidl array
645 + LPCITEMIDLIST* apidl, //[in ] simple pidl array
646 * ULONG* rgfInOut) //[out] result array
649 * Note: rgfInOut is documented as being an array of ULONGS.
650 * This does not seem to be the case. Testing This function using the shell to
651 * call it with cidl > 1 (by deleting multiple items) reveals that the shell
652 * passes ONE element in the array and writing to further elements will
653 * cause the shell to fail later.
655 static HRESULT WINAPI
IShellFolder_fnGetAttributesOf(IShellFolder
* iface
,UINT cidl
,LPCITEMIDLIST
*apidl
,DWORD
*rgfInOut
)
657 ICOM_THIS(IGenericSFImpl
, iface
);
659 LPCITEMIDLIST
* pidltemp
;
662 TRACE(shell
,"(%p)->(%d,%p,%p)\n",This
,cidl
,apidl
,rgfInOut
);
664 if ((! cidl
)| (!apidl
) | (!rgfInOut
))
671 TRACE(shell
,"-- mask=0x%08lx\n",*rgfInOut
);
676 if (_ILIsDesktop( *pidltemp
))
677 { *rgfInOut
|= ( SFGAO_HASSUBFOLDER
| SFGAO_FOLDER
| SFGAO_DROPTARGET
| SFGAO_HASPROPSHEET
| SFGAO_CANLINK
);
679 else if (_ILIsMyComputer( *pidltemp
))
680 { *rgfInOut
|= ( SFGAO_HASSUBFOLDER
| SFGAO_FOLDER
| SFGAO_FILESYSANCESTOR
|
681 SFGAO_DROPTARGET
| SFGAO_HASPROPSHEET
| SFGAO_CANRENAME
| SFGAO_CANLINK
);
683 else if (_ILIsDrive( *pidltemp
))
684 { *rgfInOut
|= ( SFGAO_HASSUBFOLDER
| SFGAO_FILESYSTEM
| SFGAO_FOLDER
| SFGAO_FILESYSANCESTOR
|
685 SFGAO_DROPTARGET
| SFGAO_HASPROPSHEET
| SFGAO_CANLINK
);
687 else if (_ILIsFolder( *pidltemp
))
688 { *rgfInOut
|= ( SFGAO_HASSUBFOLDER
| SFGAO_FILESYSTEM
| SFGAO_FOLDER
| SFGAO_CAPABILITYMASK
);
690 else if (_ILIsValue( *pidltemp
))
691 { *rgfInOut
|= (SFGAO_FILESYSTEM
| SFGAO_CAPABILITYMASK
);
696 } while (cidl
> 0 && *pidltemp
);
700 /**************************************************************************
701 * IShellFolder_fnGetUIObjectOf
704 * HWND hwndOwner, //[in ] Parent window for any output
705 * UINT cidl, //[in ] array size
706 * LPCITEMIDLIST* apidl, //[in ] simple pidl array
707 * REFIID riid, //[in ] Requested Interface
708 * UINT* prgfInOut, //[ ] reserved
709 * LPVOID* ppvObject) //[out] Resulting Interface
712 * This function gets asked to return "view objects" for one or more (multiple select)
714 * The viewobject typically is an COM object with one of the following interfaces:
715 * IExtractIcon,IDataObject,IContextMenu
716 * In order to support icon positions in the default Listview your DataObject
717 * must implement the SetData method (in addition to GetData :) - the shell passes
718 * a barely documented "Icon positions" structure to SetData when the drag starts,
719 * and GetData's it if the drop is in another explorer window that needs the positions.
721 static HRESULT WINAPI
IShellFolder_fnGetUIObjectOf(
722 IShellFolder
* iface
,
725 LPCITEMIDLIST
* apidl
,
730 ICOM_THIS(IGenericSFImpl
, iface
);
734 LPUNKNOWN pObj
= NULL
;
736 WINE_StringFromCLSID(riid
,xclsid
);
738 TRACE(shell
,"(%p)->(%u,%u,apidl=%p,\n\tIID:%s,%p,%p)\n",
739 This
,hwndOwner
,cidl
,apidl
,xclsid
,prgfInOut
,ppvOut
);
743 if(IsEqualIID(riid
, &IID_IContextMenu
))
748 pObj
= (LPUNKNOWN
)IContextMenu_Constructor((IShellFolder
*)This
, apidl
, cidl
);
750 else if (IsEqualIID(riid
, &IID_IDataObject
))
753 return(E_INVALIDARG
);
755 pObj
= (LPUNKNOWN
)IDataObject_Constructor (hwndOwner
, (IShellFolder
*)This
, apidl
, cidl
);
757 else if(IsEqualIID(riid
, &IID_IExtractIconA
))
760 return(E_INVALIDARG
);
762 pidl
= ILCombine(This
->pMyPidl
,apidl
[0]);
763 pObj
= (LPUNKNOWN
)IExtractIconA_Constructor( pidl
);
766 else if (IsEqualIID(riid
, &IID_IDropTarget
))
769 return(E_INVALIDARG
);
771 pObj
= (LPUNKNOWN
)ISFDropTarget_Constructor();
775 ERR(shell
,"(%p)->E_NOINTERFACE\n",This
);
776 return E_NOINTERFACE
;
780 return E_OUTOFMEMORY
;
785 /**************************************************************************
786 * IShellFolder_fnGetDisplayNameOf
787 * Retrieves the display name for the specified file object or subfolder
790 * LPCITEMIDLIST pidl, //[in ] complex pidl to item
791 * DWORD dwFlags, //[in ] SHGNO formatting flags
792 * LPSTRRET lpName) //[out] Returned display name
795 * if the name is in the pidl the ret value should be a STRRET_OFFSET
797 #define GET_SHGDN_FOR(dwFlags) ((DWORD)dwFlags & (DWORD)0x0000FF00)
798 #define GET_SHGDN_RELATION(dwFlags) ((DWORD)dwFlags & (DWORD)0x000000FF)
800 static HRESULT WINAPI
IShellFolder_fnGetDisplayNameOf(
801 IShellFolder
* iface
,
806 ICOM_THIS(IGenericSFImpl
, iface
);
808 CHAR szText
[MAX_PATH
];
809 CHAR szTemp
[MAX_PATH
];
810 CHAR szSpecial
[MAX_PATH
];
811 CHAR szDrive
[MAX_PATH
];
812 DWORD dwVolumeSerialNumber
,dwMaximumComponetLength
,dwFileSystemFlags
;
813 LPITEMIDLIST pidlTemp
=NULL
;
814 BOOL bSimplePidl
=FALSE
;
816 TRACE(shell
,"(%p)->(pidl=%p,0x%08lx,%p)\n",This
,pidl
,dwFlags
,lpName
);
824 /* test if simple(relative) or complex(absolute) pidl */
825 pidlTemp
= ILGetNext(pidl
);
826 if (pidlTemp
&& pidlTemp
->mkid
.cb
==0x00)
827 { bSimplePidl
= TRUE
;
828 TRACE(shell
,"-- simple pidl\n");
831 if (_ILIsDesktop( pidl
))
832 { strcpy (szText
,"Desktop");
835 { if (_ILIsMyComputer(pidl
))
836 { _ILGetItemText(pidl
, szSpecial
, MAX_PATH
);
837 pidl
= ILGetNext(pidl
);
840 if (_ILIsDrive(pidl
))
841 { _ILGetDrive( pidl
, szTemp
, MAX_PATH
);
843 if ( dwFlags
==SHGDN_NORMAL
|| dwFlags
==SHGDN_INFOLDER
) /* like "A1-dos (C:)" */
844 { GetVolumeInformationA(szTemp
,szDrive
,MAX_PATH
,&dwVolumeSerialNumber
,&dwMaximumComponetLength
,&dwFileSystemFlags
,NULL
,0);
845 szTemp
[2]=0x00; /* overwrite '\' */
846 strcat (szDrive
," (");
847 strcat (szDrive
,szTemp
);
848 strcat (szDrive
,")");
850 else /* like "C:\" */
851 { PathAddBackslashA (szTemp
);
852 strcpy(szDrive
,szTemp
);
858 { case SHGDN_NORMAL
: /* 0x0000 */
859 _ILGetPidlPath( pidl
, szText
, MAX_PATH
);
862 case SHGDN_INFOLDER
| SHGDN_FORPARSING
: /* 0x8001 */
863 case SHGDN_INFOLDER
: /* 0x0001 */
864 pidlTemp
= ILFindLastID(pidl
);
866 { _ILGetItemText( pidlTemp
, szText
, MAX_PATH
);
870 case SHGDN_FORPARSING
: /* 0x8000 */
872 { /* if the IShellFolder has parents, get the path from the
873 parent and add the ItemName*/
875 if (This
->sMyPath
&& strlen (This
->sMyPath
))
876 { if (strcmp(This
->sMyPath
,"My Computer"))
877 { strcpy (szText
,This
->sMyPath
);
878 PathAddBackslashA (szText
);
881 pidlTemp
= ILFindLastID(pidl
);
883 { _ILGetItemText( pidlTemp
, szTemp
, MAX_PATH
);
885 strcat(szText
,szTemp
);
887 else /* if the pidl is absolute, get everything from the pidl*/
888 { _ILGetPidlPath( pidl
, szText
, MAX_PATH
);
892 TRACE(shell
,"--- wrong flags=%lx\n", dwFlags
);
895 if ((szText
[0]==0x00 && szDrive
[0]!=0x00)|| (bSimplePidl
&& szDrive
[0]!=0x00))
896 { strcpy(szText
,szDrive
);
898 if (szText
[0]==0x00 && szSpecial
[0]!=0x00)
899 { strcpy(szText
,szSpecial
);
903 TRACE(shell
,"-- (%p)->(%s)\n",This
,szText
);
906 { return E_OUTOFMEMORY
;
908 lpName
->uType
= STRRET_CSTRA
;
909 strcpy(lpName
->u
.cStr
,szText
);
913 /**************************************************************************
914 * IShellFolder_fnSetNameOf
915 * Changes the name of a file object or subfolder, possibly changing its item
916 * identifier in the process.
919 * HWND hwndOwner, //[in ] Owner window for output
920 * LPCITEMIDLIST pidl, //[in ] simple pidl of item to change
921 * LPCOLESTR lpszName, //[in ] the items new display name
922 * DWORD dwFlags, //[in ] SHGNO formatting flags
923 * LPITEMIDLIST* ppidlOut) //[out] simple pidl returned
925 static HRESULT WINAPI
IShellFolder_fnSetNameOf(
926 IShellFolder
* iface
,
928 LPCITEMIDLIST pidl
, /*simple pidl*/
931 LPITEMIDLIST
*pPidlOut
)
933 ICOM_THIS(IGenericSFImpl
, iface
);
935 FIXME(shell
,"(%p)->(%u,pidl=%p,%s,%lu,%p),stub!\n",
936 This
,hwndOwner
,pidl
,debugstr_w(lpName
),dw
,pPidlOut
);
941 /**************************************************************************
942 * IShellFolder_fnGetFolderPath
943 * FIXME: drive not included
945 static HRESULT WINAPI
IShellFolder_fnGetFolderPath(IShellFolder
* iface
, LPSTR lpszOut
, DWORD dwOutSize
)
947 ICOM_THIS(IGenericSFImpl
, iface
);
950 TRACE(shell
,"(%p)->(%p %lu)\n",This
, lpszOut
, dwOutSize
);
960 dwSize
= strlen (This
->sMyPath
) +1;
961 if ( dwSize
> dwOutSize
)
963 strcpy(lpszOut
, This
->sMyPath
);
965 TRACE(shell
,"-- (%p)->(return=%s)\n",This
, lpszOut
);
969 static ICOM_VTABLE(IShellFolder
) sfvt
=
970 { IShellFolder_fnQueryInterface
,
971 IShellFolder_fnAddRef
,
972 IShellFolder_fnRelease
,
973 IShellFolder_fnParseDisplayName
,
974 IShellFolder_fnEnumObjects
,
975 IShellFolder_fnBindToObject
,
976 IShellFolder_fnBindToStorage
,
977 IShellFolder_fnCompareIDs
,
978 IShellFolder_fnCreateViewObject
,
979 IShellFolder_fnGetAttributesOf
,
980 IShellFolder_fnGetUIObjectOf
,
981 IShellFolder_fnGetDisplayNameOf
,
982 IShellFolder_fnSetNameOf
,
983 IShellFolder_fnGetFolderPath
986 /************************************************************************
987 * ISFPersistFolder_QueryInterface (IUnknown)
989 * See Windows documentation for more details on IUnknown methods.
991 static HRESULT WINAPI
ISFPersistFolder_QueryInterface(
992 IPersistFolder
* iface
,
996 _ICOM_THIS_From_IPersistFolder(IGenericSFImpl
, iface
);
998 return IShellFolder_QueryInterface((IShellFolder
*)This
, iid
, ppvObj
);
1001 /************************************************************************
1002 * ISFPersistFolder_AddRef (IUnknown)
1004 * See Windows documentation for more details on IUnknown methods.
1006 static ULONG WINAPI
ISFPersistFolder_AddRef(
1007 IPersistFolder
* iface
)
1009 _ICOM_THIS_From_IPersistFolder(IShellFolder
, iface
);
1011 return IShellFolder_AddRef((IShellFolder
*)This
);
1014 /************************************************************************
1015 * ISFPersistFolder_Release (IUnknown)
1017 * See Windows documentation for more details on IUnknown methods.
1019 static ULONG WINAPI
ISFPersistFolder_Release(
1020 IPersistFolder
* iface
)
1022 _ICOM_THIS_From_IPersistFolder(IGenericSFImpl
, iface
);
1024 return IShellFolder_Release((IShellFolder
*)This
);
1027 /************************************************************************
1028 * ISFPersistFolder_GetClassID (IPersist)
1030 * See Windows documentation for more details on IPersist methods.
1032 static HRESULT WINAPI
ISFPersistFolder_GetClassID(
1033 const IPersistFolder
* iface
,
1036 /* This ID is not documented anywhere but some tests in Windows tell
1037 * me that This is the ID for the "standard" implementation of the
1038 * IFolder interface.
1041 CLSID StdFolderID
= { 0xF3364BA0, 0x65B9, 0x11CE, {0xA9, 0xBA, 0x00, 0xAA, 0x00, 0x4A, 0xE8, 0x37} };
1043 if (lpClassId
==NULL
)
1046 memcpy(lpClassId
, &StdFolderID
, sizeof(StdFolderID
));
1051 /************************************************************************
1052 * ISFPersistFolder_Initialize (IPersistFolder)
1054 * See Windows documentation for more details on IPersistFolder methods.
1056 static HRESULT WINAPI
ISFPersistFolder_Initialize(
1057 IPersistFolder
* iface
,
1060 _ICOM_THIS_From_IPersistFolder(IGenericSFImpl
, iface
);
1063 { SHFree(This
->pMyPidl
);
1064 This
->pMyPidl
= NULL
;
1066 This
->pMyPidl
= ILClone(pidl
);
1070 static ICOM_VTABLE(IPersistFolder
) psfvt
=
1072 ISFPersistFolder_QueryInterface
,
1073 ISFPersistFolder_AddRef
,
1074 ISFPersistFolder_Release
,
1075 ISFPersistFolder_GetClassID
,
1076 ISFPersistFolder_Initialize