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 IContextMenu2 IContextMenu2_iface
;
55 LPITEMIDLIST pidl
; /* root pidl */
56 LPITEMIDLIST
*apidl
; /* array of child pidls */
60 /* background menu data */
64 static inline ContextMenu
*impl_from_IContextMenu2(IContextMenu2
*iface
)
66 return CONTAINING_RECORD(iface
, ContextMenu
, IContextMenu2_iface
);
69 static BOOL
ItemMenu_CanRenameItems(ContextMenu
*This
)
73 TRACE("(%p)\n", This
);
75 /* can't rename more than one item at a time*/
76 if (!This
->apidl
|| This
->cidl
> 1) return FALSE
;
78 attr
= SFGAO_CANRENAME
;
79 IShellFolder_GetAttributesOf(This
->parent
, 1, (LPCITEMIDLIST
*)This
->apidl
, &attr
);
80 return attr
& SFGAO_CANRENAME
;
83 static HRESULT WINAPI
ItemMenu_QueryInterface(IContextMenu2
*iface
, REFIID riid
, LPVOID
*ppvObj
)
85 ContextMenu
*This
= impl_from_IContextMenu2(iface
);
87 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), ppvObj
);
91 if (IsEqualIID(riid
, &IID_IUnknown
) ||
92 IsEqualIID(riid
, &IID_IContextMenu
) ||
93 IsEqualIID(riid
, &IID_IContextMenu2
))
97 else if (IsEqualIID(riid
, &IID_IShellExtInit
)) /*IShellExtInit*/
99 FIXME("-- LPSHELLEXTINIT pointer requested\n");
104 IContextMenu2_AddRef(iface
);
108 TRACE("-- Interface: E_NOINTERFACE\n");
109 return E_NOINTERFACE
;
112 static ULONG WINAPI
ItemMenu_AddRef(IContextMenu2
*iface
)
114 ContextMenu
*This
= impl_from_IContextMenu2(iface
);
115 ULONG ref
= InterlockedIncrement(&This
->ref
);
116 TRACE("(%p)->(%u)\n", This
, ref
);
120 static ULONG WINAPI
ItemMenu_Release(IContextMenu2
*iface
)
122 ContextMenu
*This
= impl_from_IContextMenu2(iface
);
123 ULONG ref
= InterlockedDecrement(&This
->ref
);
125 TRACE("(%p)->(%u)\n", This
, ref
);
130 IShellFolder_Release(This
->parent
);
133 _ILFreeaPidl(This
->apidl
, This
->cidl
);
135 HeapFree(GetProcessHeap(), 0, This
);
141 static HRESULT WINAPI
ItemMenu_QueryContextMenu(
142 IContextMenu2
*iface
,
149 ContextMenu
*This
= impl_from_IContextMenu2(iface
);
152 TRACE("(%p)->(%p %d 0x%x 0x%x 0x%x )\n", This
, hmenu
, indexMenu
, idCmdFirst
, idCmdLast
, uFlags
);
154 This
->verb_offset
= idCmdFirst
;
156 if(!(CMF_DEFAULTONLY
& uFlags
) && This
->cidl
> 0)
158 HMENU hmenures
= LoadMenuW(shell32_hInstance
, MAKEINTRESOURCEW(MENU_SHV_FILE
));
160 if(uFlags
& CMF_EXPLORE
)
161 RemoveMenu(hmenures
, FCIDM_SHVIEW_OPEN
, MF_BYCOMMAND
);
163 uIDMax
= Shell_MergeMenus(hmenu
, GetSubMenu(hmenures
, 0), indexMenu
, idCmdFirst
, idCmdLast
, MM_SUBMENUSHAVEIDS
);
165 DestroyMenu(hmenures
);
171 mi
.cbSize
= sizeof(mi
);
172 mi
.fMask
= MIIM_ID
| MIIM_STRING
| MIIM_FTYPE
;
175 GetMenuItemInfoW(hmenu
, FCIDM_SHVIEW_EXPLORE
, MF_BYCOMMAND
, &mi
);
176 RemoveMenu(hmenu
, FCIDM_SHVIEW_EXPLORE
, MF_BYCOMMAND
);
178 mi
.cbSize
= sizeof(mi
);
179 mi
.fMask
= MIIM_ID
| MIIM_TYPE
| MIIM_STATE
;
181 mi
.fState
= MFS_ENABLED
;
182 mi
.wID
= FCIDM_SHVIEW_EXPLORE
;
183 mi
.fType
= MFT_STRING
;
184 InsertMenuItemW(hmenu
, (uFlags
& CMF_EXPLORE
) ? 1 : 2, MF_BYPOSITION
, &mi
);
187 SetMenuDefaultItem(hmenu
, 0, MF_BYPOSITION
);
189 if(uFlags
& ~CMF_CANRENAME
)
190 RemoveMenu(hmenu
, FCIDM_SHVIEW_RENAME
, MF_BYCOMMAND
);
192 EnableMenuItem(hmenu
, FCIDM_SHVIEW_RENAME
, MF_BYCOMMAND
| ItemMenu_CanRenameItems(This
) ? MFS_ENABLED
: MFS_DISABLED
);
194 return MAKE_HRESULT(SEVERITY_SUCCESS
, 0, uIDMax
-idCmdFirst
);
196 return MAKE_HRESULT(SEVERITY_SUCCESS
, 0, 0);
199 /**************************************************************************
205 static void DoOpenExplore(ContextMenu
*This
, HWND hwnd
, LPCSTR verb
)
207 UINT i
, bFolderFound
= FALSE
;
209 SHELLEXECUTEINFOA sei
;
211 /* Find the first item in the list that is not a value. These commands
212 should never be invoked if there isn't at least one folder item in the list.*/
214 for(i
= 0; i
<This
->cidl
; i
++)
216 if(!_ILIsValue(This
->apidl
[i
]))
223 if (!bFolderFound
) return;
225 pidlFQ
= ILCombine(This
->pidl
, This
->apidl
[i
]);
227 ZeroMemory(&sei
, sizeof(sei
));
228 sei
.cbSize
= sizeof(sei
);
229 sei
.fMask
= SEE_MASK_IDLIST
| SEE_MASK_CLASSNAME
;
230 sei
.lpIDList
= pidlFQ
;
231 sei
.lpClass
= "Folder";
233 sei
.nShow
= SW_SHOWNORMAL
;
235 ShellExecuteExA(&sei
);
239 /**************************************************************************
242 * deletes the currently selected items
244 static void DoDelete(ContextMenu
*This
)
248 IShellFolder_QueryInterface(This
->parent
, &IID_ISFHelper
, (void**)&helper
);
251 ISFHelper_DeleteItems(helper
, This
->cidl
, (LPCITEMIDLIST
*)This
->apidl
);
252 ISFHelper_Release(helper
);
256 /**************************************************************************
259 * copies the currently selected items into the clipboard
261 static BOOL
DoCopyOrCut(ContextMenu
*This
, HWND hwnd
, BOOL cut
)
263 IDataObject
*dataobject
;
264 IShellBrowser
*browser
;
267 TRACE("(%p)->(wnd=%p, cut=%d)\n", This
, hwnd
, cut
);
269 /* get the active IShellView */
270 if ((browser
= (IShellBrowser
*)SendMessageA(hwnd
, CWM_GETISHELLBROWSER
, 0, 0)))
272 if (SUCCEEDED(IShellBrowser_QueryActiveShellView(browser
, &view
)))
274 if (SUCCEEDED(IShellView_GetItemObject(view
, SVGIO_SELECTION
, &IID_IDataObject
, (void**)&dataobject
)))
276 OleSetClipboard(dataobject
);
277 IDataObject_Release(dataobject
);
279 IShellView_Release(view
);
286 /**************************************************************************
287 * Properties_AddPropSheetCallback
289 * Used by DoOpenProperties through SHCreatePropSheetExtArrayEx to add
290 * propertysheet pages from shell extensions.
292 static BOOL CALLBACK
Properties_AddPropSheetCallback(HPROPSHEETPAGE hpage
, LPARAM lparam
)
294 LPPROPSHEETHEADERW psh
= (LPPROPSHEETHEADERW
) lparam
;
295 psh
->u3
.phpage
[psh
->nPages
++] = hpage
;
300 static void DoOpenProperties(ContextMenu
*This
, HWND hwnd
)
302 static const UINT MAX_PROP_PAGES
= 99;
303 static const WCHAR wszFolder
[] = {'F','o','l','d','e','r', 0};
304 static const WCHAR wszFiletypeAll
[] = {'*',0};
305 LPSHELLFOLDER lpDesktopSF
;
308 WCHAR wszFiletype
[MAX_PATH
];
309 WCHAR wszFilename
[MAX_PATH
];
310 PROPSHEETHEADERW psh
;
311 HPROPSHEETPAGE hpages
[MAX_PROP_PAGES
];
315 TRACE("(%p)->(wnd=%p)\n", This
, hwnd
);
317 ZeroMemory(&psh
, sizeof(PROPSHEETHEADERW
));
318 psh
.dwSize
= sizeof (PROPSHEETHEADERW
);
319 psh
.hwndParent
= hwnd
;
320 psh
.dwFlags
= PSH_PROPTITLE
;
322 psh
.u3
.phpage
= hpages
;
323 psh
.u2
.nStartPage
= 0;
325 _ILSimpleGetTextW(This
->apidl
[0], (LPVOID
)wszFilename
, MAX_PATH
);
326 psh
.pszCaption
= (LPCWSTR
)wszFilename
;
328 /* Find out where to look for the shell extensions */
329 if (_ILIsValue(This
->apidl
[0]))
333 if (_ILGetExtension(This
->apidl
[0], sTemp
, 64))
335 HCR_MapTypeToValueA(sTemp
, sTemp
, 64, TRUE
);
336 MultiByteToWideChar(CP_ACP
, 0, sTemp
, -1, wszFiletype
, MAX_PATH
);
343 else if (_ILIsFolder(This
->apidl
[0]))
345 lstrcpynW(wszFiletype
, wszFolder
, 64);
347 else if (_ILIsSpecialFolder(This
->apidl
[0]))
350 static const WCHAR wszclsid
[] = {'C','L','S','I','D','\\', 0};
351 folderGUID
= _ILGetGUIDPointer(This
->apidl
[0]);
352 lstrcpyW(wszFiletype
, wszclsid
);
353 StringFromGUID2(folderGUID
, &wszFiletype
[6], MAX_PATH
- 6);
357 FIXME("Requested properties for unknown type.\n");
361 /* Get a suitable DataObject for accessing the files */
362 SHGetDesktopFolder(&lpDesktopSF
);
363 if (_ILIsPidlSimple(This
->pidl
))
365 ret
= IShellFolder_GetUIObjectOf(lpDesktopSF
, hwnd
, This
->cidl
, (LPCITEMIDLIST
*)This
->apidl
,
366 &IID_IDataObject
, NULL
, (LPVOID
*)&lpDo
);
367 IShellFolder_Release(lpDesktopSF
);
371 IShellFolder_BindToObject(lpDesktopSF
, This
->pidl
, NULL
, &IID_IShellFolder
, (LPVOID
*) &lpSF
);
372 ret
= IShellFolder_GetUIObjectOf(lpSF
, hwnd
, This
->cidl
, (LPCITEMIDLIST
*)This
->apidl
,
373 &IID_IDataObject
, NULL
, (LPVOID
*)&lpDo
);
374 IShellFolder_Release(lpSF
);
375 IShellFolder_Release(lpDesktopSF
);
380 hpsxa
= SHCreatePropSheetExtArrayEx(HKEY_CLASSES_ROOT
, wszFiletype
, MAX_PROP_PAGES
- psh
.nPages
, lpDo
);
383 SHAddFromPropSheetExtArray(hpsxa
, Properties_AddPropSheetCallback
, (LPARAM
)&psh
);
384 SHDestroyPropSheetExtArray(hpsxa
);
386 hpsxa
= SHCreatePropSheetExtArrayEx(HKEY_CLASSES_ROOT
, wszFiletypeAll
, MAX_PROP_PAGES
- psh
.nPages
, lpDo
);
389 SHAddFromPropSheetExtArray(hpsxa
, Properties_AddPropSheetCallback
, (LPARAM
)&psh
);
390 SHDestroyPropSheetExtArray(hpsxa
);
392 IDataObject_Release(lpDo
);
396 PropertySheetW(&psh
);
398 FIXME("No property pages found.\n");
401 static HRESULT WINAPI
ItemMenu_InvokeCommand(
402 IContextMenu2
*iface
,
403 LPCMINVOKECOMMANDINFO lpcmi
)
405 ContextMenu
*This
= impl_from_IContextMenu2(iface
);
407 if (lpcmi
->cbSize
!= sizeof(CMINVOKECOMMANDINFO
))
408 FIXME("Is an EX structure\n");
410 TRACE("(%p)->(invcom=%p verb=%p wnd=%p)\n",This
,lpcmi
,lpcmi
->lpVerb
, lpcmi
->hwnd
);
412 if( HIWORD(lpcmi
->lpVerb
)==0 && LOWORD(lpcmi
->lpVerb
) > FCIDM_SHVIEWLAST
)
414 TRACE("Invalid Verb %x\n",LOWORD(lpcmi
->lpVerb
));
418 if (HIWORD(lpcmi
->lpVerb
) == 0)
420 switch(LOWORD(lpcmi
->lpVerb
- This
->verb_offset
))
422 case FCIDM_SHVIEW_EXPLORE
:
423 TRACE("Verb FCIDM_SHVIEW_EXPLORE\n");
424 DoOpenExplore(This
, lpcmi
->hwnd
, "explore");
426 case FCIDM_SHVIEW_OPEN
:
427 TRACE("Verb FCIDM_SHVIEW_OPEN\n");
428 DoOpenExplore(This
, lpcmi
->hwnd
, "open");
430 case FCIDM_SHVIEW_RENAME
:
432 IShellBrowser
*browser
;
434 /* get the active IShellView */
435 browser
= (IShellBrowser
*)SendMessageA(lpcmi
->hwnd
, CWM_GETISHELLBROWSER
, 0, 0);
440 if(SUCCEEDED(IShellBrowser_QueryActiveShellView(browser
, &view
)))
442 TRACE("(shellview=%p)\n", view
);
443 IShellView_SelectItem(view
, This
->apidl
[0],
444 SVSI_DESELECTOTHERS
|SVSI_EDIT
|SVSI_ENSUREVISIBLE
|SVSI_FOCUSED
|SVSI_SELECT
);
445 IShellView_Release(view
);
450 case FCIDM_SHVIEW_DELETE
:
451 TRACE("Verb FCIDM_SHVIEW_DELETE\n");
454 case FCIDM_SHVIEW_COPY
:
455 TRACE("Verb FCIDM_SHVIEW_COPY\n");
456 DoCopyOrCut(This
, lpcmi
->hwnd
, FALSE
);
458 case FCIDM_SHVIEW_CUT
:
459 TRACE("Verb FCIDM_SHVIEW_CUT\n");
460 DoCopyOrCut(This
, lpcmi
->hwnd
, TRUE
);
462 case FCIDM_SHVIEW_PROPERTIES
:
463 TRACE("Verb FCIDM_SHVIEW_PROPERTIES\n");
464 DoOpenProperties(This
, lpcmi
->hwnd
);
467 FIXME("Unhandled Verb %xl\n",LOWORD(lpcmi
->lpVerb
)-This
->verb_offset
);
473 TRACE("Verb is %s\n",debugstr_a(lpcmi
->lpVerb
));
474 if (strcmp(lpcmi
->lpVerb
,"delete")==0)
476 else if (strcmp(lpcmi
->lpVerb
,"properties")==0)
477 DoOpenProperties(This
, lpcmi
->hwnd
);
479 FIXME("Unhandled string verb %s\n",debugstr_a(lpcmi
->lpVerb
));
486 static HRESULT WINAPI
ItemMenu_GetCommandString(
487 IContextMenu2
*iface
,
494 ContextMenu
*This
= impl_from_IContextMenu2(iface
);
495 HRESULT hr
= E_INVALIDARG
;
497 TRACE("(%p)->(%lx flags=%x %p name=%p len=%x)\n", This
, idCommand
, uFlags
, lpReserved
, lpszName
, uMaxNameLen
);
507 switch(idCommand
-This
->verb_offset
)
509 case FCIDM_SHVIEW_RENAME
:
510 strcpy(lpszName
, "rename");
516 /* NT 4.0 with IE 3.0x or no IE will always call This with GCS_VERBW. In This
517 case, you need to do the lstrcpyW to the pointer passed.*/
519 switch(idCommand
-This
->verb_offset
)
521 case FCIDM_SHVIEW_RENAME
:
522 MultiByteToWideChar( CP_ACP
, 0, "rename", -1, (LPWSTR
)lpszName
, uMaxNameLen
);
533 TRACE("-- (%p)->(name=%s)\n", This
, lpszName
);
537 /**************************************************************************
539 * should be only in IContextMenu2 and IContextMenu3
540 * is nevertheless called from word95
542 static HRESULT WINAPI
ItemMenu_HandleMenuMsg(
543 IContextMenu2
*iface
,
548 ContextMenu
*This
= impl_from_IContextMenu2(iface
);
549 TRACE("(%p)->(0x%x 0x%lx 0x%lx)\n", This
, uMsg
, wParam
, lParam
);
553 static const IContextMenu2Vtbl ItemContextMenuVtbl
=
555 ItemMenu_QueryInterface
,
558 ItemMenu_QueryContextMenu
,
559 ItemMenu_InvokeCommand
,
560 ItemMenu_GetCommandString
,
561 ItemMenu_HandleMenuMsg
564 IContextMenu2
*ItemMenu_Constructor(IShellFolder
*parent
, LPCITEMIDLIST pidl
, const LPCITEMIDLIST
*apidl
, UINT cidl
)
569 This
= HeapAlloc(GetProcessHeap(), 0, sizeof(*This
));
570 This
->IContextMenu2_iface
.lpVtbl
= &ItemContextMenuVtbl
;
572 This
->verb_offset
= 0;
573 This
->parent
= parent
;
574 if (parent
) IShellFolder_AddRef(parent
);
576 This
->pidl
= ILClone(pidl
);
577 This
->apidl
= _ILCopyaPidl(apidl
, cidl
);
579 This
->allvalues
= TRUE
;
581 This
->desktop
= FALSE
;
583 for(u
= 0; u
< cidl
; u
++)
584 This
->allvalues
&= (_ILIsValue(apidl
[u
]) ? 1 : 0);
586 TRACE("(%p)\n", This
);
588 return &This
->IContextMenu2_iface
;
591 /* Background menu implementation */
592 static HRESULT WINAPI
BackgroundMenu_QueryInterface(IContextMenu2
*iface
, REFIID riid
, void **ppvObj
)
594 ContextMenu
*This
= impl_from_IContextMenu2(iface
);
596 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), ppvObj
);
600 if(IsEqualIID(riid
, &IID_IUnknown
) ||
601 IsEqualIID(riid
, &IID_IContextMenu
) ||
602 IsEqualIID(riid
, &IID_IContextMenu2
))
606 else if(IsEqualIID(riid
, &IID_IShellExtInit
)) /*IShellExtInit*/
608 FIXME("-- LPSHELLEXTINIT pointer requested\n");
613 IContextMenu2_AddRef(iface
);
614 TRACE("-- Interface: (%p)->(%p)\n", ppvObj
, *ppvObj
);
618 TRACE("-- Interface: E_NOINTERFACE\n");
619 return E_NOINTERFACE
;
622 static ULONG WINAPI
BackgroundMenu_AddRef(IContextMenu2
*iface
)
624 ContextMenu
*This
= impl_from_IContextMenu2(iface
);
625 ULONG ref
= InterlockedIncrement(&This
->ref
);
626 TRACE("(%p)->(%u)\n", This
, ref
);
630 static ULONG WINAPI
BackgroundMenu_Release(IContextMenu2
*iface
)
632 ContextMenu
*This
= impl_from_IContextMenu2(iface
);
633 ULONG ref
= InterlockedDecrement(&This
->ref
);
635 TRACE("(%p)->(%u)\n", This
, ref
);
640 IShellFolder_Release(This
->parent
);
642 HeapFree(GetProcessHeap(), 0, This
);
648 static HRESULT WINAPI
BackgroundMenu_QueryContextMenu(
649 IContextMenu2
*iface
,
656 ContextMenu
*This
= impl_from_IContextMenu2(iface
);
661 TRACE("(%p)->(hmenu=%p indexmenu=%x cmdfirst=%x cmdlast=%x flags=%x )\n",
662 This
, hMenu
, indexMenu
, idCmdFirst
, idCmdLast
, uFlags
);
664 This
->verb_offset
= idCmdFirst
;
666 hMyMenu
= LoadMenuA(shell32_hInstance
, "MENU_002");
667 if (uFlags
& CMF_DEFAULTONLY
)
669 HMENU ourMenu
= GetSubMenu(hMyMenu
,0);
670 UINT oldDef
= GetMenuDefaultItem(hMenu
,TRUE
,GMDI_USEDISABLED
);
671 UINT newDef
= GetMenuDefaultItem(ourMenu
,TRUE
,GMDI_USEDISABLED
);
672 if (newDef
!= oldDef
)
673 SetMenuDefaultItem(hMenu
,newDef
,TRUE
);
674 if (newDef
!=0xFFFFFFFF)
675 hr
= MAKE_HRESULT(SEVERITY_SUCCESS
, FACILITY_NULL
, newDef
+1);
677 hr
= MAKE_HRESULT(SEVERITY_SUCCESS
, FACILITY_NULL
, 0);
681 idMax
= Shell_MergeMenus (hMenu
, GetSubMenu(hMyMenu
,0), indexMenu
,
682 idCmdFirst
, idCmdLast
, MM_SUBMENUSHAVEIDS
);
683 hr
= MAKE_HRESULT(SEVERITY_SUCCESS
, FACILITY_NULL
, idMax
-idCmdFirst
);
685 DestroyMenu(hMyMenu
);
687 TRACE("(%p)->returning 0x%x\n",This
,hr
);
691 static void DoNewFolder(ContextMenu
*This
, IShellView
*view
)
695 IShellFolder_QueryInterface(This
->parent
, &IID_ISFHelper
, (void**)&helper
);
698 WCHAR nameW
[MAX_PATH
];
701 ISFHelper_GetUniqueName(helper
, nameW
, MAX_PATH
);
702 ISFHelper_AddFolder(helper
, 0, nameW
, &pidl
);
706 /* if we are in a shellview do labeledit */
707 IShellView_SelectItem(view
,
708 pidl
,(SVSI_DESELECTOTHERS
| SVSI_EDIT
| SVSI_ENSUREVISIBLE
709 |SVSI_FOCUSED
|SVSI_SELECT
));
713 ISFHelper_Release(helper
);
717 static BOOL
DoPaste(ContextMenu
*This
)
719 BOOL bSuccess
= FALSE
;
724 if(SUCCEEDED(OleGetClipboard(&pda
)))
729 TRACE("pda=%p\n", pda
);
731 /* Set the FORMATETC structure*/
732 InitFormatEtc(formatetc
, RegisterClipboardFormatW(CFSTR_SHELLIDLISTW
), TYMED_HGLOBAL
);
734 /* Get the pidls from IDataObject */
735 if(SUCCEEDED(IDataObject_GetData(pda
,&formatetc
,&medium
)))
737 LPITEMIDLIST
* apidl
;
739 IShellFolder
*psfFrom
= NULL
, *psfDesktop
;
741 LPIDA lpcida
= GlobalLock(medium
.u
.hGlobal
);
742 TRACE("cida=%p\n", lpcida
);
744 apidl
= _ILCopyCidaToaPidl(&pidl
, lpcida
);
746 /* bind to the source shellfolder */
747 SHGetDesktopFolder(&psfDesktop
);
750 IShellFolder_BindToObject(psfDesktop
, pidl
, NULL
, &IID_IShellFolder
, (LPVOID
*)&psfFrom
);
751 IShellFolder_Release(psfDesktop
);
756 /* get source and destination shellfolder */
757 ISFHelper
*psfhlpdst
, *psfhlpsrc
;
758 IShellFolder_QueryInterface(This
->parent
, &IID_ISFHelper
, (void**)&psfhlpdst
);
759 IShellFolder_QueryInterface(psfFrom
, &IID_ISFHelper
, (void**)&psfhlpsrc
);
761 /* do the copy/move */
762 if (psfhlpdst
&& psfhlpsrc
)
764 ISFHelper_CopyItems(psfhlpdst
, psfFrom
, lpcida
->cidl
, (LPCITEMIDLIST
*)apidl
);
766 ISFHelper_DeleteItems(psfhlpsrc, lpcida->cidl, apidl);
769 if(psfhlpdst
) ISFHelper_Release(psfhlpdst
);
770 if(psfhlpsrc
) ISFHelper_Release(psfhlpsrc
);
771 IShellFolder_Release(psfFrom
);
774 _ILFreeaPidl(apidl
, lpcida
->cidl
);
777 /* release the medium*/
778 ReleaseStgMedium(&medium
);
780 IDataObject_Release(pda
);
786 hMem
= GetClipboardData(CF_HDROP
);
790 char * pDropFiles
= GlobalLock(hMem
);
793 int len
, offset
= sizeof(DROPFILESTRUCT
);
795 while( pDropFiles
[offset
] != 0)
797 len
= strlen(pDropFiles
+ offset
);
798 TRACE("%s\n", pDropFiles
+ offset
);
809 static HRESULT WINAPI
BackgroundMenu_InvokeCommand(
810 IContextMenu2
*iface
,
811 LPCMINVOKECOMMANDINFO lpcmi
)
813 ContextMenu
*This
= impl_from_IContextMenu2(iface
);
814 IShellBrowser
*browser
;
815 IShellView
*view
= NULL
;
818 TRACE("(%p)->(invcom=%p verb=%p wnd=%p)\n", This
, lpcmi
, lpcmi
->lpVerb
, lpcmi
->hwnd
);
820 /* get the active IShellView */
821 if ((browser
= (IShellBrowser
*)SendMessageA(lpcmi
->hwnd
, CWM_GETISHELLBROWSER
, 0, 0)))
823 if (SUCCEEDED(IShellBrowser_QueryActiveShellView(browser
, &view
)))
824 IShellView_GetWindow(view
, &hWnd
);
827 if(HIWORD(lpcmi
->lpVerb
))
829 TRACE("%s\n", debugstr_a(lpcmi
->lpVerb
));
831 if (!strcmp(lpcmi
->lpVerb
, CMDSTR_NEWFOLDERA
))
833 DoNewFolder(This
, view
);
835 else if (!strcmp(lpcmi
->lpVerb
, CMDSTR_VIEWLISTA
))
837 if (hWnd
) SendMessageA(hWnd
, WM_COMMAND
, MAKEWPARAM(FCIDM_SHVIEW_LISTVIEW
, 0), 0);
839 else if (!strcmp(lpcmi
->lpVerb
, CMDSTR_VIEWDETAILSA
))
841 if (hWnd
) SendMessageA(hWnd
, WM_COMMAND
, MAKEWPARAM(FCIDM_SHVIEW_REPORTVIEW
, 0), 0);
845 FIXME("please report: unknown verb %s\n", debugstr_a(lpcmi
->lpVerb
));
850 switch (LOWORD(lpcmi
->lpVerb
) - This
->verb_offset
)
852 case FCIDM_SHVIEW_REFRESH
:
853 if (view
) IShellView_Refresh(view
);
856 case FCIDM_SHVIEW_NEWFOLDER
:
857 DoNewFolder(This
, view
);
860 case FCIDM_SHVIEW_INSERT
:
864 case FCIDM_SHVIEW_PROPERTIES
:
866 ShellExecuteA(lpcmi
->hwnd
, "open", "rundll32.exe shell32.dll,Control_RunDLL desk.cpl", NULL
, NULL
, SW_SHOWNORMAL
);
868 FIXME("launch item properties dialog\n");
873 /* if it's an id just pass it to the parent shv */
874 if (hWnd
) SendMessageA(hWnd
, WM_COMMAND
, MAKEWPARAM(LOWORD(lpcmi
->lpVerb
), 0), 0);
880 IShellView_Release(view
);
885 static HRESULT WINAPI
BackgroundMenu_GetCommandString(
886 IContextMenu2
*iface
,
893 ContextMenu
*This
= impl_from_IContextMenu2(iface
);
895 TRACE("(%p)->(idcom=%lx flags=%x %p name=%p len=%x)\n",This
, idCommand
, uFlags
, lpReserved
, lpszName
, uMaxNameLen
);
897 /* test the existence of the menu items, the file dialog enables
898 the buttons according to this */
899 if (uFlags
== GCS_VALIDATEA
)
901 if(HIWORD(idCommand
))
903 if (!strcmp((LPSTR
)idCommand
, CMDSTR_VIEWLISTA
) ||
904 !strcmp((LPSTR
)idCommand
, CMDSTR_VIEWDETAILSA
) ||
905 !strcmp((LPSTR
)idCommand
, CMDSTR_NEWFOLDERA
))
912 FIXME("unknown command string\n");
916 static HRESULT WINAPI
BackgroundMenu_HandleMenuMsg(
917 IContextMenu2
*iface
,
922 ContextMenu
*This
= impl_from_IContextMenu2(iface
);
923 FIXME("(%p)->(msg=%x wp=%lx lp=%lx)\n",This
, uMsg
, wParam
, lParam
);
927 static const IContextMenu2Vtbl BackgroundContextMenuVtbl
=
929 BackgroundMenu_QueryInterface
,
930 BackgroundMenu_AddRef
,
931 BackgroundMenu_Release
,
932 BackgroundMenu_QueryContextMenu
,
933 BackgroundMenu_InvokeCommand
,
934 BackgroundMenu_GetCommandString
,
935 BackgroundMenu_HandleMenuMsg
938 IContextMenu2
*BackgroundMenu_Constructor(IShellFolder
*parent
, BOOL desktop
)
942 This
= HeapAlloc(GetProcessHeap(), 0, sizeof(*This
));
943 This
->IContextMenu2_iface
.lpVtbl
= &BackgroundContextMenuVtbl
;
945 This
->parent
= parent
;
946 This
->verb_offset
= 0;
951 This
->allvalues
= FALSE
;
953 This
->desktop
= desktop
;
954 if (parent
) IShellFolder_AddRef(parent
);
956 TRACE("(%p)\n", This
);
957 return &This
->IContextMenu2_iface
;