4 * Copyright 1997 Marcus Meissner
5 * Copyright 1998 Juergen Schmied
20 #include "shell32_main.h"
22 static HRESULT WINAPI
IShellFolder_QueryInterface(LPSHELLFOLDER
,REFIID
,LPVOID
*);
23 static ULONG WINAPI
IShellFolder_AddRef(LPSHELLFOLDER
);
24 static ULONG WINAPI
IShellFolder_Release(LPSHELLFOLDER
);
25 static HRESULT WINAPI
IShellFolder_Initialize(LPSHELLFOLDER
,LPCITEMIDLIST
);
26 static HRESULT WINAPI
IShellFolder_ParseDisplayName(LPSHELLFOLDER
,HWND
,LPBC
,LPOLESTR
,DWORD
*,LPITEMIDLIST
*,DWORD
*);
27 static HRESULT WINAPI
IShellFolder_EnumObjects(LPSHELLFOLDER
,HWND
,DWORD
,LPENUMIDLIST
*);
28 static HRESULT WINAPI
IShellFolder_BindToObject(LPSHELLFOLDER
,LPCITEMIDLIST
,LPBC
,REFIID
,LPVOID
*);
29 static HRESULT WINAPI
IShellFolder_BindToStorage(LPSHELLFOLDER
,LPCITEMIDLIST
,LPBC
,REFIID
,LPVOID
*);
30 static HRESULT WINAPI
IShellFolder_CompareIDs(LPSHELLFOLDER
,LPARAM
,LPCITEMIDLIST
,LPCITEMIDLIST
);
31 static HRESULT WINAPI
IShellFolder_CreateViewObject(LPSHELLFOLDER
,HWND
,REFIID
,LPVOID
*);
32 static HRESULT WINAPI
IShellFolder_GetAttributesOf(LPSHELLFOLDER
,UINT
,LPCITEMIDLIST
*,DWORD
*);
33 static HRESULT WINAPI
IShellFolder_GetUIObjectOf(LPSHELLFOLDER
,HWND
,UINT
,LPCITEMIDLIST
*,REFIID
,UINT
*,LPVOID
*);
34 static HRESULT WINAPI
IShellFolder_GetDisplayNameOf(LPSHELLFOLDER
,LPCITEMIDLIST
,DWORD
,LPSTRRET
);
35 static HRESULT WINAPI
IShellFolder_SetNameOf(LPSHELLFOLDER
,HWND
,LPCITEMIDLIST
,LPCOLESTR
,DWORD
,LPITEMIDLIST
*);
36 static BOOL WINAPI
IShellFolder_GetFolderPath(LPSHELLFOLDER
,LPSTR
,DWORD
);
38 /***************************************************************************
39 * IDropTarget interface definition for the ShellFolder
43 { ICOM_VTABLE(IDropTarget
)* lpvtbl
;
47 static struct ICOM_VTABLE(IDropTarget
) dtvt
;
50 /****************************************************************************
51 * ISFDropTarget implementation
54 static IDropTarget
* WINAPI
ISFDropTarget_Constructor(void)
58 sf
= HeapAlloc(GetProcessHeap(), 0, sizeof(ISFDropTarget
));
65 return (IDropTarget
*)sf
;
68 static HRESULT WINAPI
ISFDropTarget_QueryInterface(
73 ICOM_THIS(ISFDropTarget
,iface
);
76 WINE_StringFromCLSID((LPCLSID
)riid
,xriid
);
78 TRACE(shell
,"(%p)->(\n\tIID:\t%s,%p)\n",This
,xriid
,ppvObj
);
80 if ( !This
|| !ppvObj
)
85 if(IsEqualIID(riid
, &IID_IUnknown
)) /*IUnknown*/
88 else if(IsEqualIID(riid
, &IID_IDropTarget
)) /*IShellFolder*/
89 { *ppvObj
= (ISFDropTarget
*)This
;
93 { IDropTarget_AddRef((ISFDropTarget
*)*ppvObj
);
94 TRACE(shell
,"-- Interface: (%p)->(%p)\n",ppvObj
,*ppvObj
);
98 TRACE(shell
,"-- Interface: E_NOINTERFACE\n");
100 return E_NOINTERFACE
;
103 static ULONG WINAPI
ISFDropTarget_AddRef( IDropTarget
*iface
)
105 ICOM_THIS(ISFDropTarget
,iface
);
107 TRACE(shell
,"(%p)->(count=%lu)\n",This
,This
->ref
);
111 return ++(This
->ref
);
114 static ULONG WINAPI
ISFDropTarget_Release( IDropTarget
*iface
)
116 ICOM_THIS(ISFDropTarget
,iface
);
121 { TRACE(shell
,"-- destroying ISFDropTarget (%p)\n",This
);
122 HeapFree(GetProcessHeap(),0,This
);
128 static HRESULT WINAPI
ISFDropTarget_DragEnter(
130 IDataObject
*pDataObject
,
136 ICOM_THIS(ISFDropTarget
,iface
);
138 FIXME(shell
, "Stub: This=%p, DataObject=%p\n",This
,pDataObject
);
143 static HRESULT WINAPI
ISFDropTarget_DragOver(
149 ICOM_THIS(ISFDropTarget
,iface
);
151 FIXME(shell
, "Stub: This=%p\n",This
);
156 static HRESULT WINAPI
ISFDropTarget_DragLeave(
159 ICOM_THIS(ISFDropTarget
,iface
);
161 FIXME(shell
, "Stub: This=%p\n",This
);
166 static HRESULT WINAPI
ISFDropTarget_Drop(
168 IDataObject
* pDataObject
,
173 ICOM_THIS(ISFDropTarget
,iface
);
175 FIXME(shell
, "Stub: This=%p\n",This
);
180 static struct ICOM_VTABLE(IDropTarget
) dtvt
=
182 ISFDropTarget_QueryInterface
,
183 ISFDropTarget_AddRef
,
184 ISFDropTarget_Release
,
185 ISFDropTarget_DragEnter
,
186 ISFDropTarget_DragOver
,
187 ISFDropTarget_DragLeave
,
191 /***************************************************************************
192 * GetNextElement (internal function)
194 * gets a part of a string till the first backslash
197 * pszNext [IN] string to get the element from
198 * pszOut [IN] pointer to buffer whitch receives string
199 * dwOut [IN] length of pszOut
202 * LPSTR pointer to first, not yet parsed char
204 LPSTR
GetNextElement(LPSTR pszNext
,LPSTR pszOut
,DWORD dwOut
)
205 { LPSTR pszTail
= pszNext
;
207 TRACE(shell
,"(%s %p 0x%08lx)\n",debugstr_a(pszNext
),pszOut
,dwOut
);
209 if(!pszNext
|| !*pszNext
)
212 while(*pszTail
&& (*pszTail
!= '\\'))
215 dwCopy
=((LPBYTE
)pszTail
-(LPBYTE
)pszNext
)/sizeof(CHAR
)+1;
216 lstrcpynA(pszOut
, pszNext
, (dwOut
<dwCopy
)? dwOut
: dwCopy
);
222 TRACE(shell
,"--(%s %s 0x%08lx)\n",debugstr_a(pszNext
),debugstr_a(pszOut
),dwOut
);
226 /***********************************************************************
227 * IShellFolder implementation
229 static struct IShellFolder_VTable sfvt
=
230 { IShellFolder_QueryInterface
,
232 IShellFolder_Release
,
233 IShellFolder_ParseDisplayName
,
234 IShellFolder_EnumObjects
,
235 IShellFolder_BindToObject
,
236 IShellFolder_BindToStorage
,
237 IShellFolder_CompareIDs
,
238 IShellFolder_CreateViewObject
,
239 IShellFolder_GetAttributesOf
,
240 IShellFolder_GetUIObjectOf
,
241 IShellFolder_GetDisplayNameOf
,
242 IShellFolder_SetNameOf
,
243 IShellFolder_GetFolderPath
245 /**************************************************************************
246 * IShellFolder_Constructor
249 LPSHELLFOLDER
IShellFolder_Constructor(LPSHELLFOLDER pParent
,LPITEMIDLIST pidl
)
252 sf
=(LPSHELLFOLDER
)HeapAlloc(GetProcessHeap(),0,sizeof(IShellFolder
));
255 sf
->sMyPath
=NULL
; /* path of the folder */
256 sf
->pMyPidl
=NULL
; /* my qualified pidl */
258 TRACE(shell
,"(%p)->(parent=%p, pidl=%p)\n",sf
,pParent
, pidl
);
261 /* keep a copy of the pidl in the instance*/
262 sf
->mpidl
= ILClone(pidl
); /* my short pidl */
264 if(sf
->mpidl
) /* do we have a pidl? */
266 if(pParent
->sMyPath
) /* get the size of the parents path */
267 { dwSize
+= strlen(pParent
->sMyPath
) ;
268 TRACE(shell
,"-- (%p)->(parent's path=%s)\n",sf
, debugstr_a(pParent
->sMyPath
));
270 dwSize
+= _ILGetFolderText(sf
->mpidl
,NULL
,0); /* add the size of the foldername*/
271 sf
->sMyPath
= SHAlloc(dwSize
+2); /* '\0' and backslash */
275 if(pParent
->sMyPath
) /* if the parent has a path, get it*/
276 { strcpy(sf
->sMyPath
, pParent
->sMyPath
);
277 PathAddBackslashA (sf
->sMyPath
);
279 sf
->pMyPidl
= ILCombine(pParent
->pMyPidl
, pidl
);
280 len
= strlen(sf
->sMyPath
);
281 _ILGetFolderText(sf
->mpidl
, sf
->sMyPath
+len
, dwSize
-len
);
282 TRACE(shell
,"-- (%p)->(my pidl=%p, my path=%s)\n",sf
, sf
->pMyPidl
,debugstr_a(sf
->sMyPath
));
289 /**************************************************************************
290 * IShellFolder::QueryInterface
292 * REFIID riid, //[in ] Requested InterfaceID
293 * LPVOID* ppvObject) //[out] Interface* to hold the result
295 static HRESULT WINAPI
IShellFolder_QueryInterface(
296 LPSHELLFOLDER
this, REFIID riid
, LPVOID
*ppvObj
)
298 WINE_StringFromCLSID((LPCLSID
)riid
,xriid
);
299 TRACE(shell
,"(%p)->(\n\tIID:\t%s,%p)\n",this,xriid
,ppvObj
);
303 if(IsEqualIID(riid
, &IID_IUnknown
)) /*IUnknown*/
306 else if(IsEqualIID(riid
, &IID_IShellFolder
)) /*IShellFolder*/
307 { *ppvObj
= (IShellFolder
*)this;
311 { (*(LPSHELLFOLDER
*)ppvObj
)->lpvtbl
->fnAddRef(this);
312 TRACE(shell
,"-- Interface: (%p)->(%p)\n",ppvObj
,*ppvObj
);
315 TRACE(shell
,"-- Interface: E_NOINTERFACE\n");
316 return E_NOINTERFACE
;
319 /**************************************************************************
320 * IShellFolder::AddRef
323 static ULONG WINAPI
IShellFolder_AddRef(LPSHELLFOLDER
this)
324 { TRACE(shell
,"(%p)->(count=%lu)\n",this,this->ref
);
326 return ++(this->ref
);
329 /**************************************************************************
330 * IShellFolder_Release
332 static ULONG WINAPI
IShellFolder_Release(LPSHELLFOLDER
this)
333 { TRACE(shell
,"(%p)->(count=%lu)\n",this,this->ref
);
337 { TRACE(shell
,"-- destroying IShellFolder(%p)\n",this);
339 if (pdesktopfolder
==this)
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_ParseDisplayName
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_ParseDisplayName(
376 LPOLESTR lpszDisplayName
,
379 DWORD
*pdwAttributes
)
380 { HRESULT hr
=E_OUTOFMEMORY
;
381 LPITEMIDLIST pidlFull
=NULL
, pidlTemp
= NULL
, pidlOld
= NULL
;
383 CHAR szTemp
[MAX_PATH
],szElement
[MAX_PATH
];
386 TRACE(shell
,"(%p)->(HWND=0x%08x,%p,%p=%s,%p,pidl=%p,%p)\n",
387 this,hwndOwner
,pbcReserved
,lpszDisplayName
,
388 debugstr_w(lpszDisplayName
),pchEaten
,ppidl
,pdwAttributes
);
391 WideCharToLocal(szTemp
, lpszDisplayName
, lstrlenW(lpszDisplayName
) + 1);
393 { if (strcmp(szTemp
,"Desktop")==0)
394 { pidlFull
= _ILCreateDesktop();
396 else if (strcmp(szTemp
,"My Computer")==0)
397 { pidlFull
= _ILCreateMyComputer();
400 { if (!PathIsRootA(szTemp
))
401 { if (this->sMyPath
&& strlen (this->sMyPath
))
402 { if (strcmp(this->sMyPath
,"My Computer"))
403 { strcpy (szElement
,this->sMyPath
);
404 PathAddBackslashA (szElement
);
405 strcat (szElement
, szTemp
);
406 strcpy (szTemp
, szElement
);
411 /* check if the lpszDisplayName is Folder or File*/
412 bIsFile
= ! (GetFileAttributesA(szTemp
) & FILE_ATTRIBUTE_DIRECTORY
);
413 pszNext
= GetNextElement(szTemp
, szElement
, MAX_PATH
);
415 pidlFull
= _ILCreateMyComputer();
416 pidlTemp
= _ILCreateDrive(szElement
);
418 pidlFull
= ILCombine(pidlFull
,pidlTemp
);
422 { while((pszNext
=GetNextElement(pszNext
, szElement
, MAX_PATH
)))
423 { if(!*pszNext
&& bIsFile
)
424 { pidlTemp
= _ILCreateValue(NULL
, szElement
); /* FIXME: shortname */
427 { pidlTemp
= _ILCreateFolder(NULL
, szElement
); /* FIXME: shortname */
430 pidlFull
= ILCombine(pidlFull
,pidlTemp
);
442 /**************************************************************************
443 * IShellFolder_EnumObjects
445 * HWND hwndOwner, //[in ] Parent Window
446 * DWORD grfFlags, //[in ] SHCONTF enumeration mask
447 * LPENUMIDLIST* ppenumIDList //[out] IEnumIDList interface
449 static HRESULT WINAPI
IShellFolder_EnumObjects(
453 LPENUMIDLIST
* ppEnumIDList
)
454 { TRACE(shell
,"(%p)->(HWND=0x%08x flags=0x%08lx pplist=%p)\n",this,hwndOwner
,dwFlags
,ppEnumIDList
);
456 *ppEnumIDList
= NULL
;
457 *ppEnumIDList
= IEnumIDList_Constructor (this->sMyPath
, dwFlags
);
458 TRACE(shell
,"-- (%p)->(new ID List: %p)\n",this,*ppEnumIDList
);
460 { return E_OUTOFMEMORY
;
464 /**************************************************************************
465 * IShellFolder_Initialize()
466 * IPersistFolder Method
468 static HRESULT WINAPI
IShellFolder_Initialize( LPSHELLFOLDER
this,LPCITEMIDLIST pidl
)
469 { TRACE(shell
,"(%p)->(pidl=%p)\n",this,pidl
);
472 { SHFree(this->pMyPidl
);
473 this->pMyPidl
= NULL
;
475 this->pMyPidl
= ILClone(pidl
);
479 /**************************************************************************
480 * IShellFolder_BindToObject
482 * LPCITEMIDLIST pidl, //[in ] complex pidl to open
483 * LPBC pbc, //[in ] reserved
484 * REFIID riid, //[in ] Initial Interface
485 * LPVOID* ppvObject //[out] Interface*
487 static HRESULT WINAPI
IShellFolder_BindToObject( LPSHELLFOLDER
this, LPCITEMIDLIST pidl
,
488 LPBC pbcReserved
, REFIID riid
, LPVOID
* ppvOut
)
491 LPSHELLFOLDER pShellFolder
;
493 WINE_StringFromCLSID(riid
,xriid
);
495 TRACE(shell
,"(%p)->(pidl=%p,%p,\n\tIID:%s,%p)\n",this,pidl
,pbcReserved
,xriid
,ppvOut
);
499 pShellFolder
= IShellFolder_Constructor(this, pidl
);
502 return E_OUTOFMEMORY
;
504 hr
= pShellFolder
->lpvtbl
->fnQueryInterface(pShellFolder
, riid
, ppvOut
);
505 pShellFolder
->lpvtbl
->fnRelease(pShellFolder
);
506 TRACE(shell
,"-- (%p)->(interface=%p)\n",this, ppvOut
);
510 /**************************************************************************
511 * IShellFolder_BindToStorage
513 * LPCITEMIDLIST pidl, //[in ] complex pidl to store
514 * LPBC pbc, //[in ] reserved
515 * REFIID riid, //[in ] Initial storage interface
516 * LPVOID* ppvObject //[out] Interface* returned
518 static HRESULT WINAPI
IShellFolder_BindToStorage(LPSHELLFOLDER
this,
519 LPCITEMIDLIST pidl
,LPBC pbcReserved
, REFIID riid
, LPVOID
*ppvOut
)
521 WINE_StringFromCLSID(riid
,xriid
);
523 FIXME(shell
,"(%p)->(pidl=%p,%p,\n\tIID:%s,%p) stub\n",this,pidl
,pbcReserved
,xriid
,ppvOut
);
529 /**************************************************************************
530 * IShellFolder_CompareIDs
533 * LPARAM lParam, //[in ] Column?
534 * LPCITEMIDLIST pidl1, //[in ] simple pidl
535 * LPCITEMIDLIST pidl2) //[in ] simple pidl
538 * Special case - If one of the items is a Path and the other is a File,
539 * always make the Path come before the File.
542 * we have to handle simple pidl's only (?)
544 static HRESULT WINAPI
IShellFolder_CompareIDs(LPSHELLFOLDER
this,
545 LPARAM lParam
, LPCITEMIDLIST pidl1
, LPCITEMIDLIST pidl2
)
546 { CHAR szString1
[MAX_PATH
] = "";
547 CHAR szString2
[MAX_PATH
] = "";
549 LPCITEMIDLIST pidlTemp1
= pidl1
, pidlTemp2
= pidl2
;
551 TRACE(shell
,"(%p)->(0x%08lx,pidl1=%p,pidl2=%p)\n",this,lParam
,pidl1
,pidl2
);
555 if (!pidl1
&& !pidl2
)
557 if (!pidl1
) /* Desktop < anything */
562 /* get the last item in each list */
563 while((ILGetNext(pidlTemp1
))->mkid
.cb
)
564 pidlTemp1
= ILGetNext(pidlTemp1
);
565 while((ILGetNext(pidlTemp2
))->mkid
.cb
)
566 pidlTemp2
= ILGetNext(pidlTemp2
);
568 /* at this point, both pidlTemp1 and pidlTemp2 point to the last item in the list */
569 if(_ILIsValue(pidlTemp1
) != _ILIsValue(pidlTemp2
))
570 { if(_ILIsValue(pidlTemp1
))
575 _ILGetDrive( pidl1
,szString1
,sizeof(szString1
));
576 _ILGetDrive( pidl2
,szString1
,sizeof(szString2
));
577 nReturn
= strcasecmp(szString1
, szString2
);
582 _ILGetFolderText( pidl1
,szString1
,sizeof(szString1
));
583 _ILGetFolderText( pidl2
,szString2
,sizeof(szString2
));
584 nReturn
= strcasecmp(szString1
, szString2
);
589 _ILGetValueText(pidl1
,szString1
,sizeof(szString1
));
590 _ILGetValueText(pidl2
,szString2
,sizeof(szString2
));
591 return strcasecmp(szString1
, szString2
);
594 /**************************************************************************
595 * IShellFolder_CreateViewObject
596 * Creates an View Object representing the ShellFolder
597 * IShellView / IShellBrowser / IContextMenu
600 * HWND hwndOwner, // Handle of owner window
601 * REFIID riid, // Requested initial interface
602 * LPVOID* ppvObject) // Resultant interface*
605 * the same as SHCreateShellFolderViewEx ???
607 static HRESULT WINAPI
IShellFolder_CreateViewObject( LPSHELLFOLDER
this,
608 HWND hwndOwner
, REFIID riid
, LPVOID
*ppvOut
)
609 { LPSHELLVIEW pShellView
;
613 WINE_StringFromCLSID(riid
,xriid
);
614 TRACE(shell
,"(%p)->(hwnd=0x%x,\n\tIID:\t%s,%p)\n",this,hwndOwner
,xriid
,ppvOut
);
618 pShellView
= IShellView_Constructor(this, this->mpidl
);
621 return E_OUTOFMEMORY
;
623 hr
= pShellView
->lpvtbl
->fnQueryInterface(pShellView
, riid
, ppvOut
);
624 pShellView
->lpvtbl
->fnRelease(pShellView
);
625 TRACE(shell
,"-- (%p)->(interface=%p)\n",this, ppvOut
);
629 /**************************************************************************
630 * IShellFolder_GetAttributesOf
633 * UINT cidl, //[in ] num elements in pidl array
634 + LPCITEMIDLIST* apidl, //[in ] simple pidl array
635 * ULONG* rgfInOut) //[out] result array
638 * Note: rgfInOut is documented as being an array of ULONGS.
639 * This does not seem to be the case. Testing this function using the shell to
640 * call it with cidl > 1 (by deleting multiple items) reveals that the shell
641 * passes ONE element in the array and writing to further elements will
642 * cause the shell to fail later.
644 static HRESULT WINAPI
IShellFolder_GetAttributesOf(LPSHELLFOLDER
this,UINT cidl
,LPCITEMIDLIST
*apidl
,DWORD
*rgfInOut
)
645 { LPCITEMIDLIST
* pidltemp
;
648 TRACE(shell
,"(%p)->(%d,%p,%p)\n",this,cidl
,apidl
,rgfInOut
);
650 if ((! cidl
)| (!apidl
) | (!rgfInOut
))
657 TRACE(shell
,"-- mask=0x%08lx\n",*rgfInOut
);
662 if (_ILIsDesktop( *pidltemp
))
663 { *rgfInOut
|= ( SFGAO_HASSUBFOLDER
| SFGAO_FOLDER
| SFGAO_DROPTARGET
| SFGAO_HASPROPSHEET
| SFGAO_CANLINK
);
665 else if (_ILIsMyComputer( *pidltemp
))
666 { *rgfInOut
|= ( SFGAO_HASSUBFOLDER
| SFGAO_FOLDER
| SFGAO_FILESYSANCESTOR
667 | SFGAO_DROPTARGET
| SFGAO_HASPROPSHEET
| SFGAO_CANRENAME
| SFGAO_CANLINK
);
669 else if (_ILIsDrive( *pidltemp
))
670 { *rgfInOut
|= ( SFGAO_HASSUBFOLDER
| SFGAO_FILESYSTEM
| SFGAO_FOLDER
| SFGAO_FILESYSANCESTOR
|
671 SFGAO_DROPTARGET
| SFGAO_HASPROPSHEET
| SFGAO_CANLINK
);
673 else if (_ILIsFolder( *pidltemp
))
674 { *rgfInOut
|= ( SFGAO_HASSUBFOLDER
| SFGAO_FILESYSTEM
| SFGAO_FOLDER
| SFGAO_CAPABILITYMASK
);
676 else if (_ILIsValue( *pidltemp
))
677 { *rgfInOut
|= (SFGAO_FILESYSTEM
| SFGAO_CAPABILITYMASK
);
682 } while (cidl
> 0 && *pidltemp
);
686 /**************************************************************************
687 * IShellFolder_GetUIObjectOf
690 * HWND hwndOwner, //[in ] Parent window for any output
691 * UINT cidl, //[in ] array size
692 * LPCITEMIDLIST* apidl, //[in ] simple pidl array
693 * REFIID riid, //[in ] Requested Interface
694 * UINT* prgfInOut, //[ ] reserved
695 * LPVOID* ppvObject) //[out] Resulting Interface
698 * This function gets asked to return "view objects" for one or more (multiple select)
700 * The viewobject typically is an COM object with one of the following interfaces:
701 * IExtractIcon,IDataObject,IContextMenu
702 * In order to support icon positions in the default Listview your DataObject
703 * must implement the SetData method (in addition to GetData :) - the shell passes
704 * a barely documented "Icon positions" structure to SetData when the drag starts,
705 * and GetData's it if the drop is in another explorer window that needs the positions.
707 static HRESULT WINAPI
IShellFolder_GetUIObjectOf(
711 LPCITEMIDLIST
* apidl
,
718 LPUNKNOWN pObj
= NULL
;
720 WINE_StringFromCLSID(riid
,xclsid
);
722 TRACE(shell
,"(%p)->(%u,%u,apidl=%p,\n\tIID:%s,%p,%p)\n",
723 this,hwndOwner
,cidl
,apidl
,xclsid
,prgfInOut
,ppvOut
);
727 if(IsEqualIID(riid
, &IID_IContextMenu
))
732 pObj
= (LPUNKNOWN
)IContextMenu_Constructor(this, apidl
, cidl
);
734 else if (IsEqualIID(riid
, &IID_IDataObject
))
737 return(E_INVALIDARG
);
739 pObj
= (LPUNKNOWN
)IDataObject_Constructor (hwndOwner
, this, apidl
, cidl
);
741 else if(IsEqualIID(riid
, &IID_IExtractIcon
))
744 return(E_INVALIDARG
);
746 pidl
= ILCombine(this->pMyPidl
,apidl
[0]);
747 pObj
= (LPUNKNOWN
)IExtractIcon_Constructor( pidl
);
750 else if (IsEqualIID(riid
, &IID_IDropTarget
))
753 return(E_INVALIDARG
);
755 pObj
= (LPUNKNOWN
)ISFDropTarget_Constructor();
759 ERR(shell
,"(%p)->E_NOINTERFACE\n",this);
760 return E_NOINTERFACE
;
764 return E_OUTOFMEMORY
;
769 /**************************************************************************
770 * IShellFolder_GetDisplayNameOf
771 * Retrieves the display name for the specified file object or subfolder
774 * LPCITEMIDLIST pidl, //[in ] complex pidl to item
775 * DWORD dwFlags, //[in ] SHGNO formatting flags
776 * LPSTRRET lpName) //[out] Returned display name
779 * if the name is in the pidl the ret value should be a STRRET_OFFSET
781 #define GET_SHGDN_FOR(dwFlags) ((DWORD)dwFlags & (DWORD)0x0000FF00)
782 #define GET_SHGDN_RELATION(dwFlags) ((DWORD)dwFlags & (DWORD)0x000000FF)
784 static HRESULT WINAPI
IShellFolder_GetDisplayNameOf( LPSHELLFOLDER
this, LPCITEMIDLIST pidl
, DWORD dwFlags
, LPSTRRET lpName
)
785 { CHAR szText
[MAX_PATH
];
786 CHAR szTemp
[MAX_PATH
];
787 CHAR szSpecial
[MAX_PATH
];
788 CHAR szDrive
[MAX_PATH
];
789 DWORD dwVolumeSerialNumber
,dwMaximumComponetLength
,dwFileSystemFlags
;
790 LPITEMIDLIST pidlTemp
=NULL
;
791 BOOL bSimplePidl
=FALSE
;
793 TRACE(shell
,"(%p)->(pidl=%p,0x%08lx,%p)\n",this,pidl
,dwFlags
,lpName
);
801 /* test if simple(relative) or complex(absolute) pidl */
802 pidlTemp
= ILGetNext(pidl
);
803 if (pidlTemp
&& pidlTemp
->mkid
.cb
==0x00)
804 { bSimplePidl
= TRUE
;
805 TRACE(shell
,"-- simple pidl\n");
808 if (_ILIsDesktop( pidl
))
809 { strcpy (szText
,"Desktop");
812 { if (_ILIsMyComputer(pidl
))
813 { _ILGetItemText(pidl
, szSpecial
, MAX_PATH
);
814 pidl
= ILGetNext(pidl
);
817 if (_ILIsDrive(pidl
))
818 { _ILGetDrive( pidl
, szTemp
, MAX_PATH
);
820 if ( dwFlags
==SHGDN_NORMAL
|| dwFlags
==SHGDN_INFOLDER
) /* like "A1-dos (C:)" */
821 { GetVolumeInformationA(szTemp
,szDrive
,MAX_PATH
,&dwVolumeSerialNumber
,&dwMaximumComponetLength
,&dwFileSystemFlags
,NULL
,0);
822 szTemp
[2]=0x00; /* overwrite '\' */
823 strcat (szDrive
," (");
824 strcat (szDrive
,szTemp
);
825 strcat (szDrive
,")");
827 else /* like "C:\" */
828 { PathAddBackslashA (szTemp
);
829 strcpy(szDrive
,szTemp
);
835 { case SHGDN_NORMAL
: /* 0x0000 */
836 _ILGetPidlPath( pidl
, szText
, MAX_PATH
);
839 case SHGDN_INFOLDER
| SHGDN_FORPARSING
: /* 0x8001 */
840 case SHGDN_INFOLDER
: /* 0x0001 */
841 pidlTemp
= ILFindLastID(pidl
);
843 { _ILGetItemText( pidlTemp
, szText
, MAX_PATH
);
847 case SHGDN_FORPARSING
: /* 0x8000 */
849 { /* if the IShellFolder has parents, get the path from the
850 parent and add the ItemName*/
852 if (this->sMyPath
&& strlen (this->sMyPath
))
853 { if (strcmp(this->sMyPath
,"My Computer"))
854 { strcpy (szText
,this->sMyPath
);
855 PathAddBackslashA (szText
);
858 pidlTemp
= ILFindLastID(pidl
);
860 { _ILGetItemText( pidlTemp
, szTemp
, MAX_PATH
);
862 strcat(szText
,szTemp
);
864 else /* if the pidl is absolute, get everything from the pidl*/
865 { _ILGetPidlPath( pidl
, szText
, MAX_PATH
);
869 TRACE(shell
,"--- wrong flags=%lx\n", dwFlags
);
872 if ((szText
[0]==0x00 && szDrive
[0]!=0x00)|| (bSimplePidl
&& szDrive
[0]!=0x00))
873 { strcpy(szText
,szDrive
);
875 if (szText
[0]==0x00 && szSpecial
[0]!=0x00)
876 { strcpy(szText
,szSpecial
);
880 TRACE(shell
,"-- (%p)->(%s)\n",this,szText
);
883 { return E_OUTOFMEMORY
;
885 lpName
->uType
= STRRET_CSTRA
;
886 strcpy(lpName
->u
.cStr
,szText
);
890 /**************************************************************************
891 * IShellFolder_SetNameOf
892 * Changes the name of a file object or subfolder, possibly changing its item
893 * identifier in the process.
896 * HWND hwndOwner, //[in ] Owner window for output
897 * LPCITEMIDLIST pidl, //[in ] simple pidl of item to change
898 * LPCOLESTR lpszName, //[in ] the items new display name
899 * DWORD dwFlags, //[in ] SHGNO formatting flags
900 * LPITEMIDLIST* ppidlOut) //[out] simple pidl returned
902 static HRESULT WINAPI
IShellFolder_SetNameOf(
905 LPCITEMIDLIST pidl
, /*simple pidl*/
908 LPITEMIDLIST
*pPidlOut
)
909 { FIXME(shell
,"(%p)->(%u,pidl=%p,%s,%lu,%p),stub!\n",
910 this,hwndOwner
,pidl
,debugstr_w(lpName
),dw
,pPidlOut
);
913 /**************************************************************************
914 * IShellFolder_GetFolderPath
915 * FIXME: drive not included
917 static BOOL WINAPI
IShellFolder_GetFolderPath(LPSHELLFOLDER
this, LPSTR lpszOut
, DWORD dwOutSize
)
920 TRACE(shell
,"(%p)->(%p %lu)\n",this, lpszOut
, dwOutSize
);
930 dwSize
= strlen (this->sMyPath
) +1;
931 if ( dwSize
> dwOutSize
)
933 strcpy(lpszOut
, this->sMyPath
);
935 TRACE(shell
,"-- (%p)->(return=%s)\n",this, lpszOut
);