2 * Virtual MyDocuments Folder
4 * Copyright 2007 Johannes Anderwald
5 * Copyright 2009 Andrew Hill
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
24 WINE_DEFAULT_DEBUG_CHANNEL (mydocs
);
27 CFileSysEnumX should not exist. CMyDocsFolder should aggregate a CFSFolder which always
28 maps the contents of CSIDL_PERSONAL. Therefore, CMyDocsFolder::EnumObjects simply calls
29 CFSFolder::EnumObjects.
32 /***********************************************************************
33 * MyDocumentsfolder implementation
37 public IEnumIDListImpl
43 HRESULT WINAPI
Initialize(DWORD dwFlags
);
45 BEGIN_COM_MAP(CFileSysEnumX
)
46 COM_INTERFACE_ENTRY_IID(IID_IEnumIDList
, IEnumIDList
)
50 static const shvheader MyDocumentsSFHeader
[] = {
51 {IDS_SHV_COLUMN1
, SHCOLSTATE_TYPE_STR
| SHCOLSTATE_ONBYDEFAULT
, LVCFMT_RIGHT
, 15},
52 {IDS_SHV_COLUMN2
, SHCOLSTATE_TYPE_STR
| SHCOLSTATE_ONBYDEFAULT
, LVCFMT_RIGHT
, 10},
53 {IDS_SHV_COLUMN3
, SHCOLSTATE_TYPE_STR
| SHCOLSTATE_ONBYDEFAULT
, LVCFMT_RIGHT
, 10},
54 {IDS_SHV_COLUMN4
, SHCOLSTATE_TYPE_DATE
| SHCOLSTATE_ONBYDEFAULT
, LVCFMT_RIGHT
, 12},
55 {IDS_SHV_COLUMN5
, SHCOLSTATE_TYPE_STR
| SHCOLSTATE_ONBYDEFAULT
, LVCFMT_RIGHT
, 5}
58 #define MYDOCUMENTSSHELLVIEWCOLUMNS 5
60 CFileSysEnumX::CFileSysEnumX()
64 CFileSysEnumX::~CFileSysEnumX()
68 HRESULT WINAPI
CFileSysEnumX::Initialize(DWORD dwFlags
)
70 WCHAR szPath
[MAX_PATH
];
72 if (SHGetSpecialFolderPathW(0, szPath
, CSIDL_PERSONAL
, FALSE
) == FALSE
)
74 return CreateFolderEnumList(szPath
, dwFlags
);
77 CMyDocsFolder::CMyDocsFolder()
84 CMyDocsFolder::~CMyDocsFolder()
86 TRACE ("-- destroying IShellFolder(%p)\n", this);
88 HeapFree(GetProcessHeap(), 0, sPathTarget
);
89 mFSDropTarget
->Release();
92 HRESULT WINAPI
CMyDocsFolder::FinalConstruct()
94 WCHAR szMyPath
[MAX_PATH
];
96 if (!SHGetSpecialFolderPathW(0, szMyPath
, CSIDL_PERSONAL
, TRUE
))
99 pidlRoot
= _ILCreateMyDocuments(); /* my qualified pidl */
100 sPathTarget
= (LPWSTR
)SHAlloc((wcslen(szMyPath
) + 1) * sizeof(WCHAR
));
101 wcscpy(sPathTarget
, szMyPath
);
103 LPITEMIDLIST pidl
= NULL
;
105 WCHAR szPath
[MAX_PATH
];
106 lstrcpynW(szPath
, sPathTarget
, MAX_PATH
);
107 PathAddBackslashW(szPath
);
108 CComPtr
<IShellFolder
> psfDesktop
= NULL
;
110 HRESULT hr
= SHGetDesktopFolder(&psfDesktop
);
112 hr
= psfDesktop
->ParseDisplayName(NULL
, NULL
, szPath
, NULL
, &pidl
, NULL
);
114 ERR("Error getting desktop folder\n");
118 hr
= psfDesktop
->BindToObject(pidl
, NULL
, IID_IDropTarget
, (LPVOID
*) &mFSDropTarget
);
121 ERR("Error Binding");
124 ERR("Error creating from %s\n", debugstr_w(szPath
));
129 HRESULT WINAPI
CMyDocsFolder::ParseDisplayName(HWND hwndOwner
, LPBC pbc
, LPOLESTR lpszDisplayName
,
130 DWORD
*pchEaten
, PIDLIST_RELATIVE
*ppidl
, DWORD
*pdwAttributes
)
132 WCHAR szElement
[MAX_PATH
];
133 LPCWSTR szNext
= NULL
;
134 LPITEMIDLIST pidlTemp
= NULL
;
138 TRACE ("(%p)->(HWND=%p,%p,%p=%s,%p,pidl=%p,%p)\n",
139 this, hwndOwner
, pbc
, lpszDisplayName
, debugstr_w(lpszDisplayName
),
140 pchEaten
, ppidl
, pdwAttributes
);
142 if (!lpszDisplayName
|| !ppidl
)
148 *pchEaten
= 0; /* strange but like the original */
150 if (lpszDisplayName
[0] == ':' && lpszDisplayName
[1] == ':')
152 szNext
= GetNextElementW (lpszDisplayName
, szElement
, MAX_PATH
);
153 TRACE("-- element: %s\n", debugstr_w (szElement
));
154 CLSIDFromString(szElement
+ 2, &clsid
);
155 pidlTemp
= _ILCreateGuid (PT_GUID
, clsid
);
157 else if( (pidlTemp
= SHELL32_CreatePidlFromBindCtx(pbc
, lpszDisplayName
)) )
164 /* it's a filesystem path on the desktop. Let a FSFolder parse it */
166 if (*lpszDisplayName
)
168 WCHAR szPath
[MAX_PATH
];
171 /* build a complete path to create a simple pidl */
172 lstrcpynW(szPath
, sPathTarget
, MAX_PATH
);
173 pathPtr
= PathAddBackslashW(szPath
);
176 lstrcpynW(pathPtr
, lpszDisplayName
, MAX_PATH
- (pathPtr
- szPath
));
177 hr
= _ILCreateFromPathW(szPath
, &pidlTemp
);
181 /* should never reach here, but for completeness */
182 hr
= HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER
);
186 pidlTemp
= _ILCreateMyDocuments();
191 if (SUCCEEDED(hr
) && pidlTemp
)
193 if (szNext
&& *szNext
)
195 hr
= SHELL32_ParseNextElement(this, hwndOwner
, pbc
,
196 &pidlTemp
, (LPOLESTR
) szNext
, pchEaten
, pdwAttributes
);
200 if (pdwAttributes
&& *pdwAttributes
)
201 hr
= SHELL32_GetItemAttributes(this, pidlTemp
, pdwAttributes
);
207 TRACE ("(%p)->(-- ret=0x%08x)\n", this, hr
);
212 /**************************************************************************
213 * ISF_MyDocuments_fnEnumObjects
215 HRESULT WINAPI
CMyDocsFolder::EnumObjects(HWND hwndOwner
, DWORD dwFlags
, LPENUMIDLIST
*ppEnumIDList
)
217 CComObject
<CFileSysEnumX
> *theEnumerator
;
218 CComPtr
<IEnumIDList
> result
;
221 TRACE("(%p)->(HWND=%p flags=0x%08x pplist=%p)\n", this, hwndOwner
, dwFlags
, ppEnumIDList
);
223 if (ppEnumIDList
== NULL
)
225 *ppEnumIDList
= NULL
;
226 ATLTRY (theEnumerator
= new CComObject
<CFileSysEnumX
>);
227 if (theEnumerator
== NULL
)
228 return E_OUTOFMEMORY
;
229 hResult
= theEnumerator
->QueryInterface(IID_IEnumIDList
, (void **)&result
);
230 if (FAILED (hResult
))
232 delete theEnumerator
;
235 hResult
= theEnumerator
->Initialize(dwFlags
);
236 if (FAILED (hResult
))
238 *ppEnumIDList
= result
.Detach();
240 TRACE("-- (%p)->(new ID List: %p)\n", this, *ppEnumIDList
);
245 /**************************************************************************
246 * CMyDocsFolder::BindToObject
248 HRESULT WINAPI
CMyDocsFolder::BindToObject(PCUIDLIST_RELATIVE pidl
, LPBC pbcReserved
, REFIID riid
, LPVOID
*ppvOut
)
250 TRACE("(%p)->(pidl=%p,%p,%s,%p)\n",
251 this, pidl
, pbcReserved
, shdebugstr_guid (&riid
), ppvOut
);
253 return SHELL32_BindToChild( pidlRoot
, sPathTarget
, pidl
, riid
, ppvOut
);
256 /**************************************************************************
257 * CMyDocsFolder::BindToStorage
259 HRESULT WINAPI
CMyDocsFolder::BindToStorage(PCUIDLIST_RELATIVE pidl
, LPBC pbcReserved
, REFIID riid
, LPVOID
*ppvOut
)
261 FIXME("(%p)->(pidl=%p,%p,%s,%p) stub\n",
262 this, pidl
, pbcReserved
, shdebugstr_guid (&riid
), ppvOut
);
268 /**************************************************************************
269 * CMyDocsFolder::CompareIDs
271 HRESULT WINAPI
CMyDocsFolder::CompareIDs(LPARAM lParam
, PCUIDLIST_RELATIVE pidl1
, PCUIDLIST_RELATIVE pidl2
)
275 TRACE ("(%p)->(0x%08lx,pidl1=%p,pidl2=%p)\n", this, lParam
, pidl1
, pidl2
);
276 nReturn
= SHELL32_CompareIDs (this, lParam
, pidl1
, pidl2
);
277 TRACE ("-- %i\n", nReturn
);
281 /**************************************************************************
282 * CMyDocsFolder::CreateViewObject
284 HRESULT WINAPI
CMyDocsFolder::CreateViewObject(HWND hwndOwner
, REFIID riid
, LPVOID
*ppvOut
)
286 LPSHELLVIEW pShellView
;
287 HRESULT hr
= E_INVALIDARG
;
289 TRACE ("(%p)->(hwnd=%p,%s,%p)\n",
290 this, hwndOwner
, shdebugstr_guid (&riid
), ppvOut
);
297 if (IsEqualIID (riid
, IID_IDropTarget
))
299 hr
= this->QueryInterface (IID_IDropTarget
, ppvOut
);
301 else if (IsEqualIID (riid
, IID_IContextMenu
))
303 WARN ("IContextMenu not implemented\n");
306 else if (IsEqualIID (riid
, IID_IShellView
))
308 hr
= IShellView_Constructor ((IShellFolder
*)this, &pShellView
);
311 hr
= pShellView
->QueryInterface(riid
, ppvOut
);
312 pShellView
->Release();
315 TRACE ("-- (%p)->(interface=%p)\n", this, ppvOut
);
319 /**************************************************************************
320 * CMyDocsFolder::GetAttributesOf
322 HRESULT WINAPI
CMyDocsFolder::GetAttributesOf(UINT cidl
, PCUITEMID_CHILD_ARRAY apidl
, DWORD
*rgfInOut
)
325 static const DWORD dwMyDocumentsAttributes
=
326 SFGAO_STORAGE
| SFGAO_HASPROPSHEET
| SFGAO_STORAGEANCESTOR
| SFGAO_CANCOPY
|
327 SFGAO_FILESYSANCESTOR
| SFGAO_FOLDER
| SFGAO_FILESYSTEM
| SFGAO_HASSUBFOLDER
| SFGAO_CANRENAME
| SFGAO_CANDELETE
;
329 TRACE ("(%p)->(cidl=%d apidl=%p mask=%p (0x%08x))\n",
330 this, cidl
, apidl
, rgfInOut
, rgfInOut
? *rgfInOut
: 0);
341 *rgfInOut
&= dwMyDocumentsAttributes
;
343 while (cidl
> 0 && *apidl
) {
345 if (_ILIsMyDocuments(*apidl
)) {
346 *rgfInOut
&= dwMyDocumentsAttributes
;
348 SHELL32_GetItemAttributes (this, *apidl
, rgfInOut
);
354 /* make sure SFGAO_VALIDATE is cleared, some apps depend on that */
355 *rgfInOut
&= ~SFGAO_VALIDATE
;
357 TRACE ("-- result=0x%08x\n", *rgfInOut
);
362 /**************************************************************************
363 * CMyDocsFolder::GetUIObjectOf
366 * HWND hwndOwner, //[in ] Parent window for any output
367 * UINT cidl, //[in ] array size
368 * LPCITEMIDLIST* apidl, //[in ] simple pidl array
369 * REFIID riid, //[in ] Requested Interface
370 * UINT* prgfInOut, //[ ] reserved
371 * LPVOID* ppvObject) //[out] Resulting Interface
374 HRESULT WINAPI
CMyDocsFolder::GetUIObjectOf(HWND hwndOwner
, UINT cidl
, PCUITEMID_CHILD_ARRAY apidl
,
375 REFIID riid
, UINT
* prgfInOut
, LPVOID
* ppvOut
)
378 IUnknown
*pObj
= NULL
;
379 HRESULT hr
= E_INVALIDARG
;
381 TRACE ("(%p)->(%p,%u,apidl=%p,%s,%p,%p)\n",
382 this, hwndOwner
, cidl
, apidl
, shdebugstr_guid (&riid
), prgfInOut
, ppvOut
);
389 if (IsEqualIID (riid
, IID_IContextMenu
))
391 hr
= CDefFolderMenu_Create2(pidlRoot
, hwndOwner
, cidl
, apidl
, (IShellFolder
*)this, NULL
, 0, NULL
, (IContextMenu
**)&pObj
);
393 else if (IsEqualIID (riid
, IID_IDataObject
) && (cidl
>= 1))
395 hr
= IDataObject_Constructor( hwndOwner
,
396 pidlRoot
, apidl
, cidl
, (IDataObject
**)&pObj
);
398 else if (IsEqualIID (riid
, IID_IExtractIconA
) && (cidl
== 1))
400 pidl
= ILCombine (pidlRoot
, apidl
[0]);
401 pObj
= (LPUNKNOWN
) IExtractIconA_Constructor (pidl
);
405 else if (IsEqualIID (riid
, IID_IExtractIconW
) && (cidl
== 1))
407 pidl
= ILCombine (pidlRoot
, apidl
[0]);
408 pObj
= (LPUNKNOWN
) IExtractIconW_Constructor (pidl
);
412 else if (IsEqualIID (riid
, IID_IDropTarget
) && (cidl
>= 1))
414 hr
= this->QueryInterface (IID_IDropTarget
, (LPVOID
*)&pObj
);
416 else if ((IsEqualIID(riid
, IID_IShellLinkW
) ||
417 IsEqualIID(riid
, IID_IShellLinkA
)) && (cidl
== 1))
419 pidl
= ILCombine (pidlRoot
, apidl
[0]);
420 hr
= IShellLink_ConstructFromFile(NULL
, riid
, pidl
, (LPVOID
*)&pObj
);
426 if (SUCCEEDED(hr
) && !pObj
)
430 TRACE ("(%p)->hr=0x%08x\n", this, hr
);
434 HRESULT WINAPI
CMyDocsFolder::GetDisplayNameOf(PCUITEMID_CHILD pidl
, DWORD dwFlags
, LPSTRRET strRet
)
439 TRACE ("(%p)->(pidl=%p,0x%08x,%p)\n", this, pidl
, dwFlags
, strRet
);
445 pszPath
= (LPWSTR
)CoTaskMemAlloc((MAX_PATH
+ 1) * sizeof(WCHAR
));
447 return E_OUTOFMEMORY
;
449 ZeroMemory(pszPath
, (MAX_PATH
+ 1) * sizeof(WCHAR
));
451 if (_ILIsMyDocuments (pidl
))
453 if ((GET_SHGDN_RELATION (dwFlags
) == SHGDN_NORMAL
) &&
454 (GET_SHGDN_FOR (dwFlags
) & SHGDN_FORPARSING
))
455 wcscpy(pszPath
, sPathTarget
);
457 HCR_GetClassNameW(CLSID_MyDocuments
, pszPath
, MAX_PATH
);
460 else if (_ILIsPidlSimple (pidl
))
464 if ((clsid
= _ILGetGUIDPointer (pidl
)))
466 if (GET_SHGDN_FOR (dwFlags
) & SHGDN_FORPARSING
)
468 int bWantsForParsing
;
471 * We can only get a filesystem path from a shellfolder if the
472 * value WantsFORPARSING in CLSID\\{...}\\shellfolder exists.
474 * Exception: The MyComputer folder doesn't have this key,
475 * but any other filesystem backed folder it needs it.
477 if (IsEqualIID (*clsid
, CLSID_MyDocuments
))
479 bWantsForParsing
= TRUE
;
483 /* get the "WantsFORPARSING" flag from the registry */
484 static const WCHAR clsidW
[] = L
"CLSID\\";
485 static const WCHAR shellfolderW
[] = L
"shellfolder";
486 static const WCHAR wantsForParsingW
[] = L
"WantsForParsing";
487 WCHAR szRegPath
[100];
490 wcscpy (szRegPath
, clsidW
);
491 SHELL32_GUIDToStringW (*clsid
, &szRegPath
[6]);
492 wcscat (szRegPath
, shellfolderW
);
493 r
= SHGetValueW(HKEY_CLASSES_ROOT
, szRegPath
,
494 wantsForParsingW
, NULL
, NULL
, NULL
);
495 if (r
== ERROR_SUCCESS
)
496 bWantsForParsing
= TRUE
;
498 bWantsForParsing
= FALSE
;
501 if ((GET_SHGDN_RELATION (dwFlags
) == SHGDN_NORMAL
) &&
505 * we need the filesystem path to the destination folder.
506 * Only the folder itself can know it
508 hr
= SHELL32_GetDisplayNameOfChild (this, pidl
, dwFlags
,
515 /* parsing name like ::{...} */
518 SHELL32_GUIDToStringW (*clsid
, &pszPath
[2]);
524 /* user friendly name */
525 HCR_GetClassNameW (*clsid
, pszPath
, MAX_PATH
);
533 /* file system folder or file rooted at the desktop */
534 if ((GET_SHGDN_FOR(dwFlags
) == SHGDN_FORPARSING
) &&
535 (GET_SHGDN_RELATION(dwFlags
) != SHGDN_INFOLDER
))
537 lstrcpynW(pszPath
, sPathTarget
, MAX_PATH
- 1);
538 TRACE("CP %s\n", debugstr_w(pszPath
));
541 if (!_ILIsDesktop(pidl
))
543 PathAddBackslashW(pszPath
);
544 cLen
= wcslen(pszPath
);
545 _ILSimpleGetTextW(pidl
, pszPath
+ cLen
, MAX_PATH
- cLen
);
546 if (!_ILIsFolder(pidl
))
548 SHELL_FS_ProcessDisplayFilename(pszPath
, dwFlags
);
556 /* a complex pidl, let the subfolder do the work */
557 hr
= SHELL32_GetDisplayNameOfChild (this, pidl
, dwFlags
,
564 strRet
->uType
= STRRET_WSTR
;
565 strRet
->pOleStr
= pszPath
;
568 CoTaskMemFree(pszPath
);
570 TRACE ("-- (%p)->(%s,0x%08x)\n", this, debugstr_w(strRet
->pOleStr
), hr
);
574 HRESULT WINAPI
CMyDocsFolder::SetNameOf(HWND hwndOwner
, PCUITEMID_CHILD pidl
, /* simple pidl */
575 LPCOLESTR lpName
, DWORD dwFlags
, PITEMID_CHILD
*pPidlOut
)
577 FIXME ("(%p)->(%p,pidl=%p,%s,%u,%p)\n", this, hwndOwner
, pidl
,
578 debugstr_w (lpName
), dwFlags
, pPidlOut
);
583 HRESULT WINAPI
CMyDocsFolder::GetDefaultSearchGUID(GUID
*pguid
)
585 FIXME ("(%p)\n", this);
589 HRESULT WINAPI
CMyDocsFolder::EnumSearches(IEnumExtraSearch
**ppenum
)
591 FIXME ("(%p)\n", this);
595 HRESULT WINAPI
CMyDocsFolder::GetDefaultColumn(DWORD dwRes
, ULONG
*pSort
, ULONG
*pDisplay
)
597 TRACE ("(%p)\n", this);
607 HRESULT WINAPI
CMyDocsFolder::GetDefaultColumnState(UINT iColumn
, DWORD
*pcsFlags
)
609 TRACE ("(%p)\n", this);
611 if (!pcsFlags
|| iColumn
>= MYDOCUMENTSSHELLVIEWCOLUMNS
)
614 *pcsFlags
= MyDocumentsSFHeader
[iColumn
].pcsFlags
;
619 HRESULT WINAPI
CMyDocsFolder::GetDetailsEx(PCUITEMID_CHILD pidl
, const SHCOLUMNID
*pscid
, VARIANT
*pv
)
621 FIXME ("(%p)\n", this);
626 HRESULT WINAPI
CMyDocsFolder::GetDetailsOf(PCUITEMID_CHILD pidl
, UINT iColumn
, SHELLDETAILS
*psd
)
630 TRACE ("(%p)->(%p %i %p)\n", this, pidl
, iColumn
, psd
);
632 if (!psd
|| iColumn
>= MYDOCUMENTSSHELLVIEWCOLUMNS
)
637 psd
->fmt
= MyDocumentsSFHeader
[iColumn
].fmt
;
638 psd
->cxChar
= MyDocumentsSFHeader
[iColumn
].cxChar
;
639 psd
->str
.uType
= STRRET_CSTR
;
640 LoadStringA (shell32_hInstance
, MyDocumentsSFHeader
[iColumn
].colnameid
,
641 psd
->str
.cStr
, MAX_PATH
);
645 /* the data from the pidl */
646 psd
->str
.uType
= STRRET_CSTR
;
650 hr
= GetDisplayNameOf(pidl
,
651 SHGDN_NORMAL
| SHGDN_INFOLDER
, &psd
->str
);
654 _ILGetFileSize (pidl
, psd
->str
.cStr
, MAX_PATH
);
657 _ILGetFileType (pidl
, psd
->str
.cStr
, MAX_PATH
);
660 _ILGetFileDate (pidl
, psd
->str
.cStr
, MAX_PATH
);
662 case 4: /* attributes */
663 _ILGetFileAttributes (pidl
, psd
->str
.cStr
, MAX_PATH
);
670 HRESULT WINAPI
CMyDocsFolder::MapColumnToSCID (UINT column
, SHCOLUMNID
*pscid
)
672 FIXME ("(%p)\n", this);
676 HRESULT WINAPI
CMyDocsFolder::GetClassID(CLSID
*lpClassId
)
678 static GUID
const CLSID_MyDocuments
=
679 { 0x450d8fba, 0xad25, 0x11d0, {0x98, 0xa8, 0x08, 0x00, 0x36, 0x1b, 0x11, 0x03} };
681 TRACE ("(%p)\n", this);
686 memcpy(lpClassId
, &CLSID_MyDocuments
, sizeof(GUID
));
691 HRESULT WINAPI
CMyDocsFolder::Initialize(LPCITEMIDLIST pidl
)
693 TRACE ("(%p)->(%p)\n", this, pidl
);
698 HRESULT WINAPI
CMyDocsFolder::GetCurFolder(LPITEMIDLIST
*pidl
)
700 TRACE ("(%p)->(%p)\n", this, pidl
);
702 if (!pidl
) return E_POINTER
;
703 *pidl
= ILClone (pidlRoot
);
707 HRESULT WINAPI
CMyDocsFolder::DragEnter(IDataObject
*pDataObject
,
708 DWORD dwKeyState
, POINTL pt
, DWORD
*pdwEffect
)
710 return mFSDropTarget
->DragEnter(pDataObject
, dwKeyState
, pt
, pdwEffect
);
713 HRESULT WINAPI
CMyDocsFolder::DragOver(DWORD dwKeyState
, POINTL pt
,
716 return mFSDropTarget
->DragOver(dwKeyState
, pt
, pdwEffect
);
719 HRESULT WINAPI
CMyDocsFolder::DragLeave()
721 return mFSDropTarget
->DragLeave();
724 HRESULT WINAPI
CMyDocsFolder::Drop(IDataObject
*pDataObject
,
725 DWORD dwKeyState
, POINTL pt
, DWORD
*pdwEffect
)
727 return mFSDropTarget
->Drop(pDataObject
, dwKeyState
, pt
, pdwEffect
);