>From c99f72c6becfd74cfe3596c4d14b37cd717afcec Mon Sep 17 00:00:00 2001
From: Nikolay Sivov <nsivov@codeweavers.com>
Date: Tue, 10 Jan 2012 18:47:52 +0300
Subject: [PATCH 4/4] Merge ShellView menu implementations into a single file

---
 dlls/shell32/Makefile.in        |    3 +-
 dlls/shell32/cpanelfolder.c     |    2 +-
 dlls/shell32/shell32_main.h     |    4 +-
 dlls/shell32/shfldr_desktop.c   |    4 +-
 dlls/shell32/shfldr_fs.c        |    2 +-
 dlls/shell32/shfldr_mycomp.c    |    2 +-
 dlls/shell32/shfldr_netplaces.c |    2 +-
 dlls/shell32/shfldr_unixfs.c    |    2 +-
 dlls/shell32/shlmenu.c          |    4 +-
 dlls/shell32/shlview.c          |    4 +-
 dlls/shell32/shlview_cmenu.c    |  973 +++++++++++++++++++++++++++++++++++++++
 dlls/shell32/shv_bg_cmenu.c     |  458 ------------------
 dlls/shell32/shv_item_cmenu.c   |  623 -------------------------
 13 files changed, 987 insertions(+), 1096 deletions(-)
 create mode 100644 dlls/shell32/shlview_cmenu.c
 delete mode 100644 dlls/shell32/shv_bg_cmenu.c
 delete mode 100644 dlls/shell32/shv_item_cmenu.c

diff --git a/dlls/shell32/Makefile.in b/dlls/shell32/Makefile.in
index e9fdcc1..cf61e43 100644
--- a/dlls/shell32/Makefile.in
+++ b/dlls/shell32/Makefile.in
@@ -46,9 +46,8 @@ C_SRCS = \
 	shlfsbind.c \
 	shlmenu.c \
 	shlview.c \
+	shlview_cmenu.c \
 	shpolicy.c \
-	shv_bg_cmenu.c \
-	shv_item_cmenu.c \
 	systray.c \
 	trash.c \
 	xdg.c
