2 * IContextMenu for items in the shellview
4 * Copyright 1998-2000 Juergen Schmied <juergen.schmied@debitel.net>,
5 * <juergen.schmied@metronet.de>
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
25 #define NONAMELESSUNION
26 #define NONAMELESSSTRUCT
29 #include "wine/debug.h"
34 #include "undocshell.h"
39 #include "shell32_main.h"
40 #include "shellfolder.h"
44 WINE_DEFAULT_DEBUG_CHANNEL(shell
);
48 IContextMenu3 IContextMenu3_iface
;
54 LPITEMIDLIST pidl
; /* root pidl */
55 LPITEMIDLIST
*apidl
; /* array of child pidls */
59 /* background menu data */
63 static inline ContextMenu
*impl_from_IContextMenu3(IContextMenu3
*iface
)
65 return CONTAINING_RECORD(iface
, ContextMenu
, IContextMenu3_iface
);
68 static HRESULT WINAPI
ContextMenu_QueryInterface(IContextMenu3
*iface
, REFIID riid
, LPVOID
*ppvObj
)
70 ContextMenu
*This
= impl_from_IContextMenu3(iface
);
72 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), ppvObj
);
76 if (IsEqualIID(riid
, &IID_IUnknown
) ||
77 IsEqualIID(riid
, &IID_IContextMenu
) ||
78 IsEqualIID(riid
, &IID_IContextMenu2
) ||
79 IsEqualIID(riid
, &IID_IContextMenu3
))
81 *ppvObj
= &This
->IContextMenu3_iface
;
83 else if (IsEqualIID(riid
, &IID_IShellExtInit
)) /*IShellExtInit*/
85 FIXME("-- LPSHELLEXTINIT pointer requested\n");
90 IContextMenu3_AddRef(iface
);
94 TRACE("-- Interface: E_NOINTERFACE\n");
98 static ULONG WINAPI
ContextMenu_AddRef(IContextMenu3
*iface
)
100 ContextMenu
*This
= impl_from_IContextMenu3(iface
);
101 ULONG ref
= InterlockedIncrement(&This
->ref
);
102 TRACE("(%p)->(%u)\n", This
, ref
);
106 static ULONG WINAPI
ContextMenu_Release(IContextMenu3
*iface
)
108 ContextMenu
*This
= impl_from_IContextMenu3(iface
);
109 ULONG ref
= InterlockedDecrement(&This
->ref
);
111 TRACE("(%p)->(%u)\n", This
, ref
);
116 IShellFolder_Release(This
->parent
);
119 _ILFreeaPidl(This
->apidl
, This
->cidl
);
121 HeapFree(GetProcessHeap(), 0, This
);
127 static HRESULT WINAPI
ItemMenu_QueryContextMenu(
128 IContextMenu3
*iface
,
135 ContextMenu
*This
= impl_from_IContextMenu3(iface
);
138 TRACE("(%p)->(%p %d 0x%x 0x%x 0x%x )\n", This
, hmenu
, indexMenu
, idCmdFirst
, idCmdLast
, uFlags
);
140 if(!(CMF_DEFAULTONLY
& uFlags
) && This
->cidl
> 0)
142 HMENU hmenures
= LoadMenuW(shell32_hInstance
, MAKEINTRESOURCEW(MENU_SHV_FILE
));
144 if(uFlags
& CMF_EXPLORE
)
145 RemoveMenu(hmenures
, FCIDM_SHVIEW_OPEN
, MF_BYCOMMAND
);
147 uIDMax
= Shell_MergeMenus(hmenu
, GetSubMenu(hmenures
, 0), indexMenu
, idCmdFirst
, idCmdLast
, MM_SUBMENUSHAVEIDS
);
149 DestroyMenu(hmenures
);
155 mi
.cbSize
= sizeof(mi
);
156 mi
.fMask
= MIIM_ID
| MIIM_STRING
| MIIM_FTYPE
;
159 GetMenuItemInfoW(hmenu
, FCIDM_SHVIEW_EXPLORE
, MF_BYCOMMAND
, &mi
);
160 RemoveMenu(hmenu
, FCIDM_SHVIEW_EXPLORE
+ idCmdFirst
, MF_BYCOMMAND
);
162 mi
.cbSize
= sizeof(mi
);
163 mi
.fMask
= MIIM_ID
| MIIM_TYPE
| MIIM_STATE
| MIIM_STRING
;
165 mi
.fState
= MFS_ENABLED
;
166 mi
.wID
= FCIDM_SHVIEW_EXPLORE
;
167 mi
.fType
= MFT_STRING
;
168 InsertMenuItemW(hmenu
, (uFlags
& CMF_EXPLORE
) ? 1 : 2, MF_BYPOSITION
, &mi
);
171 SetMenuDefaultItem(hmenu
, 0, MF_BYPOSITION
);
173 if(uFlags
& ~CMF_CANRENAME
)
174 RemoveMenu(hmenu
, FCIDM_SHVIEW_RENAME
, MF_BYCOMMAND
);
177 UINT enable
= MF_BYCOMMAND
;
179 /* can't rename more than one item at a time*/
180 if (!This
->apidl
|| This
->cidl
> 1)
181 enable
|= MFS_DISABLED
;
184 DWORD attr
= SFGAO_CANRENAME
;
186 IShellFolder_GetAttributesOf(This
->parent
, 1, (LPCITEMIDLIST
*)This
->apidl
, &attr
);
187 enable
|= (attr
& SFGAO_CANRENAME
) ? MFS_ENABLED
: MFS_DISABLED
;
190 EnableMenuItem(hmenu
, FCIDM_SHVIEW_RENAME
, enable
);
193 return MAKE_HRESULT(SEVERITY_SUCCESS
, 0, uIDMax
-idCmdFirst
);
195 return MAKE_HRESULT(SEVERITY_SUCCESS
, 0, 0);
198 /**************************************************************************
204 static void DoOpenExplore(ContextMenu
*This
, HWND hwnd
, LPCSTR verb
)
206 UINT i
, bFolderFound
= FALSE
;
208 SHELLEXECUTEINFOA sei
;
210 /* Find the first item in the list that is not a value. These commands
211 should never be invoked if there isn't at least one folder item in the list.*/
213 for(i
= 0; i
<This
->cidl
; i
++)
215 if(!_ILIsValue(This
->apidl
[i
]))
222 if (!bFolderFound
) return;
224 pidlFQ
= ILCombine(This
->pidl
, This
->apidl
[i
]);
226 ZeroMemory(&sei
, sizeof(sei
));
227 sei
.cbSize
= sizeof(sei
);
228 sei
.fMask
= SEE_MASK_IDLIST
| SEE_MASK_CLASSNAME
;
229 sei
.lpIDList
= pidlFQ
;
230 sei
.lpClass
= "Folder";
232 sei
.nShow
= SW_SHOWNORMAL
;
234 ShellExecuteExA(&sei
);
238 /**************************************************************************
241 * deletes the currently selected items
243 static void DoDelete(ContextMenu
*This
)
247 IShellFolder_QueryInterface(This
->parent
, &IID_ISFHelper
, (void**)&helper
);
250 ISFHelper_DeleteItems(helper
, This
->cidl
, (LPCITEMIDLIST
*)This
->apidl
);
251 ISFHelper_Release(helper
);
255 /**************************************************************************
258 * copies the currently selected items into the clipboard
260 static void DoCopyOrCut(ContextMenu
*This
, HWND hwnd
, BOOL cut
)
262 IDataObject
*dataobject
;
264 TRACE("(%p)->(wnd=%p, cut=%d)\n", This
, hwnd
, cut
);
266 if (SUCCEEDED(IShellFolder_GetUIObjectOf(This
->parent
, hwnd
, This
->cidl
, (LPCITEMIDLIST
*)This
->apidl
, &IID_IDataObject
, 0, (void**)&dataobject
)))
268 OleSetClipboard(dataobject
);
269 IDataObject_Release(dataobject
);
273 /**************************************************************************
274 * Properties_AddPropSheetCallback
276 * Used by DoOpenProperties through SHCreatePropSheetExtArrayEx to add
277 * propertysheet pages from shell extensions.
279 static BOOL CALLBACK
Properties_AddPropSheetCallback(HPROPSHEETPAGE hpage
, LPARAM lparam
)
281 LPPROPSHEETHEADERW psh
= (LPPROPSHEETHEADERW
) lparam
;
282 psh
->u3
.phpage
[psh
->nPages
++] = hpage
;
287 static void DoOpenProperties(ContextMenu
*This
, HWND hwnd
)
289 static const UINT MAX_PROP_PAGES
= 99;
290 static const WCHAR wszFolder
[] = {'F','o','l','d','e','r', 0};
291 static const WCHAR wszFiletypeAll
[] = {'*',0};
292 LPSHELLFOLDER lpDesktopSF
;
295 WCHAR wszFiletype
[MAX_PATH
];
296 WCHAR wszFilename
[MAX_PATH
];
297 PROPSHEETHEADERW psh
;
298 HPROPSHEETPAGE hpages
[MAX_PROP_PAGES
];
302 TRACE("(%p)->(wnd=%p)\n", This
, hwnd
);
304 ZeroMemory(&psh
, sizeof(PROPSHEETHEADERW
));
305 psh
.dwSize
= sizeof (PROPSHEETHEADERW
);
306 psh
.hwndParent
= hwnd
;
307 psh
.dwFlags
= PSH_PROPTITLE
;
309 psh
.u3
.phpage
= hpages
;
310 psh
.u2
.nStartPage
= 0;
312 _ILSimpleGetTextW(This
->apidl
[0], (LPVOID
)wszFilename
, MAX_PATH
);
313 psh
.pszCaption
= (LPCWSTR
)wszFilename
;
315 /* Find out where to look for the shell extensions */
316 if (_ILIsValue(This
->apidl
[0]))
320 if (_ILGetExtension(This
->apidl
[0], sTemp
, 64))
322 HCR_MapTypeToValueA(sTemp
, sTemp
, 64, TRUE
);
323 MultiByteToWideChar(CP_ACP
, 0, sTemp
, -1, wszFiletype
, MAX_PATH
);
330 else if (_ILIsFolder(This
->apidl
[0]))
332 lstrcpynW(wszFiletype
, wszFolder
, 64);
334 else if (_ILIsSpecialFolder(This
->apidl
[0]))
337 static const WCHAR wszclsid
[] = {'C','L','S','I','D','\\', 0};
338 folderGUID
= _ILGetGUIDPointer(This
->apidl
[0]);
339 lstrcpyW(wszFiletype
, wszclsid
);
340 StringFromGUID2(folderGUID
, &wszFiletype
[6], MAX_PATH
- 6);
344 FIXME("Requested properties for unknown type.\n");
348 /* Get a suitable DataObject for accessing the files */
349 SHGetDesktopFolder(&lpDesktopSF
);
350 if (_ILIsPidlSimple(This
->pidl
))
352 ret
= IShellFolder_GetUIObjectOf(lpDesktopSF
, hwnd
, This
->cidl
, (LPCITEMIDLIST
*)This
->apidl
,
353 &IID_IDataObject
, NULL
, (LPVOID
*)&lpDo
);
354 IShellFolder_Release(lpDesktopSF
);
358 IShellFolder_BindToObject(lpDesktopSF
, This
->pidl
, NULL
, &IID_IShellFolder
, (LPVOID
*) &lpSF
);
359 ret
= IShellFolder_GetUIObjectOf(lpSF
, hwnd
, This
->cidl
, (LPCITEMIDLIST
*)This
->apidl
,
360 &IID_IDataObject
, NULL
, (LPVOID
*)&lpDo
);
361 IShellFolder_Release(lpSF
);
362 IShellFolder_Release(lpDesktopSF
);
367 hpsxa
= SHCreatePropSheetExtArrayEx(HKEY_CLASSES_ROOT
, wszFiletype
, MAX_PROP_PAGES
- psh
.nPages
, lpDo
);
370 SHAddFromPropSheetExtArray(hpsxa
, Properties_AddPropSheetCallback
, (LPARAM
)&psh
);
371 SHDestroyPropSheetExtArray(hpsxa
);
373 hpsxa
= SHCreatePropSheetExtArrayEx(HKEY_CLASSES_ROOT
, wszFiletypeAll
, MAX_PROP_PAGES
- psh
.nPages
, lpDo
);
376 SHAddFromPropSheetExtArray(hpsxa
, Properties_AddPropSheetCallback
, (LPARAM
)&psh
);
377 SHDestroyPropSheetExtArray(hpsxa
);
379 IDataObject_Release(lpDo
);
383 PropertySheetW(&psh
);
385 FIXME("No property pages found.\n");
388 static HRESULT WINAPI
ItemMenu_InvokeCommand(
389 IContextMenu3
*iface
,
390 LPCMINVOKECOMMANDINFO lpcmi
)
392 ContextMenu
*This
= impl_from_IContextMenu3(iface
);
394 if (lpcmi
->cbSize
!= sizeof(CMINVOKECOMMANDINFO
))
395 FIXME("Is an EX structure\n");
397 TRACE("(%p)->(invcom=%p verb=%p wnd=%p)\n",This
,lpcmi
,lpcmi
->lpVerb
, lpcmi
->hwnd
);
399 if( HIWORD(lpcmi
->lpVerb
)==0 && LOWORD(lpcmi
->lpVerb
) > FCIDM_SHVIEWLAST
)
401 TRACE("Invalid Verb %x\n",LOWORD(lpcmi
->lpVerb
));
405 if (HIWORD(lpcmi
->lpVerb
) == 0)
407 switch(LOWORD(lpcmi
->lpVerb
))
409 case FCIDM_SHVIEW_EXPLORE
:
410 TRACE("Verb FCIDM_SHVIEW_EXPLORE\n");
411 DoOpenExplore(This
, lpcmi
->hwnd
, "explore");
413 case FCIDM_SHVIEW_OPEN
:
414 TRACE("Verb FCIDM_SHVIEW_OPEN\n");
415 DoOpenExplore(This
, lpcmi
->hwnd
, "open");
417 case FCIDM_SHVIEW_RENAME
:
419 IShellBrowser
*browser
;
421 /* get the active IShellView */
422 browser
= (IShellBrowser
*)SendMessageA(lpcmi
->hwnd
, CWM_GETISHELLBROWSER
, 0, 0);
427 if(SUCCEEDED(IShellBrowser_QueryActiveShellView(browser
, &view
)))
429 TRACE("(shellview=%p)\n", view
);
430 IShellView_SelectItem(view
, This
->apidl
[0],
431 SVSI_DESELECTOTHERS
|SVSI_EDIT
|SVSI_ENSUREVISIBLE
|SVSI_FOCUSED
|SVSI_SELECT
);
432 IShellView_Release(view
);
437 case FCIDM_SHVIEW_DELETE
:
438 TRACE("Verb FCIDM_SHVIEW_DELETE\n");
441 case FCIDM_SHVIEW_COPY
:
442 TRACE("Verb FCIDM_SHVIEW_COPY\n");
443 DoCopyOrCut(This
, lpcmi
->hwnd
, FALSE
);
445 case FCIDM_SHVIEW_CUT
:
446 TRACE("Verb FCIDM_SHVIEW_CUT\n");
447 DoCopyOrCut(This
, lpcmi
->hwnd
, TRUE
);
449 case FCIDM_SHVIEW_PROPERTIES
:
450 TRACE("Verb FCIDM_SHVIEW_PROPERTIES\n");
451 DoOpenProperties(This
, lpcmi
->hwnd
);
454 FIXME("Unhandled Verb %xl\n",LOWORD(lpcmi
->lpVerb
));
460 TRACE("Verb is %s\n",debugstr_a(lpcmi
->lpVerb
));
461 if (strcmp(lpcmi
->lpVerb
,"delete")==0)
463 else if (strcmp(lpcmi
->lpVerb
,"properties")==0)
464 DoOpenProperties(This
, lpcmi
->hwnd
);
466 FIXME("Unhandled string verb %s\n",debugstr_a(lpcmi
->lpVerb
));
473 static HRESULT WINAPI
ItemMenu_GetCommandString(
474 IContextMenu3
*iface
,
481 ContextMenu
*This
= impl_from_IContextMenu3(iface
);
482 HRESULT hr
= E_INVALIDARG
;
484 TRACE("(%p)->(%lx flags=%x %p name=%p len=%x)\n", This
, idCommand
, uFlags
, lpReserved
, lpszName
, uMaxNameLen
);
496 case FCIDM_SHVIEW_OPEN
:
497 strcpy(lpszName
, "open");
500 case FCIDM_SHVIEW_EXPLORE
:
501 strcpy(lpszName
, "explore");
504 case FCIDM_SHVIEW_CUT
:
505 strcpy(lpszName
, "cut");
508 case FCIDM_SHVIEW_COPY
:
509 strcpy(lpszName
, "copy");
512 case FCIDM_SHVIEW_CREATELINK
:
513 strcpy(lpszName
, "link");
516 case FCIDM_SHVIEW_DELETE
:
517 strcpy(lpszName
, "delete");
520 case FCIDM_SHVIEW_PROPERTIES
:
521 strcpy(lpszName
, "properties");
524 case FCIDM_SHVIEW_RENAME
:
525 strcpy(lpszName
, "rename");
531 /* NT 4.0 with IE 3.0x or no IE will always call This with GCS_VERBW. In This
532 case, you need to do the lstrcpyW to the pointer passed.*/
536 case FCIDM_SHVIEW_OPEN
:
537 MultiByteToWideChar(CP_ACP
, 0, "open", -1, (LPWSTR
)lpszName
, uMaxNameLen
);
540 case FCIDM_SHVIEW_EXPLORE
:
541 MultiByteToWideChar(CP_ACP
, 0, "explore", -1, (LPWSTR
)lpszName
, uMaxNameLen
);
544 case FCIDM_SHVIEW_CUT
:
545 MultiByteToWideChar(CP_ACP
, 0, "cut", -1, (LPWSTR
)lpszName
, uMaxNameLen
);
548 case FCIDM_SHVIEW_COPY
:
549 MultiByteToWideChar(CP_ACP
, 0, "copy", -1, (LPWSTR
)lpszName
, uMaxNameLen
);
552 case FCIDM_SHVIEW_CREATELINK
:
553 MultiByteToWideChar(CP_ACP
, 0, "link", -1, (LPWSTR
)lpszName
, uMaxNameLen
);
556 case FCIDM_SHVIEW_DELETE
:
557 MultiByteToWideChar(CP_ACP
, 0, "delete", -1, (LPWSTR
)lpszName
, uMaxNameLen
);
560 case FCIDM_SHVIEW_PROPERTIES
:
561 MultiByteToWideChar(CP_ACP
, 0, "properties", -1, (LPWSTR
)lpszName
, uMaxNameLen
);
564 case FCIDM_SHVIEW_RENAME
:
565 MultiByteToWideChar( CP_ACP
, 0, "rename", -1, (LPWSTR
)lpszName
, uMaxNameLen
);
576 TRACE("-- (%p)->(name=%s)\n", This
, lpszName
);
580 /**************************************************************************
582 * should be only in IContextMenu2 and IContextMenu3
583 * is nevertheless called from word95
585 static HRESULT WINAPI
ContextMenu_HandleMenuMsg(IContextMenu3
*iface
, UINT msg
,
586 WPARAM wParam
, LPARAM lParam
)
588 ContextMenu
*This
= impl_from_IContextMenu3(iface
);
589 FIXME("(%p)->(0x%x 0x%lx 0x%lx): stub\n", This
, msg
, wParam
, lParam
);
593 static HRESULT WINAPI
ContextMenu_HandleMenuMsg2(IContextMenu3
*iface
, UINT msg
,
594 WPARAM wParam
, LPARAM lParam
, LRESULT
*result
)
596 ContextMenu
*This
= impl_from_IContextMenu3(iface
);
597 FIXME("(%p)->(0x%x 0x%lx 0x%lx %p): stub\n", This
, msg
, wParam
, lParam
, result
);
601 static const IContextMenu3Vtbl ItemContextMenuVtbl
=
603 ContextMenu_QueryInterface
,
606 ItemMenu_QueryContextMenu
,
607 ItemMenu_InvokeCommand
,
608 ItemMenu_GetCommandString
,
609 ContextMenu_HandleMenuMsg
,
610 ContextMenu_HandleMenuMsg2
613 HRESULT
ItemMenu_Constructor(IShellFolder
*parent
, LPCITEMIDLIST pidl
, const LPCITEMIDLIST
*apidl
, UINT cidl
,
614 REFIID riid
, void **pObj
)
620 This
= HeapAlloc(GetProcessHeap(), 0, sizeof(*This
));
621 if (!This
) return E_OUTOFMEMORY
;
623 This
->IContextMenu3_iface
.lpVtbl
= &ItemContextMenuVtbl
;
625 This
->parent
= parent
;
626 if (parent
) IShellFolder_AddRef(parent
);
628 This
->pidl
= ILClone(pidl
);
629 This
->apidl
= _ILCopyaPidl(apidl
, cidl
);
631 This
->allvalues
= TRUE
;
633 This
->desktop
= FALSE
;
635 for (i
= 0; i
< cidl
; i
++)
636 This
->allvalues
&= (_ILIsValue(apidl
[i
]) ? 1 : 0);
638 hr
= IContextMenu3_QueryInterface(&This
->IContextMenu3_iface
, riid
, pObj
);
639 IContextMenu3_Release(&This
->IContextMenu3_iface
);
644 /* Background menu implementation */
645 static HRESULT WINAPI
BackgroundMenu_QueryContextMenu(
646 IContextMenu3
*iface
,
653 ContextMenu
*This
= impl_from_IContextMenu3(iface
);
658 TRACE("(%p)->(hmenu=%p indexmenu=%x cmdfirst=%x cmdlast=%x flags=%x )\n",
659 This
, hMenu
, indexMenu
, idCmdFirst
, idCmdLast
, uFlags
);
661 hMyMenu
= LoadMenuA(shell32_hInstance
, "MENU_002");
662 if (uFlags
& CMF_DEFAULTONLY
)
664 HMENU ourMenu
= GetSubMenu(hMyMenu
,0);
665 UINT oldDef
= GetMenuDefaultItem(hMenu
,TRUE
,GMDI_USEDISABLED
);
666 UINT newDef
= GetMenuDefaultItem(ourMenu
,TRUE
,GMDI_USEDISABLED
);
667 if (newDef
!= oldDef
)
668 SetMenuDefaultItem(hMenu
,newDef
,TRUE
);
669 if (newDef
!=0xFFFFFFFF)
670 hr
= MAKE_HRESULT(SEVERITY_SUCCESS
, FACILITY_NULL
, newDef
+1);
672 hr
= MAKE_HRESULT(SEVERITY_SUCCESS
, FACILITY_NULL
, 0);
676 idMax
= Shell_MergeMenus (hMenu
, GetSubMenu(hMyMenu
,0), indexMenu
,
677 idCmdFirst
, idCmdLast
, MM_SUBMENUSHAVEIDS
);
678 hr
= MAKE_HRESULT(SEVERITY_SUCCESS
, FACILITY_NULL
, idMax
-idCmdFirst
);
680 DestroyMenu(hMyMenu
);
682 TRACE("(%p)->returning 0x%x\n",This
,hr
);
686 static void DoNewFolder(ContextMenu
*This
, IShellView
*view
)
690 IShellFolder_QueryInterface(This
->parent
, &IID_ISFHelper
, (void**)&helper
);
693 WCHAR nameW
[MAX_PATH
];
696 ISFHelper_GetUniqueName(helper
, nameW
, MAX_PATH
);
697 ISFHelper_AddFolder(helper
, 0, nameW
, &pidl
);
701 /* if we are in a shellview do labeledit */
702 IShellView_SelectItem(view
,
703 pidl
,(SVSI_DESELECTOTHERS
| SVSI_EDIT
| SVSI_ENSUREVISIBLE
704 |SVSI_FOCUSED
|SVSI_SELECT
));
708 ISFHelper_Release(helper
);
712 static BOOL
DoPaste(ContextMenu
*This
)
714 BOOL bSuccess
= FALSE
;
719 if(SUCCEEDED(OleGetClipboard(&pda
)))
724 TRACE("pda=%p\n", pda
);
726 /* Set the FORMATETC structure*/
727 InitFormatEtc(formatetc
, RegisterClipboardFormatW(CFSTR_SHELLIDLISTW
), TYMED_HGLOBAL
);
729 /* Get the pidls from IDataObject */
730 if(SUCCEEDED(IDataObject_GetData(pda
,&formatetc
,&medium
)))
732 LPITEMIDLIST
* apidl
;
734 IShellFolder
*psfFrom
= NULL
, *psfDesktop
;
736 LPIDA lpcida
= GlobalLock(medium
.u
.hGlobal
);
737 TRACE("cida=%p\n", lpcida
);
739 apidl
= _ILCopyCidaToaPidl(&pidl
, lpcida
);
741 /* bind to the source shellfolder */
742 SHGetDesktopFolder(&psfDesktop
);
745 IShellFolder_BindToObject(psfDesktop
, pidl
, NULL
, &IID_IShellFolder
, (LPVOID
*)&psfFrom
);
746 IShellFolder_Release(psfDesktop
);
751 /* get source and destination shellfolder */
752 ISFHelper
*psfhlpdst
, *psfhlpsrc
;
753 IShellFolder_QueryInterface(This
->parent
, &IID_ISFHelper
, (void**)&psfhlpdst
);
754 IShellFolder_QueryInterface(psfFrom
, &IID_ISFHelper
, (void**)&psfhlpsrc
);
756 /* do the copy/move */
757 if (psfhlpdst
&& psfhlpsrc
)
759 ISFHelper_CopyItems(psfhlpdst
, psfFrom
, lpcida
->cidl
, (LPCITEMIDLIST
*)apidl
);
761 ISFHelper_DeleteItems(psfhlpsrc, lpcida->cidl, apidl);
764 if(psfhlpdst
) ISFHelper_Release(psfhlpdst
);
765 if(psfhlpsrc
) ISFHelper_Release(psfhlpsrc
);
766 IShellFolder_Release(psfFrom
);
769 _ILFreeaPidl(apidl
, lpcida
->cidl
);
772 /* release the medium*/
773 ReleaseStgMedium(&medium
);
775 IDataObject_Release(pda
);
781 hMem
= GetClipboardData(CF_HDROP
);
785 char * pDropFiles
= GlobalLock(hMem
);
788 int len
, offset
= sizeof(DROPFILESTRUCT
);
790 while( pDropFiles
[offset
] != 0)
792 len
= strlen(pDropFiles
+ offset
);
793 TRACE("%s\n", pDropFiles
+ offset
);
804 static HRESULT WINAPI
BackgroundMenu_InvokeCommand(
805 IContextMenu3
*iface
,
806 LPCMINVOKECOMMANDINFO lpcmi
)
808 ContextMenu
*This
= impl_from_IContextMenu3(iface
);
809 IShellBrowser
*browser
;
810 IShellView
*view
= NULL
;
813 TRACE("(%p)->(invcom=%p verb=%p wnd=%p)\n", This
, lpcmi
, lpcmi
->lpVerb
, lpcmi
->hwnd
);
815 /* get the active IShellView */
816 if ((browser
= (IShellBrowser
*)SendMessageA(lpcmi
->hwnd
, CWM_GETISHELLBROWSER
, 0, 0)))
818 if (SUCCEEDED(IShellBrowser_QueryActiveShellView(browser
, &view
)))
819 IShellView_GetWindow(view
, &hWnd
);
822 if(HIWORD(lpcmi
->lpVerb
))
824 TRACE("%s\n", debugstr_a(lpcmi
->lpVerb
));
826 if (!strcmp(lpcmi
->lpVerb
, CMDSTR_NEWFOLDERA
))
828 DoNewFolder(This
, view
);
830 else if (!strcmp(lpcmi
->lpVerb
, CMDSTR_VIEWLISTA
))
832 if (hWnd
) SendMessageA(hWnd
, WM_COMMAND
, MAKEWPARAM(FCIDM_SHVIEW_LISTVIEW
, 0), 0);
834 else if (!strcmp(lpcmi
->lpVerb
, CMDSTR_VIEWDETAILSA
))
836 if (hWnd
) SendMessageA(hWnd
, WM_COMMAND
, MAKEWPARAM(FCIDM_SHVIEW_REPORTVIEW
, 0), 0);
840 FIXME("please report: unknown verb %s\n", debugstr_a(lpcmi
->lpVerb
));
845 switch (LOWORD(lpcmi
->lpVerb
))
847 case FCIDM_SHVIEW_REFRESH
:
848 if (view
) IShellView_Refresh(view
);
851 case FCIDM_SHVIEW_NEWFOLDER
:
852 DoNewFolder(This
, view
);
855 case FCIDM_SHVIEW_INSERT
:
859 case FCIDM_SHVIEW_PROPERTIES
:
861 ShellExecuteA(lpcmi
->hwnd
, "open", "rundll32.exe shell32.dll,Control_RunDLL desk.cpl", NULL
, NULL
, SW_SHOWNORMAL
);
863 FIXME("launch item properties dialog\n");
868 /* if it's an id just pass it to the parent shv */
869 if (hWnd
) SendMessageA(hWnd
, WM_COMMAND
, MAKEWPARAM(LOWORD(lpcmi
->lpVerb
), 0), 0);
875 IShellView_Release(view
);
880 static HRESULT WINAPI
BackgroundMenu_GetCommandString(
881 IContextMenu3
*iface
,
888 ContextMenu
*This
= impl_from_IContextMenu3(iface
);
890 TRACE("(%p)->(idcom=%lx flags=%x %p name=%p len=%x)\n",This
, idCommand
, uFlags
, lpReserved
, lpszName
, uMaxNameLen
);
892 /* test the existence of the menu items, the file dialog enables
893 the buttons according to this */
894 if (uFlags
== GCS_VALIDATEA
)
896 if(HIWORD(idCommand
))
898 if (!strcmp((LPSTR
)idCommand
, CMDSTR_VIEWLISTA
) ||
899 !strcmp((LPSTR
)idCommand
, CMDSTR_VIEWDETAILSA
) ||
900 !strcmp((LPSTR
)idCommand
, CMDSTR_NEWFOLDERA
))
907 FIXME("unknown command string\n");
911 static const IContextMenu3Vtbl BackgroundContextMenuVtbl
=
913 ContextMenu_QueryInterface
,
916 BackgroundMenu_QueryContextMenu
,
917 BackgroundMenu_InvokeCommand
,
918 BackgroundMenu_GetCommandString
,
919 ContextMenu_HandleMenuMsg
,
920 ContextMenu_HandleMenuMsg2
923 HRESULT
BackgroundMenu_Constructor(IShellFolder
*parent
, BOOL desktop
, REFIID riid
, void **pObj
)
928 This
= HeapAlloc(GetProcessHeap(), 0, sizeof(*This
));
929 if (!This
) return E_OUTOFMEMORY
;
931 This
->IContextMenu3_iface
.lpVtbl
= &BackgroundContextMenuVtbl
;
933 This
->parent
= parent
;
938 This
->allvalues
= FALSE
;
940 This
->desktop
= desktop
;
941 if (parent
) IShellFolder_AddRef(parent
);
943 hr
= IContextMenu3_QueryInterface(&This
->IContextMenu3_iface
, riid
, pObj
);
944 IContextMenu3_Release(&This
->IContextMenu3_iface
);