4 * Copyright 1997 Marcus Meissner
5 * Copyright 1998 Juergen Schmied
16 #include "wine/obj_base.h"
17 #include "wine/obj_dragdrop.h"
23 #include "shell32_main.h"
25 static HRESULT WINAPI
IShellFolder_QueryInterface(LPSHELLFOLDER
,REFIID
,LPVOID
*);
26 static ULONG WINAPI
IShellFolder_AddRef(LPSHELLFOLDER
);
27 static ULONG WINAPI
IShellFolder_Release(LPSHELLFOLDER
);
28 static HRESULT WINAPI
IShellFolder_Initialize(LPSHELLFOLDER
,LPCITEMIDLIST
);
29 static HRESULT WINAPI
IShellFolder_ParseDisplayName(LPSHELLFOLDER
,HWND
,LPBC
,LPOLESTR
,DWORD
*,LPITEMIDLIST
*,DWORD
*);
30 static HRESULT WINAPI
IShellFolder_EnumObjects(LPSHELLFOLDER
,HWND
,DWORD
,LPENUMIDLIST
*);
31 static HRESULT WINAPI
IShellFolder_BindToObject(LPSHELLFOLDER
,LPCITEMIDLIST
,LPBC
,REFIID
,LPVOID
*);
32 static HRESULT WINAPI
IShellFolder_BindToStorage(LPSHELLFOLDER
,LPCITEMIDLIST
,LPBC
,REFIID
,LPVOID
*);
33 static HRESULT WINAPI
IShellFolder_CompareIDs(LPSHELLFOLDER
,LPARAM
,LPCITEMIDLIST
,LPCITEMIDLIST
);
34 static HRESULT WINAPI
IShellFolder_CreateViewObject(LPSHELLFOLDER
,HWND
,REFIID
,LPVOID
*);
35 static HRESULT WINAPI
IShellFolder_GetAttributesOf(LPSHELLFOLDER
,UINT
,LPCITEMIDLIST
*,DWORD
*);
36 static HRESULT WINAPI
IShellFolder_GetUIObjectOf(LPSHELLFOLDER
,HWND
,UINT
,LPCITEMIDLIST
*,REFIID
,UINT
*,LPVOID
*);
37 static HRESULT WINAPI
IShellFolder_GetDisplayNameOf(LPSHELLFOLDER
,LPCITEMIDLIST
,DWORD
,LPSTRRET
);
38 static HRESULT WINAPI
IShellFolder_SetNameOf(LPSHELLFOLDER
,HWND
,LPCITEMIDLIST
,LPCOLESTR
,DWORD
,LPITEMIDLIST
*);
39 static BOOL WINAPI
IShellFolder_GetFolderPath(LPSHELLFOLDER
,LPSTR
,DWORD
);
41 /***************************************************************************
42 * IDropTarget interface definition for the ShellFolder
46 { ICOM_VTABLE(IDropTarget
)* lpvtbl
;
50 static struct ICOM_VTABLE(IDropTarget
) dtvt
;
53 /****************************************************************************
54 * ISFDropTarget implementation
57 static IDropTarget
* WINAPI
ISFDropTarget_Constructor(void)
61 sf
= HeapAlloc(GetProcessHeap(), 0, sizeof(ISFDropTarget
));
68 return (IDropTarget
*)sf
;
71 static HRESULT WINAPI
ISFDropTarget_QueryInterface(
76 ICOM_THIS(ISFDropTarget
,iface
);
79 WINE_StringFromCLSID((LPCLSID
)riid
,xriid
);
81 TRACE(shell
,"(%p)->(\n\tIID:\t%s,%p)\n",This
,xriid
,ppvObj
);
83 if ( !This
|| !ppvObj
)
88 if(IsEqualIID(riid
, &IID_IUnknown
)) /*IUnknown*/
91 else if(IsEqualIID(riid
, &IID_IDropTarget
)) /*IShellFolder*/
92 { *ppvObj
= (ISFDropTarget
*)This
;
96 { IDropTarget_AddRef((ISFDropTarget
*)*ppvObj
);
97 TRACE(shell
,"-- Interface: (%p)->(%p)\n",ppvObj
,*ppvObj
);
101 TRACE(shell
,"-- Interface: E_NOINTERFACE\n");
103 return E_NOINTERFACE
;
106 static ULONG WINAPI
ISFDropTarget_AddRef( IDropTarget
*iface
)
108 ICOM_THIS(ISFDropTarget
,iface
);
110 TRACE(shell
,"(%p)->(count=%lu)\n",This
,This
->ref
);
114 return ++(This
->ref
);
117 static ULONG WINAPI
ISFDropTarget_Release( IDropTarget
*iface
)
119 ICOM_THIS(ISFDropTarget
,iface
);
124 { TRACE(shell
,"-- destroying ISFDropTarget (%p)\n",This
);
125 HeapFree(GetProcessHeap(),0,This
);
131 static HRESULT WINAPI
ISFDropTarget_DragEnter(
133 IDataObject
*pDataObject
,
139 ICOM_THIS(ISFDropTarget
,iface
);
141 FIXME(shell
, "Stub: This=%p, DataObject=%p\n",This
,pDataObject
);
146 static HRESULT WINAPI
ISFDropTarget_DragOver(
152 ICOM_THIS(ISFDropTarget
,iface
);
154 FIXME(shell
, "Stub: This=%p\n",This
);
159 static HRESULT WINAPI
ISFDropTarget_DragLeave(
162 ICOM_THIS(ISFDropTarget
,iface
);
164 FIXME(shell
, "Stub: This=%p\n",This
);
169 static HRESULT WINAPI
ISFDropTarget_Drop(
171 IDataObject
* pDataObject
,
176 ICOM_THIS(ISFDropTarget
,iface
);
178 FIXME(shell
, "Stub: This=%p\n",This
);
183 static struct ICOM_VTABLE(IDropTarget
) dtvt
=
185 ISFDropTarget_QueryInterface
,
186 ISFDropTarget_AddRef
,
187 ISFDropTarget_Release
,
188 ISFDropTarget_DragEnter
,
189 ISFDropTarget_DragOver
,
190 ISFDropTarget_DragLeave
,
194 /***************************************************************************
195 * GetNextElement (internal function)
197 * gets a part of a string till the first backslash
200 * pszNext [IN] string to get the element from
201 * pszOut [IN] pointer to buffer whitch receives string
202 * dwOut [IN] length of pszOut
205 * LPSTR pointer to first, not yet parsed char
207 LPSTR
GetNextElement(LPSTR pszNext
,LPSTR pszOut
,DWORD dwOut
)
208 { LPSTR pszTail
= pszNext
;
210 TRACE(shell
,"(%s %p 0x%08lx)\n",debugstr_a(pszNext
),pszOut
,dwOut
);
212 if(!pszNext
|| !*pszNext
)
215 while(*pszTail
&& (*pszTail
!= '\\'))
218 dwCopy
=((LPBYTE
)pszTail
-(LPBYTE
)pszNext
)/sizeof(CHAR
)+1;
219 lstrcpynA(pszOut
, pszNext
, (dwOut
<dwCopy
)? dwOut
: dwCopy
);
225 TRACE(shell
,"--(%s %s 0x%08lx)\n",debugstr_a(pszNext
),debugstr_a(pszOut
),dwOut
);
229 /***********************************************************************
230 * IShellFolder implementation
232 static struct IShellFolder_VTable sfvt
=
233 { IShellFolder_QueryInterface
,
235 IShellFolder_Release
,
236 IShellFolder_ParseDisplayName
,
237 IShellFolder_EnumObjects
,
238 IShellFolder_BindToObject
,
239 IShellFolder_BindToStorage
,
240 IShellFolder_CompareIDs
,
241 IShellFolder_CreateViewObject
,
242 IShellFolder_GetAttributesOf
,
243 IShellFolder_GetUIObjectOf
,
244 IShellFolder_GetDisplayNameOf
,
245 IShellFolder_SetNameOf
,
246 IShellFolder_GetFolderPath
248 /**************************************************************************
249 * IShellFolder_Constructor
252 LPSHELLFOLDER
IShellFolder_Constructor(LPSHELLFOLDER pParent
,LPITEMIDLIST pidl
)
255 sf
=(LPSHELLFOLDER
)HeapAlloc(GetProcessHeap(),0,sizeof(IShellFolder
));
258 sf
->sMyPath
=NULL
; /* path of the folder */
259 sf
->pMyPidl
=NULL
; /* my qualified pidl */
261 TRACE(shell
,"(%p)->(parent=%p, pidl=%p)\n",sf
,pParent
, pidl
);
264 /* keep a copy of the pidl in the instance*/
265 sf
->mpidl
= ILClone(pidl
); /* my short pidl */
267 if(sf
->mpidl
) /* do we have a pidl? */
269 if(pParent
->sMyPath
) /* get the size of the parents path */
270 { dwSize
+= strlen(pParent
->sMyPath
) ;
271 TRACE(shell
,"-- (%p)->(parent's path=%s)\n",sf
, debugstr_a(pParent
->sMyPath
));
273 dwSize
+= _ILGetFolderText(sf
->mpidl
,NULL
,0); /* add the size of the foldername*/
274 sf
->sMyPath
= SHAlloc(dwSize
+2); /* '\0' and backslash */
278 if(pParent
->sMyPath
) /* if the parent has a path, get it*/
279 { strcpy(sf
->sMyPath
, pParent
->sMyPath
);
280 PathAddBackslashA (sf
->sMyPath
);
282 sf
->pMyPidl
= ILCombine(pParent
->pMyPidl
, pidl
);
283 len
= strlen(sf
->sMyPath
);
284 _ILGetFolderText(sf
->mpidl
, sf
->sMyPath
+len
, dwSize
-len
);
285 TRACE(shell
,"-- (%p)->(my pidl=%p, my path=%s)\n",sf
, sf
->pMyPidl
,debugstr_a(sf
->sMyPath
));
292 /**************************************************************************
293 * IShellFolder::QueryInterface
295 * REFIID riid, //[in ] Requested InterfaceID
296 * LPVOID* ppvObject) //[out] Interface* to hold the result
298 static HRESULT WINAPI
IShellFolder_QueryInterface(
299 LPSHELLFOLDER
this, REFIID riid
, LPVOID
*ppvObj
)
301 WINE_StringFromCLSID((LPCLSID
)riid
,xriid
);
302 TRACE(shell
,"(%p)->(\n\tIID:\t%s,%p)\n",this,xriid
,ppvObj
);
306 if(IsEqualIID(riid
, &IID_IUnknown
)) /*IUnknown*/
309 else if(IsEqualIID(riid
, &IID_IShellFolder
)) /*IShellFolder*/
310 { *ppvObj
= (IShellFolder
*)this;
314 { (*(LPSHELLFOLDER
*)ppvObj
)->lpvtbl
->fnAddRef(this);
315 TRACE(shell
,"-- Interface: (%p)->(%p)\n",ppvObj
,*ppvObj
);
318 TRACE(shell
,"-- Interface: E_NOINTERFACE\n");
319 return E_NOINTERFACE
;
322 /**************************************************************************
323 * IShellFolder::AddRef
326 static ULONG WINAPI
IShellFolder_AddRef(LPSHELLFOLDER
this)
327 { TRACE(shell
,"(%p)->(count=%lu)\n",this,this->ref
);
329 return ++(this->ref
);
332 /**************************************************************************
333 * IShellFolder_Release
335 static ULONG WINAPI
IShellFolder_Release(LPSHELLFOLDER
this)
336 { TRACE(shell
,"(%p)->(count=%lu)\n",this,this->ref
);
340 { TRACE(shell
,"-- destroying IShellFolder(%p)\n",this);
342 if (pdesktopfolder
==this)
343 { pdesktopfolder
=NULL
;
344 TRACE(shell
,"-- destroyed IShellFolder(%p) was Desktopfolder\n",this);
347 { SHFree(this->pMyPidl
);
350 { SHFree(this->mpidl
);
353 { SHFree(this->sMyPath
);
356 HeapFree(GetProcessHeap(),0,this);
362 /**************************************************************************
363 * IShellFolder_ParseDisplayName
365 * HWND hwndOwner, //[in ] Parent window for any message's
366 * LPBC pbc, //[in ] reserved
367 * LPOLESTR lpszDisplayName,//[in ] "Unicode" displayname.
368 * ULONG* pchEaten, //[out] (unicode) characters processed
369 * LPITEMIDLIST* ppidl, //[out] complex pidl to item
370 * ULONG* pdwAttributes //[out] items attributes
373 * pdwAttributes: not used
375 static HRESULT WINAPI
IShellFolder_ParseDisplayName(
379 LPOLESTR lpszDisplayName
,
382 DWORD
*pdwAttributes
)
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_EnumObjects
448 * HWND hwndOwner, //[in ] Parent Window
449 * DWORD grfFlags, //[in ] SHCONTF enumeration mask
450 * LPENUMIDLIST* ppenumIDList //[out] IEnumIDList interface
452 static HRESULT WINAPI
IShellFolder_EnumObjects(
456 LPENUMIDLIST
* ppEnumIDList
)
457 { TRACE(shell
,"(%p)->(HWND=0x%08x flags=0x%08lx pplist=%p)\n",this,hwndOwner
,dwFlags
,ppEnumIDList
);
459 *ppEnumIDList
= NULL
;
460 *ppEnumIDList
= IEnumIDList_Constructor (this->sMyPath
, dwFlags
);
461 TRACE(shell
,"-- (%p)->(new ID List: %p)\n",this,*ppEnumIDList
);
463 { return E_OUTOFMEMORY
;
467 /**************************************************************************
468 * IShellFolder_Initialize()
469 * IPersistFolder Method
471 static HRESULT WINAPI
IShellFolder_Initialize( LPSHELLFOLDER
this,LPCITEMIDLIST pidl
)
472 { TRACE(shell
,"(%p)->(pidl=%p)\n",this,pidl
);
475 { SHFree(this->pMyPidl
);
476 this->pMyPidl
= NULL
;
478 this->pMyPidl
= ILClone(pidl
);
482 /**************************************************************************
483 * IShellFolder_BindToObject
485 * LPCITEMIDLIST pidl, //[in ] complex pidl to open
486 * LPBC pbc, //[in ] reserved
487 * REFIID riid, //[in ] Initial Interface
488 * LPVOID* ppvObject //[out] Interface*
490 static HRESULT WINAPI
IShellFolder_BindToObject( LPSHELLFOLDER
this, LPCITEMIDLIST pidl
,
491 LPBC pbcReserved
, REFIID riid
, LPVOID
* ppvOut
)
494 LPSHELLFOLDER pShellFolder
;
496 WINE_StringFromCLSID(riid
,xriid
);
498 TRACE(shell
,"(%p)->(pidl=%p,%p,\n\tIID:%s,%p)\n",this,pidl
,pbcReserved
,xriid
,ppvOut
);
502 pShellFolder
= IShellFolder_Constructor(this, pidl
);
505 return E_OUTOFMEMORY
;
507 hr
= pShellFolder
->lpvtbl
->fnQueryInterface(pShellFolder
, riid
, ppvOut
);
508 pShellFolder
->lpvtbl
->fnRelease(pShellFolder
);
509 TRACE(shell
,"-- (%p)->(interface=%p)\n",this, ppvOut
);
513 /**************************************************************************
514 * IShellFolder_BindToStorage
516 * LPCITEMIDLIST pidl, //[in ] complex pidl to store
517 * LPBC pbc, //[in ] reserved
518 * REFIID riid, //[in ] Initial storage interface
519 * LPVOID* ppvObject //[out] Interface* returned
521 static HRESULT WINAPI
IShellFolder_BindToStorage(LPSHELLFOLDER
this,
522 LPCITEMIDLIST pidl
,LPBC pbcReserved
, REFIID riid
, LPVOID
*ppvOut
)
524 WINE_StringFromCLSID(riid
,xriid
);
526 FIXME(shell
,"(%p)->(pidl=%p,%p,\n\tIID:%s,%p) stub\n",this,pidl
,pbcReserved
,xriid
,ppvOut
);
532 /**************************************************************************
533 * IShellFolder_CompareIDs
536 * LPARAM lParam, //[in ] Column?
537 * LPCITEMIDLIST pidl1, //[in ] simple pidl
538 * LPCITEMIDLIST pidl2) //[in ] simple pidl
541 * Special case - If one of the items is a Path and the other is a File,
542 * always make the Path come before the File.
545 * we have to handle simple pidl's only (?)
547 static HRESULT WINAPI
IShellFolder_CompareIDs(LPSHELLFOLDER
this,
548 LPARAM lParam
, LPCITEMIDLIST pidl1
, LPCITEMIDLIST pidl2
)
549 { CHAR szString1
[MAX_PATH
] = "";
550 CHAR szString2
[MAX_PATH
] = "";
552 LPCITEMIDLIST pidlTemp1
= pidl1
, pidlTemp2
= pidl2
;
554 TRACE(shell
,"(%p)->(0x%08lx,pidl1=%p,pidl2=%p)\n",this,lParam
,pidl1
,pidl2
);
558 if (!pidl1
&& !pidl2
)
560 if (!pidl1
) /* Desktop < anything */
565 /* get the last item in each list */
566 while((ILGetNext(pidlTemp1
))->mkid
.cb
)
567 pidlTemp1
= ILGetNext(pidlTemp1
);
568 while((ILGetNext(pidlTemp2
))->mkid
.cb
)
569 pidlTemp2
= ILGetNext(pidlTemp2
);
571 /* at this point, both pidlTemp1 and pidlTemp2 point to the last item in the list */
572 if(_ILIsValue(pidlTemp1
) != _ILIsValue(pidlTemp2
))
573 { if(_ILIsValue(pidlTemp1
))
578 _ILGetDrive( pidl1
,szString1
,sizeof(szString1
));
579 _ILGetDrive( pidl2
,szString1
,sizeof(szString2
));
580 nReturn
= strcasecmp(szString1
, szString2
);
585 _ILGetFolderText( pidl1
,szString1
,sizeof(szString1
));
586 _ILGetFolderText( pidl2
,szString2
,sizeof(szString2
));
587 nReturn
= strcasecmp(szString1
, szString2
);
592 _ILGetValueText(pidl1
,szString1
,sizeof(szString1
));
593 _ILGetValueText(pidl2
,szString2
,sizeof(szString2
));
594 return strcasecmp(szString1
, szString2
);
597 /**************************************************************************
598 * IShellFolder_CreateViewObject
599 * Creates an View Object representing the ShellFolder
600 * IShellView / IShellBrowser / IContextMenu
603 * HWND hwndOwner, // Handle of owner window
604 * REFIID riid, // Requested initial interface
605 * LPVOID* ppvObject) // Resultant interface*
608 * the same as SHCreateShellFolderViewEx ???
610 static HRESULT WINAPI
IShellFolder_CreateViewObject( LPSHELLFOLDER
this,
611 HWND hwndOwner
, REFIID riid
, LPVOID
*ppvOut
)
612 { LPSHELLVIEW pShellView
;
616 WINE_StringFromCLSID(riid
,xriid
);
617 TRACE(shell
,"(%p)->(hwnd=0x%x,\n\tIID:\t%s,%p)\n",this,hwndOwner
,xriid
,ppvOut
);
621 pShellView
= IShellView_Constructor(this, this->mpidl
);
624 return E_OUTOFMEMORY
;
626 hr
= pShellView
->lpvtbl
->fnQueryInterface(pShellView
, riid
, ppvOut
);
627 pShellView
->lpvtbl
->fnRelease(pShellView
);
628 TRACE(shell
,"-- (%p)->(interface=%p)\n",this, ppvOut
);
632 /**************************************************************************
633 * IShellFolder_GetAttributesOf
636 * UINT cidl, //[in ] num elements in pidl array
637 + LPCITEMIDLIST* apidl, //[in ] simple pidl array
638 * ULONG* rgfInOut) //[out] result array
641 * Note: rgfInOut is documented as being an array of ULONGS.
642 * This does not seem to be the case. Testing this function using the shell to
643 * call it with cidl > 1 (by deleting multiple items) reveals that the shell
644 * passes ONE element in the array and writing to further elements will
645 * cause the shell to fail later.
647 static HRESULT WINAPI
IShellFolder_GetAttributesOf(LPSHELLFOLDER
this,UINT cidl
,LPCITEMIDLIST
*apidl
,DWORD
*rgfInOut
)
648 { LPCITEMIDLIST
* pidltemp
;
651 TRACE(shell
,"(%p)->(%d,%p,%p)\n",this,cidl
,apidl
,rgfInOut
);
653 if ((! cidl
)| (!apidl
) | (!rgfInOut
))
660 TRACE(shell
,"-- mask=0x%08lx\n",*rgfInOut
);
665 if (_ILIsDesktop( *pidltemp
))
666 { *rgfInOut
|= ( SFGAO_HASSUBFOLDER
| SFGAO_FOLDER
| SFGAO_DROPTARGET
| SFGAO_HASPROPSHEET
| SFGAO_CANLINK
);
668 else if (_ILIsMyComputer( *pidltemp
))
669 { *rgfInOut
|= ( SFGAO_HASSUBFOLDER
| SFGAO_FOLDER
| SFGAO_FILESYSANCESTOR
670 | SFGAO_DROPTARGET
| SFGAO_HASPROPSHEET
| SFGAO_CANRENAME
| SFGAO_CANLINK
);
672 else if (_ILIsDrive( *pidltemp
))
673 { *rgfInOut
|= ( SFGAO_HASSUBFOLDER
| SFGAO_FILESYSTEM
| SFGAO_FOLDER
| SFGAO_FILESYSANCESTOR
|
674 SFGAO_DROPTARGET
| SFGAO_HASPROPSHEET
| SFGAO_CANLINK
);
676 else if (_ILIsFolder( *pidltemp
))
677 { *rgfInOut
|= ( SFGAO_HASSUBFOLDER
| SFGAO_FILESYSTEM
| SFGAO_FOLDER
| SFGAO_CAPABILITYMASK
);
679 else if (_ILIsValue( *pidltemp
))
680 { *rgfInOut
|= (SFGAO_FILESYSTEM
| SFGAO_CAPABILITYMASK
);
685 } while (cidl
> 0 && *pidltemp
);
689 /**************************************************************************
690 * IShellFolder_GetUIObjectOf
693 * HWND hwndOwner, //[in ] Parent window for any output
694 * UINT cidl, //[in ] array size
695 * LPCITEMIDLIST* apidl, //[in ] simple pidl array
696 * REFIID riid, //[in ] Requested Interface
697 * UINT* prgfInOut, //[ ] reserved
698 * LPVOID* ppvObject) //[out] Resulting Interface
701 * This function gets asked to return "view objects" for one or more (multiple select)
703 * The viewobject typically is an COM object with one of the following interfaces:
704 * IExtractIcon,IDataObject,IContextMenu
705 * In order to support icon positions in the default Listview your DataObject
706 * must implement the SetData method (in addition to GetData :) - the shell passes
707 * a barely documented "Icon positions" structure to SetData when the drag starts,
708 * and GetData's it if the drop is in another explorer window that needs the positions.
710 static HRESULT WINAPI
IShellFolder_GetUIObjectOf(
714 LPCITEMIDLIST
* apidl
,
721 LPUNKNOWN pObj
= NULL
;
723 WINE_StringFromCLSID(riid
,xclsid
);
725 TRACE(shell
,"(%p)->(%u,%u,apidl=%p,\n\tIID:%s,%p,%p)\n",
726 this,hwndOwner
,cidl
,apidl
,xclsid
,prgfInOut
,ppvOut
);
730 if(IsEqualIID(riid
, &IID_IContextMenu
))
735 pObj
= (LPUNKNOWN
)IContextMenu_Constructor(this, apidl
, cidl
);
737 else if (IsEqualIID(riid
, &IID_IDataObject
))
740 return(E_INVALIDARG
);
742 pObj
= (LPUNKNOWN
)IDataObject_Constructor (hwndOwner
, this, apidl
, cidl
);
744 else if(IsEqualIID(riid
, &IID_IExtractIcon
))
747 return(E_INVALIDARG
);
749 pidl
= ILCombine(this->pMyPidl
,apidl
[0]);
750 pObj
= (LPUNKNOWN
)IExtractIcon_Constructor( pidl
);
753 else if (IsEqualIID(riid
, &IID_IDropTarget
))
756 return(E_INVALIDARG
);
758 pObj
= (LPUNKNOWN
)ISFDropTarget_Constructor();
762 ERR(shell
,"(%p)->E_NOINTERFACE\n",this);
763 return E_NOINTERFACE
;
767 return E_OUTOFMEMORY
;
772 /**************************************************************************
773 * IShellFolder_GetDisplayNameOf
774 * Retrieves the display name for the specified file object or subfolder
777 * LPCITEMIDLIST pidl, //[in ] complex pidl to item
778 * DWORD dwFlags, //[in ] SHGNO formatting flags
779 * LPSTRRET lpName) //[out] Returned display name
782 * if the name is in the pidl the ret value should be a STRRET_OFFSET
784 #define GET_SHGDN_FOR(dwFlags) ((DWORD)dwFlags & (DWORD)0x0000FF00)
785 #define GET_SHGDN_RELATION(dwFlags) ((DWORD)dwFlags & (DWORD)0x000000FF)
787 static HRESULT WINAPI
IShellFolder_GetDisplayNameOf( LPSHELLFOLDER
this, LPCITEMIDLIST pidl
, DWORD dwFlags
, LPSTRRET lpName
)
788 { CHAR szText
[MAX_PATH
];
789 CHAR szTemp
[MAX_PATH
];
790 CHAR szSpecial
[MAX_PATH
];
791 CHAR szDrive
[MAX_PATH
];
792 DWORD dwVolumeSerialNumber
,dwMaximumComponetLength
,dwFileSystemFlags
;
793 LPITEMIDLIST pidlTemp
=NULL
;
794 BOOL bSimplePidl
=FALSE
;
796 TRACE(shell
,"(%p)->(pidl=%p,0x%08lx,%p)\n",this,pidl
,dwFlags
,lpName
);
804 /* test if simple(relative) or complex(absolute) pidl */
805 pidlTemp
= ILGetNext(pidl
);
806 if (pidlTemp
&& pidlTemp
->mkid
.cb
==0x00)
807 { bSimplePidl
= TRUE
;
808 TRACE(shell
,"-- simple pidl\n");
811 if (_ILIsDesktop( pidl
))
812 { strcpy (szText
,"Desktop");
815 { if (_ILIsMyComputer(pidl
))
816 { _ILGetItemText(pidl
, szSpecial
, MAX_PATH
);
817 pidl
= ILGetNext(pidl
);
820 if (_ILIsDrive(pidl
))
821 { _ILGetDrive( pidl
, szTemp
, MAX_PATH
);
823 if ( dwFlags
==SHGDN_NORMAL
|| dwFlags
==SHGDN_INFOLDER
) /* like "A1-dos (C:)" */
824 { GetVolumeInformationA(szTemp
,szDrive
,MAX_PATH
,&dwVolumeSerialNumber
,&dwMaximumComponetLength
,&dwFileSystemFlags
,NULL
,0);
825 szTemp
[2]=0x00; /* overwrite '\' */
826 strcat (szDrive
," (");
827 strcat (szDrive
,szTemp
);
828 strcat (szDrive
,")");
830 else /* like "C:\" */
831 { PathAddBackslashA (szTemp
);
832 strcpy(szDrive
,szTemp
);
838 { case SHGDN_NORMAL
: /* 0x0000 */
839 _ILGetPidlPath( pidl
, szText
, MAX_PATH
);
842 case SHGDN_INFOLDER
| SHGDN_FORPARSING
: /* 0x8001 */
843 case SHGDN_INFOLDER
: /* 0x0001 */
844 pidlTemp
= ILFindLastID(pidl
);
846 { _ILGetItemText( pidlTemp
, szText
, MAX_PATH
);
850 case SHGDN_FORPARSING
: /* 0x8000 */
852 { /* if the IShellFolder has parents, get the path from the
853 parent and add the ItemName*/
855 if (this->sMyPath
&& strlen (this->sMyPath
))
856 { if (strcmp(this->sMyPath
,"My Computer"))
857 { strcpy (szText
,this->sMyPath
);
858 PathAddBackslashA (szText
);
861 pidlTemp
= ILFindLastID(pidl
);
863 { _ILGetItemText( pidlTemp
, szTemp
, MAX_PATH
);
865 strcat(szText
,szTemp
);
867 else /* if the pidl is absolute, get everything from the pidl*/
868 { _ILGetPidlPath( pidl
, szText
, MAX_PATH
);
872 TRACE(shell
,"--- wrong flags=%lx\n", dwFlags
);
875 if ((szText
[0]==0x00 && szDrive
[0]!=0x00)|| (bSimplePidl
&& szDrive
[0]!=0x00))
876 { strcpy(szText
,szDrive
);
878 if (szText
[0]==0x00 && szSpecial
[0]!=0x00)
879 { strcpy(szText
,szSpecial
);
883 TRACE(shell
,"-- (%p)->(%s)\n",this,szText
);
886 { return E_OUTOFMEMORY
;
888 lpName
->uType
= STRRET_CSTRA
;
889 strcpy(lpName
->u
.cStr
,szText
);
893 /**************************************************************************
894 * IShellFolder_SetNameOf
895 * Changes the name of a file object or subfolder, possibly changing its item
896 * identifier in the process.
899 * HWND hwndOwner, //[in ] Owner window for output
900 * LPCITEMIDLIST pidl, //[in ] simple pidl of item to change
901 * LPCOLESTR lpszName, //[in ] the items new display name
902 * DWORD dwFlags, //[in ] SHGNO formatting flags
903 * LPITEMIDLIST* ppidlOut) //[out] simple pidl returned
905 static HRESULT WINAPI
IShellFolder_SetNameOf(
908 LPCITEMIDLIST pidl
, /*simple pidl*/
911 LPITEMIDLIST
*pPidlOut
)
912 { FIXME(shell
,"(%p)->(%u,pidl=%p,%s,%lu,%p),stub!\n",
913 this,hwndOwner
,pidl
,debugstr_w(lpName
),dw
,pPidlOut
);
916 /**************************************************************************
917 * IShellFolder_GetFolderPath
918 * FIXME: drive not included
920 static BOOL WINAPI
IShellFolder_GetFolderPath(LPSHELLFOLDER
this, LPSTR lpszOut
, DWORD dwOutSize
)
923 TRACE(shell
,"(%p)->(%p %lu)\n",this, lpszOut
, dwOutSize
);
933 dwSize
= strlen (this->sMyPath
) +1;
934 if ( dwSize
> dwOutSize
)
936 strcpy(lpszOut
, this->sMyPath
);
938 TRACE(shell
,"-- (%p)->(return=%s)\n",this, lpszOut
);