diff --git a/dlls/shell32/cpanelfolder.c b/dlls/shell32/cpanelfolder.c
index b006632..bbbd944 100644
--- a/dlls/shell32/cpanelfolder.c
+++ b/dlls/shell32/cpanelfolder.c
@@ -600,7 +600,7 @@ static HRESULT WINAPI ISF_ControlPanel_fnGetUIObjectOf(IShellFolder2 *iface, HWN
 	*ppvOut = NULL;
 
 	if (IsEqualIID(riid, &IID_IContextMenu) &&(cidl >= 1)) {
-	    pObj = (LPUNKNOWN) ISvItemCm_Constructor((IShellFolder *) iface, This->pidlRoot, apidl, cidl);
+	    pObj = (LPUNKNOWN) ItemMenu_Constructor((IShellFolder *) iface, This->pidlRoot, apidl, cidl);
 	    hr = S_OK;
 	} else if (IsEqualIID(riid, &IID_IDataObject) &&(cidl >= 1)) {
 	    pObj = (LPUNKNOWN) IDataObject_Constructor(hwndOwner, This->pidlRoot, apidl, cidl);
diff --git a/dlls/shell32/shell32_main.h b/dlls/shell32/shell32_main.h
index dd5f1ab..4b883fd 100644
--- a/dlls/shell32/shell32_main.h
+++ b/dlls/shell32/shell32_main.h
@@ -78,8 +78,8 @@ LPDATAOBJECT	IDataObject_Constructor(HWND hwndOwner, LPCITEMIDLIST myPidl, LPCIT
 LPENUMFORMATETC	IEnumFORMATETC_Constructor(UINT, const FORMATETC []) DECLSPEC_HIDDEN;
 
 LPCLASSFACTORY	IClassFactory_Constructor(REFCLSID) DECLSPEC_HIDDEN;
-IContextMenu2 *	ISvItemCm_Constructor(LPSHELLFOLDER pSFParent, LPCITEMIDLIST pidl, const LPCITEMIDLIST *aPidls, UINT uItemCount) DECLSPEC_HIDDEN;
-IContextMenu2 *	ISvBgCm_Constructor(LPSHELLFOLDER pSFParent, BOOL bDesktop) DECLSPEC_HIDDEN;
+IContextMenu2 *	ItemMenu_Constructor(IShellFolder*, LPCITEMIDLIST, const LPCITEMIDLIST*, UINT) DECLSPEC_HIDDEN;
+IContextMenu2 *	BackgroundMenu_Constructor(IShellFolder*, BOOL) DECLSPEC_HIDDEN;
 LPSHELLVIEW	IShellView_Constructor(LPSHELLFOLDER) DECLSPEC_HIDDEN;
 
 HRESULT WINAPI IFSFolder_Constructor(IUnknown * pUnkOuter, REFIID riid, LPVOID * ppv) DECLSPEC_HIDDEN;
diff --git a/dlls/shell32/shfldr_desktop.c b/dlls/shell32/shfldr_desktop.c
index 5b90260..202a793 100644
--- a/dlls/shell32/shfldr_desktop.c
+++ b/dlls/shell32/shfldr_desktop.c
@@ -530,9 +530,9 @@ static HRESULT WINAPI ISF_Desktop_fnGetUIObjectOf (IShellFolder2 * iface,
     if (IsEqualIID (riid, &IID_IContextMenu))
     {
         if (cidl > 0)
-            pObj = (LPUNKNOWN) ISvItemCm_Constructor( (IShellFolder *) iface, This->pidlRoot, apidl, cidl);
+            pObj = (LPUNKNOWN) ItemMenu_Constructor( (IShellFolder *) iface, This->pidlRoot, apidl, cidl);
         else
-            pObj = (LPUNKNOWN) ISvBgCm_Constructor( (IShellFolder *) iface, TRUE);
+            pObj = (LPUNKNOWN) BackgroundMenu_Constructor( (IShellFolder *) iface, TRUE);
         hr = S_OK;
     }
     else if (IsEqualIID (riid, &IID_IDataObject) && (cidl >= 1))
diff --git a/dlls/shell32/shfldr_fs.c b/dlls/shell32/shfldr_fs.c
index b591533..49c4e7e 100644
--- a/dlls/shell32/shfldr_fs.c
+++ b/dlls/shell32/shfldr_fs.c
@@ -744,7 +744,7 @@ IShellFolder_fnGetUIObjectOf (IShellFolder2 * iface,
         }
 
         if (IsEqualIID (riid, &IID_IContextMenu) && (cidl >= 1)) {
-            pObj = (LPUNKNOWN) ISvItemCm_Constructor ((IShellFolder *) iface,
+            pObj = (LPUNKNOWN) ItemMenu_Constructor ((IShellFolder *) iface,
              This->pidlRoot, apidl, cidl);
             hr = S_OK;
         } else if (IsEqualIID (riid, &IID_IDataObject) && (cidl >= 1)) {
diff --git a/dlls/shell32/shfldr_mycomp.c b/dlls/shell32/shfldr_mycomp.c
index d32f975..2482223 100644
--- a/dlls/shell32/shfldr_mycomp.c
+++ b/dlls/shell32/shfldr_mycomp.c
@@ -532,7 +532,7 @@ static HRESULT WINAPI ISF_MyComputer_fnGetUIObjectOf (IShellFolder2 * iface,
 
     if (IsEqualIID (riid, &IID_IContextMenu) && (cidl >= 1))
     {
-        pObj = (LPUNKNOWN) ISvItemCm_Constructor ((IShellFolder *) iface,
+        pObj = (LPUNKNOWN) ItemMenu_Constructor ((IShellFolder *) iface,
                                               This->pidlRoot, apidl, cidl);
         hr = S_OK;
     }
diff --git a/dlls/shell32/shfldr_netplaces.c b/dlls/shell32/shfldr_netplaces.c
index c5034f8..f1fd0e7 100644
--- a/dlls/shell32/shfldr_netplaces.c
+++ b/dlls/shell32/shfldr_netplaces.c
@@ -426,7 +426,7 @@ static HRESULT WINAPI ISF_NetworkPlaces_fnGetUIObjectOf (IShellFolder2 * iface,
 
     if (IsEqualIID (riid, &IID_IContextMenu) && (cidl >= 1))
     {
-        pObj = (LPUNKNOWN) ISvItemCm_Constructor ((IShellFolder *) iface, This->pidlRoot, apidl, cidl);
+        pObj = (LPUNKNOWN) ItemMenu_Constructor ((IShellFolder *) iface, This->pidlRoot, apidl, cidl);
         hr = S_OK;
     }
     else if (IsEqualIID (riid, &IID_IDataObject) && (cidl >= 1))
diff --git a/dlls/shell32/shfldr_unixfs.c b/dlls/shell32/shfldr_unixfs.c
index 9fe0786..40d4c5c 100644
--- a/dlls/shell32/shfldr_unixfs.c
+++ b/dlls/shell32/shfldr_unixfs.c
@@ -1167,7 +1167,7 @@ static HRESULT WINAPI UnixFolder_IShellFolder2_GetUIObjectOf(IShellFolder2* ifac
     }
     
     if (IsEqualIID(&IID_IContextMenu, riid)) {
-        *ppvOut = ISvItemCm_Constructor((IShellFolder*)iface, This->m_pidlLocation, apidl, cidl);
+        *ppvOut = ItemMenu_Constructor((IShellFolder*)iface, This->m_pidlLocation, apidl, cidl);
         return S_OK;
     } else if (IsEqualIID(&IID_IDataObject, riid)) {
         *ppvOut = IDataObject_Constructor(hwndOwner, This->m_pidlLocation, apidl, cidl);
diff --git a/dlls/shell32/shlmenu.c b/dlls/shell32/shlmenu.c
index 476cbec..c3fd055 100644
--- a/dlls/shell32/shlmenu.c
+++ b/dlls/shell32/shlmenu.c
@@ -1275,7 +1275,7 @@ HRESULT WINAPI CDefFolderMenu_Create2(LPCITEMIDLIST pidlFolder, HWND hwnd, UINT
     }
     else
         folder_pidl=ILClone(pidlFolder);
-    system_menu = (IContextMenu*)ISvItemCm_Constructor(psf,folder_pidl,(const LPCITEMIDLIST*)apidl,cidl);
+    system_menu = (IContextMenu*)ItemMenu_Constructor(psf,folder_pidl,(const LPCITEMIDLIST*)apidl,cidl);
     hres= SHELL_CreateContextMenu(hwnd,system_menu,psf,folder_pidl,apidl,cidl,ahkeys,nKeys,&IID_IContextMenu,(void**)ppcm);
     IContextMenu_Release(system_menu);
     ILFree(folder_pidl);
@@ -1300,7 +1300,7 @@ HRESULT WINAPI SHCreateDefaultContextMenu(const DEFCONTEXTMENU *pdcm, REFIID rii
         folder_pidl=ILClone(pdcm->pidlFolder);
     if(pdcm->cKeys==0)
         FIXME("Loading shell extensions using IQueryAssociations not yet supported\n");
-    system_menu = (IContextMenu*)ISvItemCm_Constructor(folder,folder_pidl,(const LPCITEMIDLIST*)pdcm->apidl,pdcm->cidl);
+    system_menu = (IContextMenu*)ItemMenu_Constructor(folder,folder_pidl,(const LPCITEMIDLIST*)pdcm->apidl,pdcm->cidl);
     ret = SHELL_CreateContextMenu(pdcm->hwnd,system_menu,folder,folder_pidl,(LPCITEMIDLIST*)pdcm->apidl,pdcm->cidl,pdcm->aKeys,pdcm->cKeys,riid,ppv);
     IContextMenu_Release(system_menu);
     ILFree(folder_pidl);
diff --git a/dlls/shell32/shlview.c b/dlls/shell32/shlview.c
index 191dfb1..44cbcb6 100644
--- a/dlls/shell32/shlview.c
+++ b/dlls/shell32/shlview.c
@@ -1095,7 +1095,7 @@ static void ShellView_DoContextMenu(IShellViewImpl * This, WORD x, WORD y, BOOL
 	{
 	  hMenu = CreatePopupMenu();
 
-	  pCM = ISvBgCm_Constructor(This->pSFParent, FALSE);
+	  pCM = BackgroundMenu_Constructor(This->pSFParent, FALSE);
 	  IContextMenu2_QueryContextMenu(pCM, hMenu, 0, FCIDM_SHVIEWFIRST, FCIDM_SHVIEWLAST, 0);
 
 	  uCommand = TrackPopupMenu( hMenu, TPM_LEFTALIGN | TPM_RETURNCMD,x,y,0,This->hWnd,NULL);
@@ -2050,7 +2050,7 @@ static HRESULT WINAPI IShellView_fnGetItemObject(IShellView2 *iface, UINT uItem,
 
         if (IsEqualIID(&IID_IContextMenu, riid))
         {
-            *ppvOut = ISvBgCm_Constructor(This->pSFParent, FALSE);
+            *ppvOut = BackgroundMenu_Constructor(This->pSFParent, FALSE);
             hr = S_OK;
         }
         else
diff --git a/dlls/shell32/shlview_cmenu.c b/dlls/shell32/shlview_cmenu.c
new file mode 100644
index 0000000..7588daa
--- /dev/null
+++ b/dlls/shell32/shlview_cmenu.c
@@ -0,0 +1,973 @@
+/*
+ *	IContextMenu for items in the shellview
+ *
+ * Copyright 1998-2000 Juergen Schmied <juergen.schmied@debitel.net>,
+ *                                     <juergen.schmied@metronet.de>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <string.h>
+
+#define COBJMACROS
+#define NONAMELESSUNION
+#define NONAMELESSSTRUCT
+
+#include "winerror.h"
+#include "wine/debug.h"
+
+#include "windef.h"
+#include "wingdi.h"
+#include "pidl.h"
+#include "undocshell.h"
+#include "shlobj.h"
+#include "winreg.h"
+#include "prsht.h"
+
+#include "shell32_main.h"
+#include "shellfolder.h"
+
+#include "shresdef.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(shell);
+
+typedef struct
+{
+    IContextMenu2 IContextMenu2_iface;
+    LONG ref;
+    IShellFolder* parent;
+    UINT verb_offset;
+} ContextMenu;
+
+typedef struct
+{
+    ContextMenu     menu;
+    LPITEMIDLIST    pidl;       /* root pidl */
+    LPITEMIDLIST    *apidl;     /* array of child pidls */
+    UINT            cidl;
+    BOOL            bAllValues;
+} ItemMenu;
+
+static inline ItemMenu *impl_from_IContextMenu2_Item(IContextMenu2 *iface)
+{
+    return CONTAINING_RECORD(iface, ItemMenu, menu.IContextMenu2_iface);
+}
+
+typedef struct
+{
+    ContextMenu menu;
+    BOOL desktop;
+} BackgroundMenu;
+
+static inline BackgroundMenu *impl_from_IContextMenu2_Back(IContextMenu2 *iface)
+{
+    return CONTAINING_RECORD(iface, BackgroundMenu, menu.IContextMenu2_iface);
+}
+
+static BOOL ItemMenu_CanRenameItems(ItemMenu *This)
+{
+    DWORD attr;
+
+    TRACE("(%p)\n", This);
+
+    /* can't rename more than one item at a time*/
+    if (!This->apidl || This->cidl > 1) return FALSE;
+
+    attr = SFGAO_CANRENAME;
+    IShellFolder_GetAttributesOf(This->menu.parent, 1, (LPCITEMIDLIST*)This->apidl, &attr);
+    return attr & SFGAO_CANRENAME;
+}
+
+static HRESULT WINAPI ItemMenu_QueryInterface(IContextMenu2 *iface, REFIID riid, LPVOID *ppvObj)
+{
+	ItemMenu *This = impl_from_IContextMenu2_Item(iface);
+
+	TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_guid(riid),ppvObj);
+
+	*ppvObj = NULL;
+
+        if(IsEqualIID(riid, &IID_IUnknown) ||
+           IsEqualIID(riid, &IID_IContextMenu) ||
+           IsEqualIID(riid, &IID_IContextMenu2))
+	{
+	  *ppvObj = This;
+	}
+	else if(IsEqualIID(riid, &IID_IShellExtInit))  /*IShellExtInit*/
+	{
+	  FIXME("-- LPSHELLEXTINIT pointer requested\n");
+	}
+
+	if(*ppvObj)
+	{
+	  IUnknown_AddRef((IUnknown*)*ppvObj);
+	  TRACE("-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj);
+	  return S_OK;
+	}
+	TRACE("-- Interface: E_NOINTERFACE\n");
+	return E_NOINTERFACE;
+}
+
+static ULONG WINAPI ItemMenu_AddRef(IContextMenu2 *iface)
+{
+	ItemMenu *This = impl_from_IContextMenu2_Item(iface);
+	ULONG refCount = InterlockedIncrement(&This->menu.ref);
+
+	TRACE("(%p)->(count=%u)\n", This, refCount - 1);
+
+	return refCount;
+}
+
+static ULONG WINAPI ItemMenu_Release(IContextMenu2 *iface)
+{
+	ItemMenu *This = impl_from_IContextMenu2_Item(iface);
+	ULONG refCount = InterlockedDecrement(&This->menu.ref);
+
+	TRACE("(%p)->(count=%i)\n", This, refCount + 1);
+
+	if (!refCount)
+	{
+	  TRACE(" destroying IContextMenu(%p)\n",This);
+
+	  if(This->menu.parent)
+	    IShellFolder_Release(This->menu.parent);
+
+	  SHFree(This->pidl);
+
+	  /*make sure the pidl is freed*/
+	  _ILFreeaPidl(This->apidl, This->cidl);
+
+	  HeapFree(GetProcessHeap(),0,This);
+	}
+	return refCount;
+}
+
+static HRESULT WINAPI ItemMenu_QueryContextMenu(
+	IContextMenu2 *iface,
+	HMENU hmenu,
+	UINT indexMenu,
+	UINT idCmdFirst,
+	UINT idCmdLast,
+	UINT uFlags)
+{
+    ItemMenu *This = impl_from_IContextMenu2_Item(iface);
+    INT uIDMax;
+
+    TRACE("(%p)->(hmenu=%p indexmenu=%x cmdfirst=%x cmdlast=%x flags=%x )\n",This, hmenu, indexMenu, idCmdFirst, idCmdLast, uFlags);
+
+    This->menu.verb_offset=idCmdFirst;
+
+    if(!(CMF_DEFAULTONLY & uFlags) && This->cidl>0)
+    {
+        HMENU hmenures = LoadMenuW(shell32_hInstance, MAKEINTRESOURCEW(MENU_SHV_FILE));
+
+        if(uFlags & CMF_EXPLORE)
+            RemoveMenu(hmenures, FCIDM_SHVIEW_OPEN, MF_BYCOMMAND);
+
+        uIDMax = Shell_MergeMenus(hmenu, GetSubMenu(hmenures, 0), indexMenu, idCmdFirst, idCmdLast, MM_SUBMENUSHAVEIDS);
+
+        DestroyMenu(hmenures);
+
+        if(This->bAllValues)
+        {
+            MENUITEMINFOW mi;
+            WCHAR str[255];
+            mi.cbSize = sizeof(mi);
+            mi.fMask = MIIM_ID | MIIM_STRING | MIIM_FTYPE;
+            mi.dwTypeData = str;
+            mi.cch = 255;
+            GetMenuItemInfoW(hmenu, FCIDM_SHVIEW_EXPLORE, MF_BYCOMMAND, &mi);
+            RemoveMenu(hmenu, FCIDM_SHVIEW_EXPLORE, MF_BYCOMMAND);
+
+            mi.cbSize = sizeof(mi);
+            mi.fMask = MIIM_ID | MIIM_TYPE | MIIM_STATE;
+            mi.dwTypeData = str;
+            mi.fState = MFS_ENABLED;
+            mi.wID = FCIDM_SHVIEW_EXPLORE;
+            mi.fType = MFT_STRING;
+            InsertMenuItemW(hmenu, (uFlags & CMF_EXPLORE) ? 1 : 2, MF_BYPOSITION, &mi);
+        }
+
+        SetMenuDefaultItem(hmenu, 0, MF_BYPOSITION);
+
+        if(uFlags & ~CMF_CANRENAME)
+            RemoveMenu(hmenu, FCIDM_SHVIEW_RENAME, MF_BYCOMMAND);
+        else
+            EnableMenuItem(hmenu, FCIDM_SHVIEW_RENAME, MF_BYCOMMAND | ItemMenu_CanRenameItems(This) ? MFS_ENABLED : MFS_DISABLED);
+
+        return MAKE_HRESULT(SEVERITY_SUCCESS, 0, uIDMax-idCmdFirst);
+    }
+    return MAKE_HRESULT(SEVERITY_SUCCESS, 0, 0);
+}
+
+/**************************************************************************
+* DoOpenExplore
+*
+*  for folders only
+*/
+
+static void DoOpenExplore(ItemMenu *This, HWND hwnd, LPCSTR verb)
+{
+	UINT i, bFolderFound = FALSE;
+	LPITEMIDLIST	pidlFQ;
+	SHELLEXECUTEINFOA	sei;
+
+	/* Find the first item in the list that is not a value. These commands
+	    should never be invoked if there isn't at least one folder item in the list.*/
+
+	for(i = 0; i<This->cidl; i++)
+	{
+	  if(!_ILIsValue(This->apidl[i]))
+	  {
+	    bFolderFound = TRUE;
+	    break;
+	  }
+	}
+
+	if (!bFolderFound) return;
+
+	pidlFQ = ILCombine(This->pidl, This->apidl[i]);
+
+	ZeroMemory(&sei, sizeof(sei));
+	sei.cbSize = sizeof(sei);
+	sei.fMask = SEE_MASK_IDLIST | SEE_MASK_CLASSNAME;
+	sei.lpIDList = pidlFQ;
+	sei.lpClass = "Folder";
+	sei.hwnd = hwnd;
+	sei.nShow = SW_SHOWNORMAL;
+	sei.lpVerb = verb;
+	ShellExecuteExA(&sei);
+	SHFree(pidlFQ);
+}
+
+/**************************************************************************
+ * DoDelete
+ *
+ * deletes the currently selected items
+ */
+static void DoDelete(ItemMenu *This)
+{
+	ISFHelper * psfhlp;
+
+	IShellFolder_QueryInterface(This->menu.parent, &IID_ISFHelper, (LPVOID*)&psfhlp);
+	if (psfhlp)
+	{
+	  ISFHelper_DeleteItems(psfhlp, This->cidl, (LPCITEMIDLIST *)This->apidl);
+	  ISFHelper_Release(psfhlp);
+	}
+}
+
+/**************************************************************************
+ * DoCopyOrCut
+ *
+ * copies the currently selected items into the clipboard
+ */
+static BOOL DoCopyOrCut(ItemMenu *This, HWND hwnd, BOOL bCut)
+{
+	LPSHELLBROWSER	lpSB;
+	LPSHELLVIEW	lpSV;
+	LPDATAOBJECT    lpDo;
+
+	TRACE("(%p)->(wnd=%p,bCut=0x%08x)\n",This, hwnd, bCut);
+
+	/* get the active IShellView */
+	if ((lpSB = (LPSHELLBROWSER)SendMessageA(hwnd, CWM_GETISHELLBROWSER,0,0)))
+	{
+	  if (SUCCEEDED(IShellBrowser_QueryActiveShellView(lpSB, &lpSV)))
+	  {
+	    if (SUCCEEDED(IShellView_GetItemObject(lpSV, SVGIO_SELECTION, &IID_IDataObject, (LPVOID*)&lpDo)))
+	    {
+	      OleSetClipboard(lpDo);
+	      IDataObject_Release(lpDo);
+	    }
+	    IShellView_Release(lpSV);
+	  }
+	}
+	return TRUE;
+}
+
+/**************************************************************************
+ * Properties_AddPropSheetCallback
+ *
+ * Used by DoOpenProperties through SHCreatePropSheetExtArrayEx to add
+ * propertysheet pages from shell extensions.
+ */
+static BOOL CALLBACK Properties_AddPropSheetCallback(HPROPSHEETPAGE hpage, LPARAM lparam)
+{
+	LPPROPSHEETHEADERW psh = (LPPROPSHEETHEADERW) lparam;
+	psh->u3.phpage[psh->nPages++] = hpage;
+
+	return TRUE;
+}
+
+/**************************************************************************
+ * DoOpenProperties
+ */
+static void DoOpenProperties(ItemMenu *This, HWND hwnd)
+{
+	static const UINT MAX_PROP_PAGES = 99;
+	static const WCHAR wszFolder[] = {'F','o','l','d','e','r', 0};
+	static const WCHAR wszFiletypeAll[] = {'*',0};
+	LPSHELLFOLDER lpDesktopSF;
+	LPSHELLFOLDER lpSF;
+	LPDATAOBJECT lpDo;
+	WCHAR wszFiletype[MAX_PATH];
+	WCHAR wszFilename[MAX_PATH];
+	PROPSHEETHEADERW psh;
+	HPROPSHEETPAGE hpages[MAX_PROP_PAGES];
+	HPSXA hpsxa;
+	UINT ret;
+
+	TRACE("(%p)->(wnd=%p)\n", This, hwnd);
+
+	ZeroMemory(&psh, sizeof(PROPSHEETHEADERW));
+	psh.dwSize = sizeof (PROPSHEETHEADERW);
+	psh.hwndParent = hwnd;
+	psh.dwFlags = PSH_PROPTITLE;
+	psh.nPages = 0;
+	psh.u3.phpage = hpages;
+	psh.u2.nStartPage = 0;
+
+	_ILSimpleGetTextW(This->apidl[0], (LPVOID)wszFilename, MAX_PATH);
+	psh.pszCaption = (LPCWSTR)wszFilename;
+
+	/* Find out where to look for the shell extensions */
+	if (_ILIsValue(This->apidl[0]))
+	{
+	    char sTemp[64];
+	    sTemp[0] = 0;
+	    if (_ILGetExtension(This->apidl[0], sTemp, 64))
+	    {
+		HCR_MapTypeToValueA(sTemp, sTemp, 64, TRUE);
+		MultiByteToWideChar(CP_ACP, 0, sTemp, -1, wszFiletype, MAX_PATH);
+	    }
+	    else
+	    {
+		wszFiletype[0] = 0;
+	    }
+	}
+	else if (_ILIsFolder(This->apidl[0]))
+	{
+	    lstrcpynW(wszFiletype, wszFolder, 64);
+	}
+	else if (_ILIsSpecialFolder(This->apidl[0]))
+	{
+	    LPGUID folderGUID;
+	    static const WCHAR wszclsid[] = {'C','L','S','I','D','\\', 0};
+	    folderGUID = _ILGetGUIDPointer(This->apidl[0]);
+	    lstrcpyW(wszFiletype, wszclsid);
+	    StringFromGUID2(folderGUID, &wszFiletype[6], MAX_PATH - 6);
+	}
+	else
+	{
+	    FIXME("Requested properties for unknown type.\n");
+	    return;
+	}
+
+	/* Get a suitable DataObject for accessing the files */
+	SHGetDesktopFolder(&lpDesktopSF);
+	if (_ILIsPidlSimple(This->pidl))
+	{
+	    ret = IShellFolder_GetUIObjectOf(lpDesktopSF, hwnd, This->cidl, (LPCITEMIDLIST*)This->apidl,
+					     &IID_IDataObject, NULL, (LPVOID *)&lpDo);
+	    IShellFolder_Release(lpDesktopSF);
+	}
+	else
+	{
+	    IShellFolder_BindToObject(lpDesktopSF, This->pidl, NULL, &IID_IShellFolder, (LPVOID*) &lpSF);
+	    ret = IShellFolder_GetUIObjectOf(lpSF, hwnd, This->cidl, (LPCITEMIDLIST*)This->apidl,
+					     &IID_IDataObject, NULL, (LPVOID *)&lpDo);
+	    IShellFolder_Release(lpSF);
+	    IShellFolder_Release(lpDesktopSF);
+	}
+
+	if (SUCCEEDED(ret))
+	{
+	    hpsxa = SHCreatePropSheetExtArrayEx(HKEY_CLASSES_ROOT, wszFiletype, MAX_PROP_PAGES - psh.nPages, lpDo);
+	    if (hpsxa != NULL)
+	    {
+		SHAddFromPropSheetExtArray(hpsxa, Properties_AddPropSheetCallback, (LPARAM)&psh);
+		SHDestroyPropSheetExtArray(hpsxa);
+	    }
+	    hpsxa = SHCreatePropSheetExtArrayEx(HKEY_CLASSES_ROOT, wszFiletypeAll, MAX_PROP_PAGES - psh.nPages, lpDo);
+	    if (hpsxa != NULL)
+	    {
+		SHAddFromPropSheetExtArray(hpsxa, Properties_AddPropSheetCallback, (LPARAM)&psh);
+		SHDestroyPropSheetExtArray(hpsxa);
+	    }
+	    IDataObject_Release(lpDo);
+	}
+
+	if (psh.nPages)
+	    PropertySheetW(&psh);
+	else
+	    FIXME("No property pages found.\n");
+}
+
+static HRESULT WINAPI ItemMenu_InvokeCommand(
+	IContextMenu2 *iface,
+	LPCMINVOKECOMMANDINFO lpcmi)
+{
+    ItemMenu *This = impl_from_IContextMenu2_Item(iface);
+
+    if (lpcmi->cbSize != sizeof(CMINVOKECOMMANDINFO))
+        FIXME("Is an EX structure\n");
+
+    TRACE("(%p)->(invcom=%p verb=%p wnd=%p)\n",This,lpcmi,lpcmi->lpVerb, lpcmi->hwnd);
+
+    if( HIWORD(lpcmi->lpVerb)==0 && LOWORD(lpcmi->lpVerb) > FCIDM_SHVIEWLAST)
+    {
+        TRACE("Invalid Verb %x\n",LOWORD(lpcmi->lpVerb));
+        return E_INVALIDARG;
+    }
+
+    if (HIWORD(lpcmi->lpVerb) == 0)
+    {
+        switch(LOWORD(lpcmi->lpVerb-This->menu.verb_offset))
+        {
+        case FCIDM_SHVIEW_EXPLORE:
+            TRACE("Verb FCIDM_SHVIEW_EXPLORE\n");
+            DoOpenExplore(This, lpcmi->hwnd, "explore");
+            break;
+        case FCIDM_SHVIEW_OPEN:
+            TRACE("Verb FCIDM_SHVIEW_OPEN\n");
+            DoOpenExplore(This, lpcmi->hwnd, "open");
+            break;
+        case FCIDM_SHVIEW_RENAME:
+        {
+            IShellBrowser *browser;
+
+            /* get the active IShellView */
+            browser = (IShellBrowser*)SendMessageA(lpcmi->hwnd, CWM_GETISHELLBROWSER, 0, 0);
+            if (browser)
+            {
+                IShellView *view;
+
+                if(SUCCEEDED(IShellBrowser_QueryActiveShellView(browser, &view)))
+                {
+                    TRACE("(shellview=%p)\n", view);
+                    IShellView_SelectItem(view, This->apidl[0],
+                         SVSI_DESELECTOTHERS|SVSI_EDIT|SVSI_ENSUREVISIBLE|SVSI_FOCUSED|SVSI_SELECT);
+                    IShellView_Release(view);
+                }
+            }
+            break;
+        }
+        case FCIDM_SHVIEW_DELETE:
+            TRACE("Verb FCIDM_SHVIEW_DELETE\n");
+            DoDelete(This);
+            break;
+        case FCIDM_SHVIEW_COPY:
+            TRACE("Verb FCIDM_SHVIEW_COPY\n");
+            DoCopyOrCut(This, lpcmi->hwnd, FALSE);
+            break;
+        case FCIDM_SHVIEW_CUT:
+            TRACE("Verb FCIDM_SHVIEW_CUT\n");
+            DoCopyOrCut(This, lpcmi->hwnd, TRUE);
+            break;
+        case FCIDM_SHVIEW_PROPERTIES:
+            TRACE("Verb FCIDM_SHVIEW_PROPERTIES\n");
+            DoOpenProperties(This, lpcmi->hwnd);
+            break;
+        default:
+            FIXME("Unhandled Verb %xl\n",LOWORD(lpcmi->lpVerb)-This->menu.verb_offset);
+            return E_INVALIDARG;
+        }
+    }
+    else
+    {
+        TRACE("Verb is %s\n",debugstr_a(lpcmi->lpVerb));
+        if (strcmp(lpcmi->lpVerb,"delete")==0)
+            DoDelete(This);
+        else if (strcmp(lpcmi->lpVerb,"properties")==0)
+            DoOpenProperties(This, lpcmi->hwnd);
+        else {
+            FIXME("Unhandled string verb %s\n",debugstr_a(lpcmi->lpVerb));
+            return E_FAIL;
+        }
+    }
+    return S_OK;
+}
+
+static HRESULT WINAPI ItemMenu_GetCommandString(
+	IContextMenu2 *iface,
+	UINT_PTR idCommand,
+	UINT uFlags,
+	UINT* lpReserved,
+	LPSTR lpszName,
+	UINT uMaxNameLen)
+{
+	ItemMenu *This = impl_from_IContextMenu2_Item(iface);
+
+	HRESULT  hr = E_INVALIDARG;
+
+	TRACE("(%p)->(idcom=%lx flags=%x %p name=%p len=%x)\n",This, idCommand, uFlags, lpReserved, lpszName, uMaxNameLen);
+
+	switch(uFlags)
+	{
+	  case GCS_HELPTEXTA:
+	  case GCS_HELPTEXTW:
+	    hr = E_NOTIMPL;
+	    break;
+
+	  case GCS_VERBA:
+	    switch(idCommand-This->menu.verb_offset)
+	    {
+	    case FCIDM_SHVIEW_RENAME:
+	        strcpy(lpszName, "rename");
+	        hr = S_OK;
+	        break;
+	    }
+	    break;
+
+	     /* NT 4.0 with IE 3.0x or no IE will always call This with GCS_VERBW. In This
+	     case, you need to do the lstrcpyW to the pointer passed.*/
+	  case GCS_VERBW:
+	    switch(idCommand-This->menu.verb_offset)
+	    {
+	    case FCIDM_SHVIEW_RENAME:
+                MultiByteToWideChar( CP_ACP, 0, "rename", -1, (LPWSTR)lpszName, uMaxNameLen );
+	        hr = S_OK;
+	        break;
+	    }
+	    break;
+
+	  case GCS_VALIDATEA:
+	  case GCS_VALIDATEW:
+	    hr = S_OK;
+	    break;
+	}
+	TRACE("-- (%p)->(name=%s)\n",This, lpszName);
+	return hr;
+}
+
+/**************************************************************************
+* NOTES
+*  should be only in IContextMenu2 and IContextMenu3
+*  is nevertheless called from word95
+*/
+static HRESULT WINAPI ItemMenu_HandleMenuMsg(
+	IContextMenu2 *iface,
+	UINT uMsg,
+	WPARAM wParam,
+	LPARAM lParam)
+{
+	ItemMenu *This = impl_from_IContextMenu2_Item(iface);
+
+	TRACE("(%p)->(msg=%x wp=%lx lp=%lx)\n",This, uMsg, wParam, lParam);
+
+	return E_NOTIMPL;
+}
+
+static const IContextMenu2Vtbl ItemContextMenuVtbl =
+{
+    ItemMenu_QueryInterface,
+    ItemMenu_AddRef,
+    ItemMenu_Release,
+    ItemMenu_QueryContextMenu,
+    ItemMenu_InvokeCommand,
+    ItemMenu_GetCommandString,
+    ItemMenu_HandleMenuMsg
+};
+
+IContextMenu2 *ItemMenu_Constructor(IShellFolder *parent, LPCITEMIDLIST pidl, const LPCITEMIDLIST *apidl, UINT cidl)
+{	ItemMenu* cm;
+	UINT  u;
+
+	cm = HeapAlloc(GetProcessHeap(), 0, sizeof(ItemMenu));
+	cm->menu.IContextMenu2_iface.lpVtbl = &ItemContextMenuVtbl;
+	cm->menu.ref = 1;
+	cm->menu.verb_offset = 0;
+	cm->menu.parent = parent;
+
+	cm->pidl = ILClone(pidl);
+
+	if (parent) IShellFolder_AddRef(parent);
+
+	cm->apidl = _ILCopyaPidl(apidl, cidl);
+	cm->cidl = cidl;
+
+	cm->bAllValues = 1;
+	for(u = 0; u < cidl; u++)
+	  cm->bAllValues &= (_ILIsValue(apidl[u]) ? 1 : 0);
+
+	TRACE("(%p)\n",cm);
+
+	return &cm->menu.IContextMenu2_iface;
+}
+
+/* Background menu implementation */
+static HRESULT WINAPI BackgroundMenu_QueryInterface(IContextMenu2 *iface, REFIID riid, void **ppvObj)
+{
+    BackgroundMenu *This = impl_from_IContextMenu2_Back(iface);
+
+    TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppvObj);
+
+    *ppvObj = NULL;
+
+    if(IsEqualIID(riid, &IID_IUnknown) ||
+       IsEqualIID(riid, &IID_IContextMenu) ||
+       IsEqualIID(riid, &IID_IContextMenu2))
+    {
+        *ppvObj = This;
+    }
+    else if(IsEqualIID(riid, &IID_IShellExtInit))  /*IShellExtInit*/
+    {
+        FIXME("-- LPSHELLEXTINIT pointer requested\n");
+    }
+
+    if(*ppvObj)
+    {
+	IUnknown_AddRef((IUnknown*)*ppvObj);
+	TRACE("-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj);
+	return S_OK;
+    }
+
+    TRACE("-- Interface: E_NOINTERFACE\n");
+    return E_NOINTERFACE;
+}
+
+static ULONG WINAPI BackgroundMenu_AddRef(IContextMenu2 *iface)
+{
+    BackgroundMenu *This = impl_from_IContextMenu2_Back(iface);
+    ULONG ref = InterlockedIncrement(&This->menu.ref);
+    TRACE("(%p)->(%u)\n", This, ref);
+    return ref;
+}
+
+static ULONG WINAPI BackgroundMenu_Release(IContextMenu2 *iface)
+{
+    BackgroundMenu *This = impl_from_IContextMenu2_Back(iface);
+    ULONG ref = InterlockedDecrement(&This->menu.ref);
+
+    TRACE("(%p)->(%u)\n", This, ref);
+
+    if (!ref)
+    {
+        if (This->menu.parent)
+            IShellFolder_Release(This->menu.parent);
+
+        HeapFree(GetProcessHeap(), 0, This);
+    }
+
+    return ref;
+}
+
+static HRESULT WINAPI BackgroundMenu_QueryContextMenu(
+	IContextMenu2 *iface,
+	HMENU hMenu,
+	UINT indexMenu,
+	UINT idCmdFirst,
+	UINT idCmdLast,
+	UINT uFlags)
+{
+    BackgroundMenu *This = impl_from_IContextMenu2_Back(iface);
+    HMENU hMyMenu;
+    UINT idMax;
+    HRESULT hr;
+
+    TRACE("(%p)->(hmenu=%p indexmenu=%x cmdfirst=%x cmdlast=%x flags=%x )\n",
+          This, hMenu, indexMenu, idCmdFirst, idCmdLast, uFlags);
+
+    This->menu.verb_offset = idCmdFirst;
+
+    hMyMenu = LoadMenuA(shell32_hInstance, "MENU_002");
+    if (uFlags & CMF_DEFAULTONLY)
+    {
+        HMENU ourMenu = GetSubMenu(hMyMenu,0);
+        UINT oldDef = GetMenuDefaultItem(hMenu,TRUE,GMDI_USEDISABLED);
+        UINT newDef = GetMenuDefaultItem(ourMenu,TRUE,GMDI_USEDISABLED);
+        if (newDef != oldDef)
+            SetMenuDefaultItem(hMenu,newDef,TRUE);
+        if (newDef!=0xFFFFFFFF)
+            hr =  MAKE_HRESULT(SEVERITY_SUCCESS, FACILITY_NULL, newDef+1);
+        else
+            hr =  MAKE_HRESULT(SEVERITY_SUCCESS, FACILITY_NULL, 0);
+    }
+    else
+    {
+        idMax = Shell_MergeMenus (hMenu, GetSubMenu(hMyMenu,0), indexMenu,
+                                  idCmdFirst, idCmdLast, MM_SUBMENUSHAVEIDS);
+        hr =  MAKE_HRESULT(SEVERITY_SUCCESS, FACILITY_NULL, idMax-idCmdFirst);
+    }
+    DestroyMenu(hMyMenu);
+
+    TRACE("(%p)->returning 0x%x\n",This,hr);
+    return hr;
+}
+
+static void DoNewFolder(BackgroundMenu *This, IShellView *psv)
+{
+	ISFHelper * psfhlp;
+	WCHAR wszName[MAX_PATH];
+
+	IShellFolder_QueryInterface(This->menu.parent, &IID_ISFHelper, (LPVOID*)&psfhlp);
+	if (psfhlp)
+	{
+	  LPITEMIDLIST pidl;
+	  ISFHelper_GetUniqueName(psfhlp, wszName, MAX_PATH);
+	  ISFHelper_AddFolder(psfhlp, 0, wszName, &pidl);
+
+	  if(psv)
+	  {
+	    /* if we are in a shellview do labeledit */
+	    IShellView_SelectItem(psv,
+                    pidl,(SVSI_DESELECTOTHERS | SVSI_EDIT | SVSI_ENSUREVISIBLE
+                    |SVSI_FOCUSED|SVSI_SELECT));
+	  }
+	  SHFree(pidl);
+
+	  ISFHelper_Release(psfhlp);
+	}
+}
+
+static BOOL DoPaste(BackgroundMenu *This)
+{
+	BOOL bSuccess = FALSE;
+	IDataObject * pda;
+
+	TRACE("\n");
+
+	if(SUCCEEDED(OleGetClipboard(&pda)))
+	{
+	  STGMEDIUM medium;
+	  FORMATETC formatetc;
+
+	  TRACE("pda=%p\n", pda);
+
+	  /* Set the FORMATETC structure*/
+	  InitFormatEtc(formatetc, RegisterClipboardFormatW(CFSTR_SHELLIDLISTW), TYMED_HGLOBAL);
+
+	  /* Get the pidls from IDataObject */
+	  if(SUCCEEDED(IDataObject_GetData(pda,&formatetc,&medium)))
+          {
+	    LPITEMIDLIST * apidl;
+	    LPITEMIDLIST pidl;
+	    IShellFolder *psfFrom = NULL, *psfDesktop;
+
+	    LPIDA lpcida = GlobalLock(medium.u.hGlobal);
+	    TRACE("cida=%p\n", lpcida);
+
+	    apidl = _ILCopyCidaToaPidl(&pidl, lpcida);
+
+	    /* bind to the source shellfolder */
+	    SHGetDesktopFolder(&psfDesktop);
+	    if(psfDesktop)
+	    {
+	      IShellFolder_BindToObject(psfDesktop, pidl, NULL, &IID_IShellFolder, (LPVOID*)&psfFrom);
+	      IShellFolder_Release(psfDesktop);
+	    }
+
+	    if (psfFrom)
+	    {
+	      /* get source and destination shellfolder */
+	      ISFHelper *psfhlpdst, *psfhlpsrc;
+	      IShellFolder_QueryInterface(This->menu.parent, &IID_ISFHelper, (LPVOID*)&psfhlpdst);
+	      IShellFolder_QueryInterface(psfFrom, &IID_ISFHelper, (LPVOID*)&psfhlpsrc);
+
+	      /* do the copy/move */
+	      if (psfhlpdst && psfhlpsrc)
+	      {
+	        ISFHelper_CopyItems(psfhlpdst, psfFrom, lpcida->cidl, (LPCITEMIDLIST*)apidl);
+		/* FIXME handle move
+		ISFHelper_DeleteItems(psfhlpsrc, lpcida->cidl, apidl);
+		*/
+	      }
+	      if(psfhlpdst) ISFHelper_Release(psfhlpdst);
+	      if(psfhlpsrc) ISFHelper_Release(psfhlpsrc);
+	      IShellFolder_Release(psfFrom);
+	    }
+
+	    _ILFreeaPidl(apidl, lpcida->cidl);
+	    SHFree(pidl);
+
+	    /* release the medium*/
+	    ReleaseStgMedium(&medium);
+	  }
+	  IDataObject_Release(pda);
+	}
+#if 0
+	HGLOBAL  hMem;
+
+	OpenClipboard(NULL);
+	hMem = GetClipboardData(CF_HDROP);
+
+	if(hMem)
+	{
+          char * pDropFiles = GlobalLock(hMem);
+	  if(pDropFiles)
+	  {
+	    int len, offset = sizeof(DROPFILESTRUCT);
+
+	    while( pDropFiles[offset] != 0)
+	    {
+	      len = strlen(pDropFiles + offset);
+	      TRACE("%s\n", pDropFiles + offset);
+	      offset += len+1;
+	    }
+	  }
+	  GlobalUnlock(hMem);
+	}
+	CloseClipboard();
+#endif
+	return bSuccess;
+}
+
+static HRESULT WINAPI BackgroundMenu_InvokeCommand(
+	IContextMenu2 *iface,
+	LPCMINVOKECOMMANDINFO lpcmi)
+{
+        BackgroundMenu *This = impl_from_IContextMenu2_Back(iface);
+        LPSHELLBROWSER lpSB;
+	LPSHELLVIEW lpSV = NULL;
+	HWND hWndSV = 0;
+
+	TRACE("(%p)->(invcom=%p verb=%p wnd=%p)\n",This,lpcmi,lpcmi->lpVerb, lpcmi->hwnd);
+
+	/* get the active IShellView */
+	if((lpSB = (LPSHELLBROWSER)SendMessageA(lpcmi->hwnd, CWM_GETISHELLBROWSER,0,0)))
+	{
+	  if(SUCCEEDED(IShellBrowser_QueryActiveShellView(lpSB, &lpSV)))
+	  {
+	    IShellView_GetWindow(lpSV, &hWndSV);
+	  }
+	}
+
+	  if(HIWORD(lpcmi->lpVerb))
+	  {
+	    TRACE("%s\n",lpcmi->lpVerb);
+
+	    if (! strcmp(lpcmi->lpVerb,CMDSTR_NEWFOLDERA))
+	    {
+                DoNewFolder(This, lpSV);
+	    }
+	    else if (! strcmp(lpcmi->lpVerb,CMDSTR_VIEWLISTA))
+	    {
+	      if(hWndSV) SendMessageA(hWndSV, WM_COMMAND, MAKEWPARAM(FCIDM_SHVIEW_LISTVIEW,0),0 );
+	    }
+	    else if (! strcmp(lpcmi->lpVerb,CMDSTR_VIEWDETAILSA))
+	    {
+	      if(hWndSV) SendMessageA(hWndSV, WM_COMMAND, MAKEWPARAM(FCIDM_SHVIEW_REPORTVIEW,0),0 );
+	    }
+	    else
+	    {
+	      FIXME("please report: unknown verb %s\n",lpcmi->lpVerb);
+	    }
+	  }
+	  else
+	  {
+	    switch(LOWORD(lpcmi->lpVerb)-This->menu.verb_offset)
+	    {
+	      case FCIDM_SHVIEW_REFRESH:
+	        if (lpSV) IShellView_Refresh(lpSV);
+	        break;
+
+	      case FCIDM_SHVIEW_NEWFOLDER:
+                DoNewFolder(This, lpSV);
+		break;
+
+	      case FCIDM_SHVIEW_INSERT:
+                DoPaste(This);
+	        break;
+
+	      case FCIDM_SHVIEW_PROPERTIES:
+		if (This->desktop) {
+		    ShellExecuteA(lpcmi->hwnd, "open", "rundll32.exe shell32.dll,Control_RunDLL desk.cpl", NULL, NULL, SW_SHOWNORMAL);
+		} else {
+		    FIXME("launch item properties dialog\n");
+		}
+		break;
+
+	      default:
+	        /* if it's an id just pass it to the parent shv */
+	        if (hWndSV) SendMessageA(hWndSV, WM_COMMAND, MAKEWPARAM(LOWORD(lpcmi->lpVerb), 0),0 );
+		break;
+	    }
+	  }
+
+        if (lpSV)
+	  IShellView_Release(lpSV);	/* QueryActiveShellView does AddRef */
+
+	return S_OK;
+}
+
+static HRESULT WINAPI BackgroundMenu_GetCommandString(
+	IContextMenu2 *iface,
+	UINT_PTR idCommand,
+	UINT uFlags,
+	UINT* lpReserved,
+	LPSTR lpszName,
+	UINT uMaxNameLen)
+{
+        BackgroundMenu *This = impl_from_IContextMenu2_Back(iface);
+
+	TRACE("(%p)->(idcom=%lx flags=%x %p name=%p len=%x)\n",This, idCommand, uFlags, lpReserved, lpszName, uMaxNameLen);
+
+	/* test the existence of the menu items, the file dialog enables
+	   the buttons according to this */
+	if (uFlags == GCS_VALIDATEA)
+	{
+	  if(HIWORD(idCommand))
+	  {
+	    if (!strcmp((LPSTR)idCommand, CMDSTR_VIEWLISTA) ||
+	        !strcmp((LPSTR)idCommand, CMDSTR_VIEWDETAILSA) ||
+	        !strcmp((LPSTR)idCommand, CMDSTR_NEWFOLDERA))
+	    {
+	      return S_OK;
+	    }
+	  }
+	}
+
+	FIXME("unknown command string\n");
+	return E_FAIL;
+}
+
+static HRESULT WINAPI BackgroundMenu_HandleMenuMsg(
+	IContextMenu2 *iface,
+	UINT uMsg,
+	WPARAM wParam,
+	LPARAM lParam)
+{
+    BackgroundMenu *This = impl_from_IContextMenu2_Back(iface);
+    FIXME("(%p)->(msg=%x wp=%lx lp=%lx)\n",This, uMsg, wParam, lParam);
+    return E_NOTIMPL;
+}
+
+static const IContextMenu2Vtbl BackgroundContextMenuVtbl =
+{
+    BackgroundMenu_QueryInterface,
+    BackgroundMenu_AddRef,
+    BackgroundMenu_Release,
+    BackgroundMenu_QueryContextMenu,
+    BackgroundMenu_InvokeCommand,
+    BackgroundMenu_GetCommandString,
+    BackgroundMenu_HandleMenuMsg
+};
+
+IContextMenu2 *BackgroundMenu_Constructor(IShellFolder *parent, BOOL desktop)
+{
+    BackgroundMenu *cm;
+
+    cm = HeapAlloc(GetProcessHeap(), 0, sizeof(*cm));
+    cm->menu.IContextMenu2_iface.lpVtbl = &BackgroundContextMenuVtbl;
+    cm->menu.ref = 1;
+    cm->menu.parent = parent;
+    cm->menu.verb_offset = 0;
+
+    cm->desktop = desktop;
+    if (parent) IShellFolder_AddRef(parent);
+
+    TRACE("(%p)->()\n", cm);
+    return &cm->menu.IContextMenu2_iface;
+}
diff --git a/dlls/shell32/shv_bg_cmenu.c b/dlls/shell32/shv_bg_cmenu.c
deleted file mode 100644
index c2c6f08..0000000
--- a/dlls/shell32/shv_bg_cmenu.c
+++ /dev/null
@@ -1,458 +0,0 @@
-/*
- *	IContextMenu
- *	ShellView Background Context Menu (shv_bg_cm)
- *
- *	Copyright 1999	Juergen Schmied <juergen.schmied@metronet.de>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- */
-#include <string.h>
-
-#define COBJMACROS
-#define NONAMELESSUNION
-#define NONAMELESSSTRUCT
-
-#include "wine/debug.h"
-
-#include "windef.h"
-#include "wingdi.h"
-#include "pidl.h"
-#include "shlobj.h"
-
-#include "shell32_main.h"
-#include "shellfolder.h"
-#include "undocshell.h"
-
-WINE_DEFAULT_DEBUG_CHANNEL(shell);
-
-/**************************************************************************
-*  IContextMenu Implementation
-*/
-typedef struct
-{
-    IContextMenu2           IContextMenu2_iface;
-    IShellFolder*           pSFParent;
-    LONG                    ref;
-    BOOL                    bDesktop;
-    UINT                    verb_offset;
-} BgCmImpl;
-
-static inline BgCmImpl *impl_from_IContextMenu2(IContextMenu2 *iface)
-{
-    return CONTAINING_RECORD(iface, BgCmImpl, IContextMenu2_iface);
-}
-
-/**************************************************************************
-*  ISVBgCm_fnQueryInterface
-*/
-static HRESULT WINAPI ISVBgCm_fnQueryInterface(IContextMenu2 *iface, REFIID riid, LPVOID *ppvObj)
-{
-        BgCmImpl *This = impl_from_IContextMenu2(iface);
-
-	TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_guid(riid),ppvObj);
-
-	*ppvObj = NULL;
-
-        if(IsEqualIID(riid, &IID_IUnknown) ||
-           IsEqualIID(riid, &IID_IContextMenu) ||
-           IsEqualIID(riid, &IID_IContextMenu2))
-	{
-	  *ppvObj = This;
-	}
-	else if(IsEqualIID(riid, &IID_IShellExtInit))  /*IShellExtInit*/
-	{
-	  FIXME("-- LPSHELLEXTINIT pointer requested\n");
-	}
-
-	if(*ppvObj)
-	{
-	  IUnknown_AddRef((IUnknown*)*ppvObj);
-	  TRACE("-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj);
-	  return S_OK;
-	}
-	TRACE("-- Interface: E_NOINTERFACE\n");
-	return E_NOINTERFACE;
-}
-
-/**************************************************************************
-*  ISVBgCm_fnAddRef
-*/
-static ULONG WINAPI ISVBgCm_fnAddRef(IContextMenu2 *iface)
-{
-        BgCmImpl *This = impl_from_IContextMenu2(iface);
-	ULONG refCount = InterlockedIncrement(&This->ref);
-
-	TRACE("(%p)->(count=%u)\n", This, refCount - 1);
-
-	return refCount;
-}
-
-/**************************************************************************
-*  ISVBgCm_fnRelease
-*/
-static ULONG WINAPI ISVBgCm_fnRelease(IContextMenu2 *iface)
-{
-        BgCmImpl *This = impl_from_IContextMenu2(iface);
-	ULONG refCount = InterlockedDecrement(&This->ref);
-
-	TRACE("(%p)->(count=%i)\n", This, refCount + 1);
-
-	if (!refCount)
-	{
-	  TRACE(" destroying IContextMenu(%p)\n",This);
-
-	  if(This->pSFParent)
-	    IShellFolder_Release(This->pSFParent);
-
-	  HeapFree(GetProcessHeap(),0,This);
-	}
-	return refCount;
-}
-
-/**************************************************************************
-* ISVBgCm_fnQueryContextMenu()
-*/
-
-static HRESULT WINAPI ISVBgCm_fnQueryContextMenu(
-	IContextMenu2 *iface,
-	HMENU hMenu,
-	UINT indexMenu,
-	UINT idCmdFirst,
-	UINT idCmdLast,
-	UINT uFlags)
-{
-    BgCmImpl *This = impl_from_IContextMenu2(iface);
-    HMENU hMyMenu;
-    UINT idMax;
-    HRESULT hr;
-
-    TRACE("(%p)->(hmenu=%p indexmenu=%x cmdfirst=%x cmdlast=%x flags=%x )\n",
-          This, hMenu, indexMenu, idCmdFirst, idCmdLast, uFlags);
-
-    This->verb_offset=idCmdFirst;
-
-    hMyMenu = LoadMenuA(shell32_hInstance, "MENU_002");
-    if (uFlags & CMF_DEFAULTONLY)
-    {
-        HMENU ourMenu = GetSubMenu(hMyMenu,0);
-        UINT oldDef = GetMenuDefaultItem(hMenu,TRUE,GMDI_USEDISABLED);
-        UINT newDef = GetMenuDefaultItem(ourMenu,TRUE,GMDI_USEDISABLED);
-        if (newDef != oldDef)
-            SetMenuDefaultItem(hMenu,newDef,TRUE);
-        if (newDef!=0xFFFFFFFF)
-            hr =  MAKE_HRESULT(SEVERITY_SUCCESS, FACILITY_NULL, newDef+1);
-        else
-            hr =  MAKE_HRESULT(SEVERITY_SUCCESS, FACILITY_NULL, 0);
-    }
-    else
-    {
-        idMax = Shell_MergeMenus (hMenu, GetSubMenu(hMyMenu,0), indexMenu,
-                                  idCmdFirst, idCmdLast, MM_SUBMENUSHAVEIDS);
-        hr =  MAKE_HRESULT(SEVERITY_SUCCESS, FACILITY_NULL, idMax-idCmdFirst);
-    }
-    DestroyMenu(hMyMenu);
-
-    TRACE("(%p)->returning 0x%x\n",This,hr);
-    return hr;
-}
-
-/**************************************************************************
-* DoNewFolder
-*/
-static void DoNewFolder(
-        BgCmImpl *This,
-	IShellView *psv)
-{
-	ISFHelper * psfhlp;
-	WCHAR wszName[MAX_PATH];
-
-	IShellFolder_QueryInterface(This->pSFParent, &IID_ISFHelper, (LPVOID*)&psfhlp);
-	if (psfhlp)
-	{
-	  LPITEMIDLIST pidl;
-	  ISFHelper_GetUniqueName(psfhlp, wszName, MAX_PATH);
-	  ISFHelper_AddFolder(psfhlp, 0, wszName, &pidl);
-
-	  if(psv)
-	  {
-	    /* if we are in a shellview do labeledit */
-	    IShellView_SelectItem(psv,
-                    pidl,(SVSI_DESELECTOTHERS | SVSI_EDIT | SVSI_ENSUREVISIBLE
-                    |SVSI_FOCUSED|SVSI_SELECT));
-	  }
-	  SHFree(pidl);
-
-	  ISFHelper_Release(psfhlp);
-	}
-}
-
-/**************************************************************************
-* DoPaste
-*/
-static BOOL DoPaste(
-        BgCmImpl *This)
-{
-	BOOL bSuccess = FALSE;
-	IDataObject * pda;
-
-	TRACE("\n");
-
-	if(SUCCEEDED(OleGetClipboard(&pda)))
-	{
-	  STGMEDIUM medium;
-	  FORMATETC formatetc;
-
-	  TRACE("pda=%p\n", pda);
-
-	  /* Set the FORMATETC structure*/
-	  InitFormatEtc(formatetc, RegisterClipboardFormatW(CFSTR_SHELLIDLISTW), TYMED_HGLOBAL);
-
-	  /* Get the pidls from IDataObject */
-	  if(SUCCEEDED(IDataObject_GetData(pda,&formatetc,&medium)))
-          {
-	    LPITEMIDLIST * apidl;
-	    LPITEMIDLIST pidl;
-	    IShellFolder *psfFrom = NULL, *psfDesktop;
-
-	    LPIDA lpcida = GlobalLock(medium.u.hGlobal);
-	    TRACE("cida=%p\n", lpcida);
-
-	    apidl = _ILCopyCidaToaPidl(&pidl, lpcida);
-
-	    /* bind to the source shellfolder */
-	    SHGetDesktopFolder(&psfDesktop);
-	    if(psfDesktop)
-	    {
-	      IShellFolder_BindToObject(psfDesktop, pidl, NULL, &IID_IShellFolder, (LPVOID*)&psfFrom);
-	      IShellFolder_Release(psfDesktop);
-	    }
-
-	    if (psfFrom)
-	    {
-	      /* get source and destination shellfolder */
-	      ISFHelper *psfhlpdst, *psfhlpsrc;
-	      IShellFolder_QueryInterface(This->pSFParent, &IID_ISFHelper, (LPVOID*)&psfhlpdst);
-	      IShellFolder_QueryInterface(psfFrom, &IID_ISFHelper, (LPVOID*)&psfhlpsrc);
-
-	      /* do the copy/move */
-	      if (psfhlpdst && psfhlpsrc)
-	      {
-	        ISFHelper_CopyItems(psfhlpdst, psfFrom, lpcida->cidl, (LPCITEMIDLIST*)apidl);
-		/* FIXME handle move
-		ISFHelper_DeleteItems(psfhlpsrc, lpcida->cidl, apidl);
-		*/
-	      }
-	      if(psfhlpdst) ISFHelper_Release(psfhlpdst);
-	      if(psfhlpsrc) ISFHelper_Release(psfhlpsrc);
-	      IShellFolder_Release(psfFrom);
-	    }
-
-	    _ILFreeaPidl(apidl, lpcida->cidl);
-	    SHFree(pidl);
-
-	    /* release the medium*/
-	    ReleaseStgMedium(&medium);
-	  }
-	  IDataObject_Release(pda);
-	}
-#if 0
-	HGLOBAL  hMem;
-
-	OpenClipboard(NULL);
-	hMem = GetClipboardData(CF_HDROP);
-
-	if(hMem)
-	{
-          char * pDropFiles = GlobalLock(hMem);
-	  if(pDropFiles)
-	  {
-	    int len, offset = sizeof(DROPFILESTRUCT);
-
-	    while( pDropFiles[offset] != 0)
-	    {
-	      len = strlen(pDropFiles + offset);
-	      TRACE("%s\n", pDropFiles + offset);
-	      offset += len+1;
-	    }
-	  }
-	  GlobalUnlock(hMem);
-	}
-	CloseClipboard();
-#endif
-	return bSuccess;
-}
-
-/**************************************************************************
-* ISVBgCm_fnInvokeCommand()
-*/
-static HRESULT WINAPI ISVBgCm_fnInvokeCommand(
-	IContextMenu2 *iface,
-	LPCMINVOKECOMMANDINFO lpcmi)
-{
-        BgCmImpl *This = impl_from_IContextMenu2(iface);
-        LPSHELLBROWSER lpSB;
-	LPSHELLVIEW lpSV = NULL;
-	HWND hWndSV = 0;
-
-	TRACE("(%p)->(invcom=%p verb=%p wnd=%p)\n",This,lpcmi,lpcmi->lpVerb, lpcmi->hwnd);
-
-	/* get the active IShellView */
-	if((lpSB = (LPSHELLBROWSER)SendMessageA(lpcmi->hwnd, CWM_GETISHELLBROWSER,0,0)))
-	{
-	  if(SUCCEEDED(IShellBrowser_QueryActiveShellView(lpSB, &lpSV)))
-	  {
-	    IShellView_GetWindow(lpSV, &hWndSV);
-	  }
-	}
-
-	  if(HIWORD(lpcmi->lpVerb))
-	  {
-	    TRACE("%s\n",lpcmi->lpVerb);
-
-	    if (! strcmp(lpcmi->lpVerb,CMDSTR_NEWFOLDERA))
-	    {
-                DoNewFolder(This, lpSV);
-	    }
-	    else if (! strcmp(lpcmi->lpVerb,CMDSTR_VIEWLISTA))
-	    {
-	      if(hWndSV) SendMessageA(hWndSV, WM_COMMAND, MAKEWPARAM(FCIDM_SHVIEW_LISTVIEW,0),0 );
-	    }
-	    else if (! strcmp(lpcmi->lpVerb,CMDSTR_VIEWDETAILSA))
-	    {
-	      if(hWndSV) SendMessageA(hWndSV, WM_COMMAND, MAKEWPARAM(FCIDM_SHVIEW_REPORTVIEW,0),0 );
-	    }
-	    else
-	    {
-	      FIXME("please report: unknown verb %s\n",lpcmi->lpVerb);
-	    }
-	  }
-	  else
-	  {
-	    switch(LOWORD(lpcmi->lpVerb)-This->verb_offset)
-	    {
-	      case FCIDM_SHVIEW_REFRESH:
-	        if (lpSV) IShellView_Refresh(lpSV);
-	        break;
-
-	      case FCIDM_SHVIEW_NEWFOLDER:
-                DoNewFolder(This, lpSV);
-		break;
-
-	      case FCIDM_SHVIEW_INSERT:
-                DoPaste(This);
-	        break;
-
-	      case FCIDM_SHVIEW_PROPERTIES:
-		if (This->bDesktop) {
-		    ShellExecuteA(lpcmi->hwnd, "open", "rundll32.exe shell32.dll,Control_RunDLL desk.cpl", NULL, NULL, SW_SHOWNORMAL);
-		} else {
-		    FIXME("launch item properties dialog\n");
-		}
-		break;
-
-	      default:
-	        /* if it's an id just pass it to the parent shv */
-	        if (hWndSV) SendMessageA(hWndSV, WM_COMMAND, MAKEWPARAM(LOWORD(lpcmi->lpVerb), 0),0 );
-		break;
-	    }
-	  }
-
-        if (lpSV)
-	  IShellView_Release(lpSV);	/* QueryActiveShellView does AddRef */
-
-	return S_OK;
-}
-
-/**************************************************************************
- *  ISVBgCm_fnGetCommandString()
- *
- */
-static HRESULT WINAPI ISVBgCm_fnGetCommandString(
-	IContextMenu2 *iface,
-	UINT_PTR idCommand,
-	UINT uFlags,
-	UINT* lpReserved,
-	LPSTR lpszName,
-	UINT uMaxNameLen)
-{
-        BgCmImpl *This = impl_from_IContextMenu2(iface);
-
-	TRACE("(%p)->(idcom=%lx flags=%x %p name=%p len=%x)\n",This, idCommand, uFlags, lpReserved, lpszName, uMaxNameLen);
-
-	/* test the existence of the menu items, the file dialog enables
-	   the buttons according to this */
-	if (uFlags == GCS_VALIDATEA)
-	{
-	  if(HIWORD(idCommand))
-	  {
-	    if (!strcmp((LPSTR)idCommand, CMDSTR_VIEWLISTA) ||
-	        !strcmp((LPSTR)idCommand, CMDSTR_VIEWDETAILSA) ||
-	        !strcmp((LPSTR)idCommand, CMDSTR_NEWFOLDERA))
-	    {
-	      return S_OK;
-	    }
-	  }
-	}
-
-	FIXME("unknown command string\n");
-	return E_FAIL;
-}
-
-/**************************************************************************
-* ISVBgCm_fnHandleMenuMsg()
-*/
-static HRESULT WINAPI ISVBgCm_fnHandleMenuMsg(
-	IContextMenu2 *iface,
-	UINT uMsg,
-	WPARAM wParam,
-	LPARAM lParam)
-{
-        BgCmImpl *This = impl_from_IContextMenu2(iface);
-
-	FIXME("(%p)->(msg=%x wp=%lx lp=%lx)\n",This, uMsg, wParam, lParam);
-
-	return E_NOTIMPL;
-}
-
-/**************************************************************************
-* IContextMenu2 VTable
-*
-*/
-static const IContextMenu2Vtbl BackgroundContextMenuVtbl =
-{
-	ISVBgCm_fnQueryInterface,
-	ISVBgCm_fnAddRef,
-	ISVBgCm_fnRelease,
-	ISVBgCm_fnQueryContextMenu,
-	ISVBgCm_fnInvokeCommand,
-	ISVBgCm_fnGetCommandString,
-	ISVBgCm_fnHandleMenuMsg
-};
-
-IContextMenu2 *ISvBgCm_Constructor(IShellFolder *pSFParent, BOOL bDesktop)
-{
-    BgCmImpl *cm;
-
-    cm = HeapAlloc(GetProcessHeap(), 0, sizeof(*cm));
-    cm->IContextMenu2_iface.lpVtbl = &BackgroundContextMenuVtbl;
-    cm->ref = 1;
-    cm->pSFParent = pSFParent;
-    cm->bDesktop = bDesktop;
-    cm->verb_offset = 0;
-    if(pSFParent) IShellFolder_AddRef(pSFParent);
-
-    TRACE("(%p)->()\n", cm);
-    return &cm->IContextMenu2_iface;
-}
diff --git a/dlls/shell32/shv_item_cmenu.c b/dlls/shell32/shv_item_cmenu.c
deleted file mode 100644
index 06169c5..0000000
--- a/dlls/shell32/shv_item_cmenu.c
+++ /dev/null
@@ -1,623 +0,0 @@
-/*
- *	IContextMenu for items in the shellview
- *
- * Copyright 1998, 2000 Juergen Schmied <juergen.schmied@debitel.net>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include <string.h>
-
-#define COBJMACROS
-#define NONAMELESSUNION
-#define NONAMELESSSTRUCT
-
-#include "winerror.h"
-#include "wine/debug.h"
-
-#include "windef.h"
-#include "wingdi.h"
-#include "pidl.h"
-#include "undocshell.h"
-#include "shlobj.h"
-#include "winreg.h"
-#include "prsht.h"
-
-#include "shell32_main.h"
-#include "shellfolder.h"
-
-#include "shresdef.h"
-
-WINE_DEFAULT_DEBUG_CHANNEL(shell);
-
-
-typedef struct
-{
-    IContextMenu2 IContextMenu2_iface;
-    LONG ref;
-    IShellFolder* parent;
-    UINT verb_offset;
-} ContextMenu;
-
-/**************************************************************************
-*  IContextMenu Implementation
-*/
-typedef struct
-{
-    ContextMenu     menu;
-
-    LPITEMIDLIST    pidl;       /* root pidl */
-    LPITEMIDLIST    *apidl;     /* array of child pidls */
-    UINT            cidl;
-    BOOL            bAllValues;
-} ItemCmImpl;
-
-static inline ItemCmImpl *impl_from_IContextMenu2(IContextMenu2 *iface)
-{
-    return CONTAINING_RECORD(iface, ItemCmImpl, menu.IContextMenu2_iface);
-}
-
-/**************************************************************************
-* ISvItemCm_CanRenameItems()
-*/
-static BOOL ISvItemCm_CanRenameItems(ItemCmImpl *This)
-{
-    DWORD attr;
-
-    TRACE("(%p)\n", This);
-
-    /* can't rename more than one item at a time*/
-    if (!This->apidl || This->cidl > 1) return FALSE;
-
-    attr = SFGAO_CANRENAME;
-    IShellFolder_GetAttributesOf(This->menu.parent, 1, (LPCITEMIDLIST*)This->apidl, &attr);
-    return attr & SFGAO_CANRENAME;
-}
-
-/**************************************************************************
-*  ISvItemCm_fnQueryInterface
-*/
-static HRESULT WINAPI ISvItemCm_fnQueryInterface(IContextMenu2 *iface, REFIID riid, LPVOID *ppvObj)
-{
-	ItemCmImpl *This = impl_from_IContextMenu2(iface);
-
-	TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_guid(riid),ppvObj);
-
-	*ppvObj = NULL;
-
-        if(IsEqualIID(riid, &IID_IUnknown) ||
-           IsEqualIID(riid, &IID_IContextMenu) ||
-           IsEqualIID(riid, &IID_IContextMenu2))
-	{
-	  *ppvObj = This;
-	}
-	else if(IsEqualIID(riid, &IID_IShellExtInit))  /*IShellExtInit*/
-	{
-	  FIXME("-- LPSHELLEXTINIT pointer requested\n");
-	}
-
-	if(*ppvObj)
-	{
-	  IUnknown_AddRef((IUnknown*)*ppvObj);
-	  TRACE("-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj);
-	  return S_OK;
-	}
-	TRACE("-- Interface: E_NOINTERFACE\n");
-	return E_NOINTERFACE;
-}
-
-/**************************************************************************
-*  ISvItemCm_fnAddRef
-*/
-static ULONG WINAPI ISvItemCm_fnAddRef(IContextMenu2 *iface)
-{
-	ItemCmImpl *This = impl_from_IContextMenu2(iface);
-	ULONG refCount = InterlockedIncrement(&This->menu.ref);
-
-	TRACE("(%p)->(count=%u)\n", This, refCount - 1);
-
-	return refCount;
-}
-
-/**************************************************************************
-*  ISvItemCm_fnRelease
-*/
-static ULONG WINAPI ISvItemCm_fnRelease(IContextMenu2 *iface)
-{
-	ItemCmImpl *This = impl_from_IContextMenu2(iface);
-	ULONG refCount = InterlockedDecrement(&This->menu.ref);
-
-	TRACE("(%p)->(count=%i)\n", This, refCount + 1);
-
-	if (!refCount)
-	{
-	  TRACE(" destroying IContextMenu(%p)\n",This);
-
-	  if(This->menu.parent)
-	    IShellFolder_Release(This->menu.parent);
-
-	  SHFree(This->pidl);
-
-	  /*make sure the pidl is freed*/
-	  _ILFreeaPidl(This->apidl, This->cidl);
-
-	  HeapFree(GetProcessHeap(),0,This);
-	}
-	return refCount;
-}
-
-/**************************************************************************
-* ISvItemCm_fnQueryContextMenu()
-*/
-static HRESULT WINAPI ISvItemCm_fnQueryContextMenu(
-	IContextMenu2 *iface,
-	HMENU hmenu,
-	UINT indexMenu,
-	UINT idCmdFirst,
-	UINT idCmdLast,
-	UINT uFlags)
-{
-    ItemCmImpl *This = impl_from_IContextMenu2(iface);
-    INT uIDMax;
-
-    TRACE("(%p)->(hmenu=%p indexmenu=%x cmdfirst=%x cmdlast=%x flags=%x )\n",This, hmenu, indexMenu, idCmdFirst, idCmdLast, uFlags);
-
-    This->menu.verb_offset=idCmdFirst;
-
-    if(!(CMF_DEFAULTONLY & uFlags) && This->cidl>0)
-    {
-        HMENU hmenures = LoadMenuW(shell32_hInstance, MAKEINTRESOURCEW(MENU_SHV_FILE));
-
-        if(uFlags & CMF_EXPLORE)
-            RemoveMenu(hmenures, FCIDM_SHVIEW_OPEN, MF_BYCOMMAND);
-
-        uIDMax = Shell_MergeMenus(hmenu, GetSubMenu(hmenures, 0), indexMenu, idCmdFirst, idCmdLast, MM_SUBMENUSHAVEIDS);
-
-        DestroyMenu(hmenures);
-
-        if(This->bAllValues)
-        {
-            MENUITEMINFOW mi;
-            WCHAR str[255];
-            mi.cbSize = sizeof(mi);
-            mi.fMask = MIIM_ID | MIIM_STRING | MIIM_FTYPE;
-            mi.dwTypeData = str;
-            mi.cch = 255;
-            GetMenuItemInfoW(hmenu, FCIDM_SHVIEW_EXPLORE, MF_BYCOMMAND, &mi);
-            RemoveMenu(hmenu, FCIDM_SHVIEW_EXPLORE, MF_BYCOMMAND);
-
-            mi.cbSize = sizeof(mi);
-            mi.fMask = MIIM_ID | MIIM_TYPE | MIIM_STATE;
-            mi.dwTypeData = str;
-            mi.fState = MFS_ENABLED;
-            mi.wID = FCIDM_SHVIEW_EXPLORE;
-            mi.fType = MFT_STRING;
-            InsertMenuItemW(hmenu, (uFlags & CMF_EXPLORE) ? 1 : 2, MF_BYPOSITION, &mi);
-        }
-
-        SetMenuDefaultItem(hmenu, 0, MF_BYPOSITION);
-
-        if(uFlags & ~CMF_CANRENAME)
-            RemoveMenu(hmenu, FCIDM_SHVIEW_RENAME, MF_BYCOMMAND);
-        else
-            EnableMenuItem(hmenu, FCIDM_SHVIEW_RENAME, MF_BYCOMMAND | ISvItemCm_CanRenameItems(This) ? MFS_ENABLED : MFS_DISABLED);
-
-        return MAKE_HRESULT(SEVERITY_SUCCESS, 0, uIDMax-idCmdFirst);
-    }
-    return MAKE_HRESULT(SEVERITY_SUCCESS, 0, 0);
-}
-
-/**************************************************************************
-* DoOpenExplore
-*
-*  for folders only
-*/
-
-static void DoOpenExplore(ItemCmImpl *This, HWND hwnd, LPCSTR verb)
-{
-	UINT i, bFolderFound = FALSE;
-	LPITEMIDLIST	pidlFQ;
-	SHELLEXECUTEINFOA	sei;
-
-	/* Find the first item in the list that is not a value. These commands
-	    should never be invoked if there isn't at least one folder item in the list.*/
-
-	for(i = 0; i<This->cidl; i++)
-	{
-	  if(!_ILIsValue(This->apidl[i]))
-	  {
-	    bFolderFound = TRUE;
-	    break;
-	  }
-	}
-
-	if (!bFolderFound) return;
-
-	pidlFQ = ILCombine(This->pidl, This->apidl[i]);
-
-	ZeroMemory(&sei, sizeof(sei));
-	sei.cbSize = sizeof(sei);
-	sei.fMask = SEE_MASK_IDLIST | SEE_MASK_CLASSNAME;
-	sei.lpIDList = pidlFQ;
-	sei.lpClass = "Folder";
-	sei.hwnd = hwnd;
-	sei.nShow = SW_SHOWNORMAL;
-	sei.lpVerb = verb;
-	ShellExecuteExA(&sei);
-	SHFree(pidlFQ);
-}
-
-/**************************************************************************
- * DoDelete
- *
- * deletes the currently selected items
- */
-static void DoDelete(ItemCmImpl *This)
-{
-	ISFHelper * psfhlp;
-
-	IShellFolder_QueryInterface(This->menu.parent, &IID_ISFHelper, (LPVOID*)&psfhlp);
-	if (psfhlp)
-	{
-	  ISFHelper_DeleteItems(psfhlp, This->cidl, (LPCITEMIDLIST *)This->apidl);
-	  ISFHelper_Release(psfhlp);
-	}
-}
-
-/**************************************************************************
- * DoCopyOrCut
- *
- * copies the currently selected items into the clipboard
- */
-static BOOL DoCopyOrCut(ItemCmImpl *This, HWND hwnd, BOOL bCut)
-{
-	LPSHELLBROWSER	lpSB;
-	LPSHELLVIEW	lpSV;
-	LPDATAOBJECT    lpDo;
-
-	TRACE("(%p)->(wnd=%p,bCut=0x%08x)\n",This, hwnd, bCut);
-
-	/* get the active IShellView */
-	if ((lpSB = (LPSHELLBROWSER)SendMessageA(hwnd, CWM_GETISHELLBROWSER,0,0)))
-	{
-	  if (SUCCEEDED(IShellBrowser_QueryActiveShellView(lpSB, &lpSV)))
-	  {
-	    if (SUCCEEDED(IShellView_GetItemObject(lpSV, SVGIO_SELECTION, &IID_IDataObject, (LPVOID*)&lpDo)))
-	    {
-	      OleSetClipboard(lpDo);
-	      IDataObject_Release(lpDo);
-	    }
-	    IShellView_Release(lpSV);
-	  }
-	}
-	return TRUE;
-}
-
-/**************************************************************************
- * Properties_AddPropSheetCallback
- *
- * Used by DoOpenProperties through SHCreatePropSheetExtArrayEx to add
- * propertysheet pages from shell extensions.
- */
-static BOOL CALLBACK Properties_AddPropSheetCallback(HPROPSHEETPAGE hpage, LPARAM lparam)
-{
-	LPPROPSHEETHEADERW psh = (LPPROPSHEETHEADERW) lparam;
-	psh->u3.phpage[psh->nPages++] = hpage;
-
-	return TRUE;
-}
-
-/**************************************************************************
- * DoOpenProperties
- */
-static void DoOpenProperties(ItemCmImpl *This, HWND hwnd)
-{
-	static const UINT MAX_PROP_PAGES = 99;
-	static const WCHAR wszFolder[] = {'F','o','l','d','e','r', 0};
-	static const WCHAR wszFiletypeAll[] = {'*',0};
-	LPSHELLFOLDER lpDesktopSF;
-	LPSHELLFOLDER lpSF;
-	LPDATAOBJECT lpDo;
-	WCHAR wszFiletype[MAX_PATH];
-	WCHAR wszFilename[MAX_PATH];
-	PROPSHEETHEADERW psh;
-	HPROPSHEETPAGE hpages[MAX_PROP_PAGES];
-	HPSXA hpsxa;
-	UINT ret;
-
-	TRACE("(%p)->(wnd=%p)\n", This, hwnd);
-
-	ZeroMemory(&psh, sizeof(PROPSHEETHEADERW));
-	psh.dwSize = sizeof (PROPSHEETHEADERW);
-	psh.hwndParent = hwnd;
-	psh.dwFlags = PSH_PROPTITLE;
-	psh.nPages = 0;
-	psh.u3.phpage = hpages;
-	psh.u2.nStartPage = 0;
-
-	_ILSimpleGetTextW(This->apidl[0], (LPVOID)wszFilename, MAX_PATH);
-	psh.pszCaption = (LPCWSTR)wszFilename;
-
-	/* Find out where to look for the shell extensions */
-	if (_ILIsValue(This->apidl[0]))
-	{
-	    char sTemp[64];
-	    sTemp[0] = 0;
-	    if (_ILGetExtension(This->apidl[0], sTemp, 64))
-	    {
-		HCR_MapTypeToValueA(sTemp, sTemp, 64, TRUE);
-		MultiByteToWideChar(CP_ACP, 0, sTemp, -1, wszFiletype, MAX_PATH);
-	    }
-	    else
-	    {
-		wszFiletype[0] = 0;
-	    }
-	}
-	else if (_ILIsFolder(This->apidl[0]))
-	{
-	    lstrcpynW(wszFiletype, wszFolder, 64);
-	}
-	else if (_ILIsSpecialFolder(This->apidl[0]))
-	{
-	    LPGUID folderGUID;
-	    static const WCHAR wszclsid[] = {'C','L','S','I','D','\\', 0};
-	    folderGUID = _ILGetGUIDPointer(This->apidl[0]);
-	    lstrcpyW(wszFiletype, wszclsid);
-	    StringFromGUID2(folderGUID, &wszFiletype[6], MAX_PATH - 6);
-	}
-	else
-	{
-	    FIXME("Requested properties for unknown type.\n");
-	    return;
-	}
-
-	/* Get a suitable DataObject for accessing the files */
-	SHGetDesktopFolder(&lpDesktopSF);
-	if (_ILIsPidlSimple(This->pidl))
-	{
-	    ret = IShellFolder_GetUIObjectOf(lpDesktopSF, hwnd, This->cidl, (LPCITEMIDLIST*)This->apidl,
-					     &IID_IDataObject, NULL, (LPVOID *)&lpDo);
-	    IShellFolder_Release(lpDesktopSF);
-	}
-	else
-	{
-	    IShellFolder_BindToObject(lpDesktopSF, This->pidl, NULL, &IID_IShellFolder, (LPVOID*) &lpSF);
-	    ret = IShellFolder_GetUIObjectOf(lpSF, hwnd, This->cidl, (LPCITEMIDLIST*)This->apidl,
-					     &IID_IDataObject, NULL, (LPVOID *)&lpDo);
-	    IShellFolder_Release(lpSF);
-	    IShellFolder_Release(lpDesktopSF);
-	}
-
-	if (SUCCEEDED(ret))
-	{
-	    hpsxa = SHCreatePropSheetExtArrayEx(HKEY_CLASSES_ROOT, wszFiletype, MAX_PROP_PAGES - psh.nPages, lpDo);
-	    if (hpsxa != NULL)
-	    {
-		SHAddFromPropSheetExtArray(hpsxa, Properties_AddPropSheetCallback, (LPARAM)&psh);
-		SHDestroyPropSheetExtArray(hpsxa);
-	    }
-	    hpsxa = SHCreatePropSheetExtArrayEx(HKEY_CLASSES_ROOT, wszFiletypeAll, MAX_PROP_PAGES - psh.nPages, lpDo);
-	    if (hpsxa != NULL)
-	    {
-		SHAddFromPropSheetExtArray(hpsxa, Properties_AddPropSheetCallback, (LPARAM)&psh);
-		SHDestroyPropSheetExtArray(hpsxa);
-	    }
-	    IDataObject_Release(lpDo);
-	}
-
-	if (psh.nPages)
-	    PropertySheetW(&psh);
-	else
-	    FIXME("No property pages found.\n");
-}
-
-/**************************************************************************
-* ISvItemCm_fnInvokeCommand()
-*/
-static HRESULT WINAPI ISvItemCm_fnInvokeCommand(
-	IContextMenu2 *iface,
-	LPCMINVOKECOMMANDINFO lpcmi)
-{
-    ItemCmImpl *This = impl_from_IContextMenu2(iface);
-
-    if (lpcmi->cbSize != sizeof(CMINVOKECOMMANDINFO))
-        FIXME("Is an EX structure\n");
-
-    TRACE("(%p)->(invcom=%p verb=%p wnd=%p)\n",This,lpcmi,lpcmi->lpVerb, lpcmi->hwnd);
-
-    if( HIWORD(lpcmi->lpVerb)==0 && LOWORD(lpcmi->lpVerb) > FCIDM_SHVIEWLAST)
-    {
-        TRACE("Invalid Verb %x\n",LOWORD(lpcmi->lpVerb));
-        return E_INVALIDARG;
-    }
-
-    if (HIWORD(lpcmi->lpVerb) == 0)
-    {
-        switch(LOWORD(lpcmi->lpVerb-This->menu.verb_offset))
-        {
-        case FCIDM_SHVIEW_EXPLORE:
-            TRACE("Verb FCIDM_SHVIEW_EXPLORE\n");
-            DoOpenExplore(This, lpcmi->hwnd, "explore");
-            break;
-        case FCIDM_SHVIEW_OPEN:
-            TRACE("Verb FCIDM_SHVIEW_OPEN\n");
-            DoOpenExplore(This, lpcmi->hwnd, "open");
-            break;
-        case FCIDM_SHVIEW_RENAME:
-        {
-            IShellBrowser *browser;
-
-            /* get the active IShellView */
-            browser = (IShellBrowser*)SendMessageA(lpcmi->hwnd, CWM_GETISHELLBROWSER, 0, 0);
-            if (browser)
-            {
-                IShellView *view;
-
-                if(SUCCEEDED(IShellBrowser_QueryActiveShellView(browser, &view)))
-                {
-                    TRACE("(shellview=%p)\n", view);
-                    IShellView_SelectItem(view, This->apidl[0],
-                         SVSI_DESELECTOTHERS|SVSI_EDIT|SVSI_ENSUREVISIBLE|SVSI_FOCUSED|SVSI_SELECT);
-                    IShellView_Release(view);
-                }
-            }
-            break;
-        }
-        case FCIDM_SHVIEW_DELETE:
-            TRACE("Verb FCIDM_SHVIEW_DELETE\n");
-            DoDelete(This);
-            break;
-        case FCIDM_SHVIEW_COPY:
-            TRACE("Verb FCIDM_SHVIEW_COPY\n");
-            DoCopyOrCut(This, lpcmi->hwnd, FALSE);
-            break;
-        case FCIDM_SHVIEW_CUT:
-            TRACE("Verb FCIDM_SHVIEW_CUT\n");
-            DoCopyOrCut(This, lpcmi->hwnd, TRUE);
-            break;
-        case FCIDM_SHVIEW_PROPERTIES:
-            TRACE("Verb FCIDM_SHVIEW_PROPERTIES\n");
-            DoOpenProperties(This, lpcmi->hwnd);
-            break;
-        default:
-            FIXME("Unhandled Verb %xl\n",LOWORD(lpcmi->lpVerb)-This->menu.verb_offset);
-            return E_INVALIDARG;
-        }
-    }
-    else
-    {
-        TRACE("Verb is %s\n",debugstr_a(lpcmi->lpVerb));
-        if (strcmp(lpcmi->lpVerb,"delete")==0)
-            DoDelete(This);
-        else if (strcmp(lpcmi->lpVerb,"properties")==0)
-            DoOpenProperties(This, lpcmi->hwnd);
-        else {
-            FIXME("Unhandled string verb %s\n",debugstr_a(lpcmi->lpVerb));
-            return E_FAIL;
-        }
-    }
-    return S_OK;
-}
-
-/**************************************************************************
-*  ISvItemCm_fnGetCommandString()
-*/
-static HRESULT WINAPI ISvItemCm_fnGetCommandString(
-	IContextMenu2 *iface,
-	UINT_PTR idCommand,
-	UINT uFlags,
-	UINT* lpReserved,
-	LPSTR lpszName,
-	UINT uMaxNameLen)
-{
-	ItemCmImpl *This = impl_from_IContextMenu2(iface);
-
-	HRESULT  hr = E_INVALIDARG;
-
-	TRACE("(%p)->(idcom=%lx flags=%x %p name=%p len=%x)\n",This, idCommand, uFlags, lpReserved, lpszName, uMaxNameLen);
-
-	switch(uFlags)
-	{
-	  case GCS_HELPTEXTA:
-	  case GCS_HELPTEXTW:
-	    hr = E_NOTIMPL;
-	    break;
-
-	  case GCS_VERBA:
-	    switch(idCommand-This->menu.verb_offset)
-	    {
-	    case FCIDM_SHVIEW_RENAME:
-	        strcpy(lpszName, "rename");
-	        hr = S_OK;
-	        break;
-	    }
-	    break;
-
-	     /* NT 4.0 with IE 3.0x or no IE will always call This with GCS_VERBW. In This
-	     case, you need to do the lstrcpyW to the pointer passed.*/
-	  case GCS_VERBW:
-	    switch(idCommand-This->menu.verb_offset)
-	    {
-	    case FCIDM_SHVIEW_RENAME:
-                MultiByteToWideChar( CP_ACP, 0, "rename", -1, (LPWSTR)lpszName, uMaxNameLen );
-	        hr = S_OK;
-	        break;
-	    }
-	    break;
-
-	  case GCS_VALIDATEA:
-	  case GCS_VALIDATEW:
-	    hr = S_OK;
-	    break;
-	}
-	TRACE("-- (%p)->(name=%s)\n",This, lpszName);
-	return hr;
-}
-
-/**************************************************************************
-* ISvItemCm_fnHandleMenuMsg()
-* NOTES
-*  should be only in IContextMenu2 and IContextMenu3
-*  is nevertheless called from word95
-*/
-static HRESULT WINAPI ISvItemCm_fnHandleMenuMsg(
-	IContextMenu2 *iface,
-	UINT uMsg,
-	WPARAM wParam,
-	LPARAM lParam)
-{
-	ItemCmImpl *This = impl_from_IContextMenu2(iface);
-
-	TRACE("(%p)->(msg=%x wp=%lx lp=%lx)\n",This, uMsg, wParam, lParam);
-
-	return E_NOTIMPL;
-}
-
-static const IContextMenu2Vtbl ItemContextMenuVtbl =
-{
-	ISvItemCm_fnQueryInterface,
-	ISvItemCm_fnAddRef,
-	ISvItemCm_fnRelease,
-	ISvItemCm_fnQueryContextMenu,
-	ISvItemCm_fnInvokeCommand,
-	ISvItemCm_fnGetCommandString,
-	ISvItemCm_fnHandleMenuMsg
-};
-
-IContextMenu2 *ISvItemCm_Constructor(IShellFolder *parent, LPCITEMIDLIST pidl, const LPCITEMIDLIST *apidl, UINT cidl)
-{	ItemCmImpl* cm;
-	UINT  u;
-
-	cm = HeapAlloc(GetProcessHeap(), 0, sizeof(ItemCmImpl));
-	cm->menu.IContextMenu2_iface.lpVtbl = &ItemContextMenuVtbl;
-	cm->menu.ref = 1;
-	cm->menu.verb_offset = 0;
-	cm->menu.parent = parent;
-
-	cm->pidl = ILClone(pidl);
-
-	if (parent) IShellFolder_AddRef(parent);
-
-	cm->apidl = _ILCopyaPidl(apidl, cidl);
-	cm->cidl = cidl;
-
-	cm->bAllValues = 1;
-	for(u = 0; u < cidl; u++)
-	  cm->bAllValues &= (_ILIsValue(apidl[u]) ? 1 : 0);
-
-	TRACE("(%p)\n",cm);
-
-	return &cm->menu.IContextMenu2_iface;
-}
-- 
1.5.6.5


