[ros-diffs] [janderwald] 31547: - scan HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\HideDesktopIcons\ClassicStartMenu key if a shellfolder should be hidden - also add items which should should not be hidden - network location shell folder now appears but isnt working

janderwald at svn.reactos.org janderwald at svn.reactos.org
Wed Jan 2 00:34:29 CET 2008


Author: janderwald
Date: Wed Jan  2 02:34:28 2008
New Revision: 31547

URL: http://svn.reactos.org/svn/reactos?rev=31547&view=rev
Log:
- scan HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\HideDesktopIcons\ClassicStartMenu key if a shellfolder should be hidden
- also add items which should should not be hidden 
- network location shell folder now appears but isnt working

Added:
    trunk/reactos/dll/win32/shell32/shv_default_context_menu.c   (with props)
Modified:
    trunk/reactos/dll/win32/shell32/enumidlist.c
    trunk/reactos/dll/win32/shell32/enumidlist.h
    trunk/reactos/dll/win32/shell32/shfldr_desktop.c
    trunk/reactos/dll/win32/shell32/shlfldr_mydocuments.c
    trunk/reactos/dll/win32/shell32/shlfolder.c
    trunk/reactos/dll/win32/shell32/shv_item_cmenu.c

Modified: trunk/reactos/dll/win32/shell32/enumidlist.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/shell32/enumidlist.c?rev=31547&r1=31546&r2=31547&view=diff
==============================================================================
--- trunk/reactos/dll/win32/shell32/enumidlist.c (original)
+++ trunk/reactos/dll/win32/shell32/enumidlist.c Wed Jan  2 02:34:28 2008
@@ -98,6 +98,29 @@
 	}
 	return FALSE;
 }
+/**************************************************************************
+ *  HasItemWithCLSID()
+ */
+BOOL HasItemWithCLSID(IEnumIDList *iface, LPITEMIDLIST pidl)
+{
+	IEnumIDListImpl *This = (IEnumIDListImpl *)iface;
+	LPENUMLIST  pCur;
+    REFIID refid = _ILGetGUIDPointer(pidl);
+
+    pCur = This->mpFirst;
+
+    while(pCur)
+    {
+        REFIID curid = _ILGetGUIDPointer(pCur->pidl);
+        if (IsEqualIID(curid, refid))
+        {
+            return TRUE;
+        }
+        pCur = pCur->pNext;
+    }
+    return FALSE;
+}
+
 
 /**************************************************************************
  *  CreateFolderEnumList()

Modified: trunk/reactos/dll/win32/shell32/enumidlist.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/shell32/enumidlist.h?rev=31547&r1=31546&r2=31547&view=diff
==============================================================================
--- trunk/reactos/dll/win32/shell32/enumidlist.h (original)
+++ trunk/reactos/dll/win32/shell32/enumidlist.h Wed Jan  2 02:34:28 2008
@@ -21,6 +21,7 @@
 /* Creates an IEnumIDList; add LPITEMIDLISTs to it with AddToEnumList. */
 LPENUMIDLIST IEnumIDList_Constructor(void);
 BOOL AddToEnumList(IEnumIDList *list, LPITEMIDLIST pidl);
+BOOL HasItemWithCLSID(IEnumIDList *list, LPITEMIDLIST pidl);
 
 /* Enumerates the folders and/or files (depending on dwFlags) in lpszPath and
  * adds them to the already-created list.

Modified: trunk/reactos/dll/win32/shell32/shfldr_desktop.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/shell32/shfldr_desktop.c?rev=31547&r1=31546&r2=31547&view=diff
==============================================================================
--- trunk/reactos/dll/win32/shell32/shfldr_desktop.c (original)
+++ trunk/reactos/dll/win32/shell32/shfldr_desktop.c Wed Jan  2 02:34:28 2008
@@ -239,6 +239,34 @@
     return hr;
 }
 
+static const WCHAR ClassicStartMenuW[] =  {'S','O','F','T','W','A','R','E','\\',
+ 'M','i','c','r','o','s','o','f','t','\\','W','i','n','d','o','w','s','\\',
+ 'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\','E','x','p','l','o','r','e','r',
+ '\\','H','i','d','e','D','e','s','k','t','o','p','I','c','o','n','s','\\',
+ 'C','l','a','s','s','i','c','S','t','a','r','t','M','e','n','u','\0' };
+
+INT
+HideNamespaceExtension(WCHAR *iid)
+{
+    DWORD Result, dwResult;
+    dwResult = sizeof(DWORD);
+
+    if (RegGetValueW(HKEY_CURRENT_USER, /* FIXME use NewStartPanel when activated */
+                     ClassicStartMenuW,
+                     iid,
+                     RRF_RT_DWORD,
+                     NULL,
+                     &Result,
+                     &dwResult) != ERROR_SUCCESS)
+    {
+        return -1;     
+    }
+    
+    return Result;
+}
+
+
+
 /**************************************************************************
  *  CreateDesktopEnumList()
  */
@@ -252,6 +280,8 @@
 {
     BOOL ret = TRUE;
     WCHAR szPath[MAX_PATH];
+    static WCHAR MyDocumentsClassString[] = L"{450D8FBA-AD25-11D0-98A8-0800361B1103}";
+
 
     TRACE("(%p)->(flags=0x%08x)\n", list, dwFlags);
 
@@ -260,14 +290,23 @@
     {
         HKEY hkey;
         UINT i;
+        DWORD dwResult;
 
         /* create the pidl for This item */
-        ret = AddToEnumList(list, _ILCreateMyDocuments());
+        if (HideNamespaceExtension(MyDocumentsClassString) < 1)
+        {
+            ret = AddToEnumList(list, _ILCreateMyDocuments());
+        }
         ret = AddToEnumList(list, _ILCreateMyComputer());
 
-        for (i=0; i<2; i++) {
-            if (ret && !RegOpenKeyExW(i == 0 ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER,
-                                      Desktop_NameSpaceW, 0, KEY_READ, &hkey))
+        for (i = 0; i < 2; i++)
+        {
+            if (i == 0)
+                dwResult = RegOpenKeyExW(HKEY_LOCAL_MACHINE, Desktop_NameSpaceW, 0, KEY_READ, &hkey);
+            else 
+                dwResult = RegOpenKeyExW(HKEY_CURRENT_USER, Desktop_NameSpaceW, 0, KEY_READ, &hkey);
+
+            if (dwResult == ERROR_SUCCESS)
             {
                 WCHAR iid[50];
                 LPITEMIDLIST pidl;
@@ -282,24 +321,69 @@
                     r = RegEnumKeyExW(hkey, i, iid, &size, 0, NULL, NULL, NULL);
                     if (ERROR_SUCCESS == r)
                     {
-                        pidl = _ILCreateGuidFromStrW(iid);
-                        if (_ILIsMyDocuments(pidl))
+                        if (HideNamespaceExtension(iid) < 1)
                         {
-                            SHFree(pidl);
+                           pidl = _ILCreateGuidFromStrW(iid);
+                           if (!HasItemWithCLSID(list, pidl))
+                           {
+                               ret = AddToEnumList(list, pidl);
+                           }
+                           else
+                           {
+                                SHFree(pidl);
+                           }
+                       }
+                    }
+                    else if (ERROR_NO_MORE_ITEMS == r)
+                        break;
+                    else
+                        ret = FALSE;
+                    i++;
+                }
+                RegCloseKey(hkey);
+            }
+        }
+        for (i = 0; i < 2; i++)
+        {
+            if (i == 0)
+                dwResult = RegOpenKeyExW(HKEY_LOCAL_MACHINE, ClassicStartMenuW, 0, KEY_READ, &hkey);
+            else 
+                dwResult = RegOpenKeyExW(HKEY_CURRENT_USER, ClassicStartMenuW, 0, KEY_READ, &hkey);
+
+            if (dwResult == ERROR_SUCCESS)
+            {
+                DWORD j = 0, dwVal, Val, dwType, dwIID;
+                LONG r;
+                WCHAR iid[50];
+
+                while(ret)
+                {
+                    dwVal = sizeof(Val);
+                    dwIID = sizeof(iid) / sizeof(WCHAR);
+
+                    r = RegEnumValueW(hkey, j++, iid, &dwIID, NULL, &dwType, (LPBYTE)&Val, &dwVal);
+                    if (r == ERROR_SUCCESS)
+                    {
+                        if (Val == 0 && dwType == REG_DWORD)
+                        {
+                            LPITEMIDLIST pidl = _ILCreateGuidFromStrW(iid);
+                            if (!HasItemWithCLSID(list, pidl))
+                            {
+                               AddToEnumList(list, pidl);
+                            }
+                            else
+                            {
+                                SHFree(pidl);
+                            }
                         }
-                        else
-                        {
-                            ret = AddToEnumList(list, pidl);
-                        }
-                        i++;
                     }
                     else if (ERROR_NO_MORE_ITEMS == r)
                         break;
                     else
                         ret = FALSE;
                 }
-                RegCloseKey(hkey);
             }
+
         }
     }
 

Modified: trunk/reactos/dll/win32/shell32/shlfldr_mydocuments.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/shell32/shlfldr_mydocuments.c?rev=31547&r1=31546&r2=31547&view=diff
==============================================================================
--- trunk/reactos/dll/win32/shell32/shlfldr_mydocuments.c (original)
+++ trunk/reactos/dll/win32/shell32/shlfldr_mydocuments.c Wed Jan  2 02:34:28 2008
@@ -52,7 +52,7 @@
 #include "debughlp.h"
 #include "shfldr.h"
 
-WINE_DEFAULT_DEBUG_CHANNEL (shell);
+WINE_DEFAULT_DEBUG_CHANNEL (mydocs);
 
 /***********************************************************************
 *     MyDocumentsfolder implementation
@@ -500,13 +500,14 @@
     if (!pszPath)
         return E_OUTOFMEMORY;
 
-    if (_ILIsMyDocuments (pidl) || _ILIsDesktop(pidl))
+    if (_ILIsMyDocuments (pidl))
     {
         if ((GET_SHGDN_RELATION (dwFlags) == SHGDN_NORMAL) &&
             (GET_SHGDN_FOR (dwFlags) & SHGDN_FORPARSING))
             strcpyW(pszPath, This->sPathTarget);
         else
             HCR_GetClassNameW(&CLSID_MyDocuments, pszPath, MAX_PATH);
+        TRACE("CP\n");
     }
     else if (_ILIsPidlSimple (pidl))
     {
@@ -563,6 +564,7 @@
                     hr = SHELL32_GetDisplayNameOfChild (iface, pidl, dwFlags,
                                                         pszPath,
                                                         MAX_PATH);
+                            TRACE("CP\n");
                 }
                 else
                 {
@@ -570,12 +572,14 @@
                     pszPath[0] = ':';
                     pszPath[1] = ':';
                     SHELL32_GUIDToStringW (clsid, &pszPath[2]);
+                            TRACE("CP\n");
                 }
             }
             else
             {
                 /* user friendly name */
                 HCR_GetClassNameW (clsid, pszPath, MAX_PATH);
+                        TRACE("CP\n");
             }
         }
         else
@@ -587,14 +591,20 @@
                 (GET_SHGDN_RELATION(dwFlags) != SHGDN_INFOLDER))
             {
                 lstrcpynW(pszPath, This->sPathTarget, MAX_PATH - 1);
+                TRACE("CP %s\n", debugstr_w(pszPath));
+            }
+
+            if (!_ILIsDesktop(pidl))
+            {
                 PathAddBackslashW(pszPath);
                 cLen = lstrlenW(pszPath);
+                _ILSimpleGetTextW(pidl, pszPath + cLen, MAX_PATH - cLen);
+                if (!_ILIsFolder(pidl))
+                {
+                    SHELL_FS_ProcessDisplayFilename(pszPath, dwFlags);
+                            TRACE("CP\n");
+                }
             }
-
-            _ILSimpleGetTextW(pidl, pszPath + cLen, MAX_PATH - cLen);
-
-            if (!_ILIsFolder(pidl))
-                SHELL_FS_ProcessDisplayFilename(pszPath, dwFlags);
         }
     }
     else
@@ -602,31 +612,18 @@
         /* a complex pidl, let the subfolder do the work */
         hr = SHELL32_GetDisplayNameOfChild (iface, pidl, dwFlags,
                                             pszPath, MAX_PATH);
+                        TRACE("CP\n");                                
     }
 
     if (SUCCEEDED(hr))
     {
-        /* Win9x always returns ANSI strings, NT always returns Unicode strings */
-        if (GetVersion() & 0x80000000)
-        {
-            strRet->uType = STRRET_CSTR;
-            if (!WideCharToMultiByte(CP_ACP, 0, pszPath, -1, strRet->u.cStr, MAX_PATH,
-                                     NULL, NULL))
-                strRet->u.cStr[0] = '\0';
-            CoTaskMemFree(pszPath);
-        }
-        else
-        {
-            strRet->uType = STRRET_WSTR;
-            strRet->u.pOleStr = pszPath;
-        }
+        strRet->uType = STRRET_WSTR;
+        strRet->u.pOleStr = pszPath;
     }
     else
         CoTaskMemFree(pszPath);
 
-    TRACE ("-- (%p)->(%s,0x%08x)\n", This,
-     strRet->uType == STRRET_CSTR ? strRet->u.cStr :
-     debugstr_w(strRet->u.pOleStr), hr);
+    TRACE ("-- (%p)->(%s,0x%08x)\n", This, debugstr_w(strRet->u.pOleStr), hr);
     return hr;
 }
 

Modified: trunk/reactos/dll/win32/shell32/shlfolder.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/shell32/shlfolder.c?rev=31547&r1=31546&r2=31547&view=diff
==============================================================================
--- trunk/reactos/dll/win32/shell32/shlfolder.c (original)
+++ trunk/reactos/dll/win32/shell32/shlfolder.c Wed Jan  2 02:34:28 2008
@@ -418,7 +418,7 @@
 
     if (_ILIsDrive (pidl)) {
         *pdwAttributes &= SFGAO_HASSUBFOLDER|SFGAO_FILESYSTEM|SFGAO_FOLDER|SFGAO_FILESYSANCESTOR|
-	    SFGAO_DROPTARGET|SFGAO_HASPROPSHEET|SFGAO_CANLINK;
+	    SFGAO_DROPTARGET|SFGAO_HASPROPSHEET|SFGAO_CANLINK|SFGAO_CANRENAME;
     } else if (has_guid && HCR_GetFolderAttributes(pidl, &dwAttributes)) {
 	*pdwAttributes = dwAttributes;
     } else if (_ILGetDataPointer (pidl)) {

Added: trunk/reactos/dll/win32/shell32/shv_default_context_menu.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/shell32/shv_default_context_menu.c?rev=31547&view=auto
==============================================================================
--- trunk/reactos/dll/win32/shell32/shv_default_context_menu.c (added)
+++ trunk/reactos/dll/win32/shell32/shv_default_context_menu.c Wed Jan  2 02:34:28 2008
@@ -1,0 +1,1246 @@
+/*
+ * PROJECT:     shell32
+ * LICENSE:     GPL - See COPYING in the top level directory
+ * FILE:        dll/win32/shell32/shv_item_new.c
+ * PURPOSE:     provides default context menu implementation
+ * PROGRAMMERS: Johannes Anderwald (janderwald at reactos.org)
+ */
+
+#include <string.h>
+
+#define COBJMACROS
+#define NONAMELESSUNION
+#define NONAMELESSSTRUCT
+#define YDEBUG
+#include "winerror.h"
+#include "wine/debug.h"
+
+#include "windef.h"
+#include "wingdi.h"
+#include "pidl.h"
+#include "undocshell.h"
+#include "shlobj.h"
+#include "objbase.h"
+
+#include "shlwapi.h"
+#include "shell32_main.h"
+#include "shellfolder.h"
+#include "debughlp.h"
+#include "shresdef.h"
+#include "shlguid.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(dmenu);
+
+typedef struct _DynamicShellEntry_
+{
+    UINT iIdCmdFirst;
+    UINT NumIds;
+    IContextMenu * CMenu;
+    struct _DynamicShellEntry_ * Next;
+}DynamicShellEntry, *PDynamicShellEntry;
+
+typedef struct _StaticShellEntry_
+{
+   LPWSTR szVerb;
+   LPWSTR szClass;
+   struct _StaticShellEntry_ * Next;
+}StaticShellEntry, *PStaticShellEntry;
+
+
+typedef struct
+{
+	const IContextMenu2Vtbl *lpVtbl;
+	LONG		ref;
+    DEFCONTEXTMENU dcm;
+    IDataObject * pDataObj;
+    DWORD bGroupPolicyActive;
+    PDynamicShellEntry dhead; /* first dynamic shell extension entry */
+    UINT           iIdSHEFirst; /* first used id */
+    UINT           iIdSHELast; /* last used id */
+    PStaticShellEntry shead; /* first static shell extension entry */
+    UINT           iIdSCMFirst; /* first static used id */
+    UINT           iIdSCMLast; /* last static used id */
+}IDefaultContextMenuImpl;
+
+static inline IDefaultContextMenuImpl *impl_from_IContextMenu( IContextMenu2 *iface )
+{
+    return (IDefaultContextMenuImpl *)((char*)iface - FIELD_OFFSET(IDefaultContextMenuImpl, lpVtbl));
+}
+
+static
+HRESULT
+WINAPI
+IDefaultContextMenu_fnQueryInterface(
+	IContextMenu2 *iface,
+    REFIID riid,
+    LPVOID *ppvObj)
+{
+	IDefaultContextMenuImpl *This = (IDefaultContextMenuImpl *)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;
+	}
+
+	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
+IDefaultContextMenu_fnAddRef(
+	IContextMenu2 *iface)
+{
+	IDefaultContextMenuImpl *This = (IDefaultContextMenuImpl *)iface;
+	ULONG refCount = InterlockedIncrement(&This->ref);
+
+	TRACE("(%p)->(count=%u)\n", This, refCount - 1);
+
+	return refCount;
+}
+
+static
+ULONG
+WINAPI
+IDefaultContextMenu_fnRelease(
+	IContextMenu2 *iface)
+{
+	IDefaultContextMenuImpl *This = (IDefaultContextMenuImpl *)iface;
+	ULONG refCount = InterlockedDecrement(&This->ref);
+
+	TRACE("(%p)->(count=%u)\n", This, refCount + 1);
+    if (!refCount)
+    {
+	  TRACE(" destroying IContextMenu(%p)\n",This);
+
+	  HeapFree(GetProcessHeap(),0,This);
+    }
+
+	return refCount;
+}
+
+static
+void
+SH_AddStaticEntry(IDefaultContextMenuImpl * This, HKEY hKey, WCHAR *szVerb, WCHAR * szClass)
+{
+  PStaticShellEntry curEntry;
+  PStaticShellEntry lastEntry = NULL;
+
+  curEntry = This->shead;
+
+  while(curEntry)
+  {
+    if (!wcsicmp(curEntry->szVerb, szVerb))
+    {
+       /* entry already exists */
+       return;
+    }
+    lastEntry = curEntry;
+    curEntry = curEntry->Next;
+  }
+  
+  TRACE("adding verb %s szClass %s\n", debugstr_w(szVerb), debugstr_w(szClass));
+
+  curEntry = malloc(sizeof(StaticShellEntry));
+  if (curEntry)
+  {
+      curEntry->Next = NULL;
+      curEntry->szVerb = wcsdup(szVerb);
+      curEntry->szClass = wcsdup(szClass);
+  }
+
+  if (lastEntry)
+  {
+    lastEntry->Next = curEntry;
+  }
+  else
+  {
+    This->shead = curEntry;
+  }
+}
+
+static
+void
+SH_AddStaticEntryForKey(IDefaultContextMenuImpl * This, HKEY hKey, WCHAR * szClass)
+{
+    LONG result;
+    DWORD dwIndex;
+    WCHAR szName[40];
+    DWORD dwName;
+
+    dwIndex = 0;
+    do
+    {
+        szName[0] = 0;
+        dwName = sizeof(szName) / sizeof(WCHAR);
+        result = RegEnumKeyExW(hKey, dwIndex, szName, &dwName, NULL, NULL, NULL, NULL);
+        szName[39] = 0;   
+        if (result == ERROR_SUCCESS)
+        {
+            SH_AddStaticEntry(This, hKey, szName, szClass);
+        }
+        dwIndex++;
+    }while(result == ERROR_SUCCESS);
+}
+
+static
+void
+SH_AddStaticEntryForFileClass(IDefaultContextMenuImpl * This, WCHAR * szExt)
+{
+    WCHAR szBuffer[100];
+    HKEY hKey;
+    LONG result;
+    DWORD dwBuffer;
+
+    TRACE("SH_AddStaticEntryForFileClass entered with %s\n", debugstr_w(szExt));
+
+    wcscpy(szBuffer, szExt);
+    wcscat(szBuffer, L"\\shell");
+    result = RegOpenKeyExW(HKEY_CLASSES_ROOT, szBuffer, 0, KEY_READ | KEY_QUERY_VALUE, &hKey);
+    if (result == ERROR_SUCCESS)
+    {
+        SH_AddStaticEntryForKey(This, hKey, szExt);
+        RegCloseKey(hKey);
+    }
+
+    dwBuffer = sizeof(szBuffer);
+    result = RegGetValueW(HKEY_CLASSES_ROOT, szExt, NULL, RRF_RT_REG_SZ, NULL, (LPBYTE)szBuffer, &dwBuffer);
+    if (result == ERROR_SUCCESS)
+    {
+        UINT length = strlenW(szBuffer);
+        wcscat(szBuffer, L"\\shell");
+        TRACE("szBuffer %s\n", debugstr_w(szBuffer));
+
+        result = RegOpenKeyExW(HKEY_CLASSES_ROOT, szBuffer, 0, KEY_READ | KEY_QUERY_VALUE, &hKey);
+        if (result == ERROR_SUCCESS)
+        {
+           szBuffer[length] = 0;
+           SH_AddStaticEntryForKey(This, hKey, szBuffer);
+           RegCloseKey(hKey);
+        }
+    }
+
+    strcpyW(szBuffer, "SystemFileAssociations\\");
+    dwBuffer = sizeof(szBuffer) - strlenW(szBuffer) * sizeof(WCHAR);
+    result = RegGetValueW(HKEY_CLASSES_ROOT, szExt, L"PerceivedType", RRF_RT_REG_SZ, NULL, (LPBYTE)&szBuffer[23], &dwBuffer);
+    if (result == ERROR_SUCCESS)
+    {
+        UINT length = strlenW(szBuffer);
+        wcscat(szBuffer, L"\\shell");
+        TRACE("szBuffer %s\n", debugstr_w(szBuffer));
+
+        result = RegOpenKeyExW(HKEY_CLASSES_ROOT, szBuffer, 0, KEY_READ | KEY_QUERY_VALUE, &hKey);
+        if (result == ERROR_SUCCESS)
+        {
+           szBuffer[length] = 0;
+           SH_AddStaticEntryForKey(This, hKey, szBuffer);
+           RegCloseKey(hKey);
+        }
+    }
+    RegCloseKey(hKey);
+}
+
+static
+BOOL 
+HasClipboardData()
+{
+    BOOL ret = FALSE;
+    IDataObject * pda;
+
+    if(SUCCEEDED(OleGetClipboard(&pda)))
+    {
+      STGMEDIUM medium;
+      FORMATETC formatetc;
+
+      TRACE("pda=%p\n", pda);
+
+      /* Set the FORMATETC structure*/
+      InitFormatEtc(formatetc, RegisterClipboardFormatA(CFSTR_SHELLIDLIST), TYMED_HGLOBAL);
+      if(SUCCEEDED(IDataObject_GetData(pda,&formatetc,&medium)))
+      {
+          ret = TRUE;
+      }
+
+      IDataObject_Release(pda);
+      ReleaseStgMedium(&medium);
+    }
+
+    return ret;
+}
+
+VOID
+DisablePasteOptions(HMENU hMenu)
+{
+    MENUITEMINFOW mii;
+
+    mii.cbSize = sizeof(mii);
+    mii.fMask = MIIM_STATE;
+    mii.fState = MFS_DISABLED;
+
+    TRACE("result %d\n", SetMenuItemInfoW(hMenu, FCIDM_SHVIEW_INSERT, FALSE, &mii));
+    TRACE("result %d\n", SetMenuItemInfoW(hMenu, FCIDM_SHVIEW_INSERTLINK, FALSE, &mii));
+}
+
+static
+HRESULT
+SH_LoadDynamicContextMenuHandler(IDefaultContextMenuImpl * This, HKEY hKey, const CLSID * szClass, BOOL bExternalInit)
+{
+  HRESULT hr;
+  IContextMenu * cmobj;
+  IShellExtInit *shext;
+  PDynamicShellEntry curEntry;
+  TRACE("SH_LoadDynamicContextMenuHandler entered with This %p hKey %p szClass %s bExternalInit %u\n",This, hKey, wine_dbgstr_guid(szClass), bExternalInit);
+
+  hr = SHCoCreateInstance(NULL, szClass, NULL, &IID_IContextMenu, (void**)&cmobj);
+  if (hr != S_OK)
+  {
+      TRACE("SHCoCreateInstance failed %x\n", GetLastError());
+      return hr;
+  }
+
+  if (bExternalInit)
+  {
+      hr = cmobj->lpVtbl->QueryInterface(cmobj, &IID_IShellExtInit, (void**)&shext);
+      if (hr != S_OK)
+      {
+        TRACE("Failed to query for interface IID_IShellExtInit\n");
+        cmobj->lpVtbl->Release(cmobj);
+        return FALSE;
+      }
+      hr = shext->lpVtbl->Initialize(shext, NULL, This->pDataObj, hKey);
+      shext->lpVtbl->Release(shext);
+      if (hr != S_OK)
+      {
+        TRACE("Failed to initialize shell extension error %x\n", hr);
+        cmobj->lpVtbl->Release(cmobj);
+        return hr;
+      }
+  }
+
+  curEntry = malloc(sizeof(DynamicShellEntry));
+  if(!curEntry)
+  {
+      return E_OUTOFMEMORY;
+  }
+
+  curEntry->iIdCmdFirst = 0;
+  curEntry->Next = NULL;
+  curEntry->NumIds = 0;
+  curEntry->CMenu = cmobj;
+
+  if (This->dhead)
+  {
+      PDynamicShellEntry pEntry = This->dhead;
+
+      while(pEntry->Next)
+      {
+         pEntry = pEntry->Next;
+      }
+
+      pEntry->Next = curEntry;
+  }
+  else
+  {
+      This->dhead = curEntry;
+  }
+
+  return hr;
+}
+
+static
+UINT
+EnumerateDynamicContextHandlerForKey(IDefaultContextMenuImpl *This, HKEY hRootKey)
+{
+   WCHAR szKey[MAX_PATH] = {0};
+   WCHAR szName[MAX_PATH] = {0};
+   DWORD dwIndex, dwName;
+   LONG res;
+   HRESULT hResult;
+   UINT index;
+   CLSID clsid;
+   HKEY hKey;
+
+   static const WCHAR szShellEx[] = { 's','h','e','l','l','e','x','\\','C','o','n','t','e','x','t','M','e','n','u','H','a','n','d','l','e','r','s',0 };
+
+   if (RegOpenKeyExW(hRootKey, szShellEx, 0, KEY_READ, &hKey) != ERROR_SUCCESS)
+   {
+      TRACE("RegOpenKeyExW failed for key %s\n", debugstr_w(szKey));
+      return 0;
+   }
+
+   dwIndex = 0;
+   index = 0;
+   do
+   {
+      dwName = MAX_PATH;
+      res = RegEnumKeyExW(hKey, dwIndex, szName, &dwName, NULL, NULL, NULL, NULL);
+      if (res == ERROR_SUCCESS)
+      {
+         hResult = CLSIDFromString(szName, &clsid);
+         if (hResult != S_OK)
+         {
+             dwName = MAX_PATH;
+             if (RegGetValueW(hKey, szName, NULL, RRF_RT_REG_SZ, NULL, szKey, &dwName) == ERROR_SUCCESS)
+             {
+                if (CLSIDFromString(szKey, &clsid) == S_OK)
+                {
+                    if (This->bGroupPolicyActive)
+                    {
+                        if (RegGetValueW(HKEY_LOCAL_MACHINE,
+                                         L"Software\\Microsoft\\Windows\\CurrentVersion\\Shell Extensions\\Approved",
+                                         szKey,
+                                         RRF_RT_REG_SZ,
+                                         NULL,
+                                         NULL,
+                                         &dwName) == ERROR_SUCCESS)
+                        {
+                            SH_LoadDynamicContextMenuHandler(This, hKey, &clsid, TRUE);
+                        }
+
+                    }
+                    else
+                    {
+                        SH_LoadDynamicContextMenuHandler(This, hKey, &clsid, TRUE);
+                    }
+                }
+             }
+         }
+         if (hResult == S_OK)
+         {
+            if (This->bGroupPolicyActive)
+            {
+                if (RegGetValueW(HKEY_LOCAL_MACHINE,
+                                 L"Software\\Microsoft\\Windows\\CurrentVersion\\Shell Extensions\\Approved",
+                                 szKey,
+                                 RRF_RT_REG_SZ,
+                                 NULL,
+                                NULL,
+                                &dwName) == ERROR_SUCCESS)
+                {
+                    SH_LoadDynamicContextMenuHandler(This, hKey, &clsid, TRUE);
+                }
+            }
+            else
+            {
+                SH_LoadDynamicContextMenuHandler(This, hKey, &clsid, TRUE);
+            }
+         }
+      }
+      dwIndex++;
+   }while(res == ERROR_SUCCESS);
+
+   RegCloseKey(hKey);
+   return index;
+}
+
+
+static 
+UINT
+InsertMenuItemsOfDynamicContextMenuExtension(IDefaultContextMenuImpl * This, HMENU hMenu, UINT indexMenu, UINT idCmdFirst, UINT idCmdLast)
+{
+    PDynamicShellEntry curEntry;
+    HRESULT hResult;
+    MENUITEMINFOW mii;
+    if (!This->dhead)
+    {
+        This->iIdSHEFirst = 0;
+        This->iIdSHELast = 0;
+        return indexMenu;
+    }
+
+    curEntry = This->dhead;
+    This->iIdSHEFirst = idCmdFirst;
+
+    mii.cbSize = sizeof(mii);
+    mii.fMask = MIIM_FTYPE | MIIM_STATE;
+    mii.fType = MFT_SEPARATOR;
+    mii.fState = MFS_ENABLED;
+    InsertMenuItemW(hMenu, indexMenu++, TRUE, &mii);
+
+    do
+    {
+        hResult = IContextMenu_QueryContextMenu(curEntry->CMenu, hMenu, indexMenu, idCmdFirst, idCmdLast, CMF_NORMAL);
+        if (SUCCEEDED(hResult))
+        {
+            curEntry->iIdCmdFirst = idCmdFirst;
+            curEntry->NumIds = LOWORD(hResult);
+            indexMenu += curEntry->NumIds;
+            idCmdFirst += curEntry->NumIds + 0x10;
+        }
+        TRACE("curEntry %p hresult %x contextmenu %p cmdfirst %x num ids %x\n", curEntry, hResult, curEntry->CMenu, curEntry->iIdCmdFirst, curEntry->NumIds);
+        curEntry = curEntry->Next;
+    }while(curEntry);
+
+    This->iIdSHELast = idCmdFirst;
+    TRACE("SH_LoadContextMenuHandlers first %x last %x\n", This->iIdSHEFirst, This->iIdSHELast);
+    return indexMenu;
+}
+
+UINT
+BuildBackgroundContextMenu(
+    IDefaultContextMenuImpl * This,
+    HMENU hMenu,
+    UINT iIdCmdFirst,
+    UINT iIdCmdLast,
+    UINT uFlags)
+{
+    MENUITEMINFOW mii;
+    WCHAR szBuffer[MAX_PATH];
+    UINT indexMenu = 0;
+    HMENU hSubMenu;
+    HKEY hKey;
+
+    ZeroMemory(&mii, sizeof(mii));
+
+    TRACE("BuildBackgroundContextMenu entered\n");
+
+    if (!_ILIsDesktop(This->dcm.pidlFolder))
+    {
+        /* view option is only available in browsing mode */
+        hSubMenu = LoadMenuA(shell32_hInstance, "MENU_001");
+        if (hSubMenu)
+        {
+            szBuffer[0] = 0;
+            LoadStringW(shell32_hInstance, FCIDM_SHVIEW_VIEW, szBuffer, MAX_PATH);
+            szBuffer[MAX_PATH-1] = 0;
+            
+            TRACE("szBuffer %s\n", debugstr_w(szBuffer));
+
+            mii.cbSize = sizeof(mii);
+            mii.fMask = MIIM_TYPE | MIIM_STATE | MIIM_SUBMENU | MIIM_ID;
+            mii.fType = MFT_STRING;
+            mii.wID = iIdCmdFirst++;
+            mii.dwTypeData = szBuffer;
+            mii.cch = strlenW( mii.dwTypeData );
+            mii.fState = MFS_ENABLED;
+            mii.hSubMenu = hSubMenu;
+            InsertMenuItemW(hMenu, indexMenu++, TRUE, &mii);
+            DestroyMenu(hSubMenu);
+        }
+    }
+    hSubMenu = LoadMenuA(shell32_hInstance, "MENU_002");
+    if (hSubMenu)
+    {
+        /* merge general background context menu in */
+        iIdCmdFirst = Shell_MergeMenus(hMenu, hSubMenu, indexMenu, 0, iIdCmdLast, MM_DONTREMOVESEPS | MM_SUBMENUSHAVEIDS) + 1;
+        DestroyMenu(hSubMenu);
+    }
+
+    if (!HasClipboardData())
+    {
+        TRACE("disabling paste options\n");
+        DisablePasteOptions(hMenu);
+    }
+    /* load extensions from HKCR\* key */
+    if (RegOpenKeyExW(HKEY_CLASSES_ROOT,
+                     L"*",
+                     0,
+                     KEY_READ,
+                     &hKey) == ERROR_SUCCESS)
+    {
+        EnumerateDynamicContextHandlerForKey(This, hKey);
+        RegCloseKey(hKey);
+    }
+
+    /* load create new shell extension */
+    if (RegOpenKeyExW(HKEY_CLASSES_ROOT,
+                     L"CLSID\\{D969A300-E7FF-11d0-A93B-00A0C90F2719}",
+                     0,
+                     KEY_READ,
+                     &hKey) == ERROR_SUCCESS)
+    {
+        static const GUID dummy1 = {0xD969A300, 0xE7FF, 0x11d0, {0xA9, 0x3B, 0x00, 0xA0, 0xC9, 0x0F, 0x27, 0x19} };
+        SH_LoadDynamicContextMenuHandler(This, hKey, &dummy1, FALSE);
+        RegCloseKey(hKey);
+    }
+    
+    InsertMenuItemsOfDynamicContextMenuExtension(This, hMenu, GetMenuItemCount(hMenu), iIdCmdFirst, iIdCmdLast);
+    return iIdCmdLast;
+}
+
+static
+UINT
+AddStaticContextMenusToMenu(
+    HMENU hMenu,
+    UINT indexMenu,
+    IDefaultContextMenuImpl * This)
+{
+    MENUITEMINFOW mii;
+    PStaticShellEntry curEntry;
+
+    mii.cbSize = sizeof(mii);
+    mii.fMask = MIIM_ID | MIIM_TYPE | MIIM_STATE | MIIM_DATA;
+    mii.fType = MFT_STRING;
+    mii.fState = MFS_ENABLED | MFS_DEFAULT;
+    mii.wID = 0x4000;
+    This->iIdSCMFirst = mii.wID;
+
+    curEntry = This->shead;
+
+    while(curEntry)
+    {
+       /* FIXME
+        * load localized verbs if its an open edit find print printto openas properties verb
+        */
+
+       mii.dwTypeData = curEntry->szVerb;
+       mii.cch = strlenW(mii.dwTypeData);
+       InsertMenuItemW(hMenu, indexMenu++, TRUE, &mii);
+       mii.fState = MFS_ENABLED;
+       mii.wID++;
+       curEntry = curEntry->Next;
+    }
+    This->iIdSCMLast = mii.wID - 1;
+    return indexMenu;
+}
+
+static
+const char * 
+GetLocalizedString(
+    HMENU hMenu,
+    UINT wID,
+    char * sResult)
+{
+   MENUITEMINFOA mii;
+
+   sResult[0] = 0;
+   if (!hMenu)
+   {
+       return sResult;
+   }
+
+   mii.cbSize = sizeof(mii);
+   mii.fMask = MIIM_TYPE;
+   mii.fType = MFT_STRING;
+   mii.dwTypeData = sResult;
+   mii.cch = 100;
+
+   GetMenuItemInfoA(hMenu, wID, FALSE, &mii);
+   return sResult;
+}
+#if 0
+UINT
+BuildControlPanelContextMenu(
+    IDefaultContextMenuImpl * This,
+    HMENU hMenu,
+    UINT iIdCmdFirst,
+    UINT iIdCmdLast)
+{
+    GUID * guid;
+    SFGAOF attributes;
+    DWORD dwSize;
+    UINT indexMenu = 0;
+    LPOLESTR pwszCLSID;
+    WCHAR szClass[80];
+    UINT length;
+    MENUITEMINFOW mii;
+
+
+    ZeroMemory(&mii, sizeof(MENUITEMINFOW));
+
+    mii.cbSize = sizeof(MENUITEMINFOW);
+    mii.fMask = MIIM_FTYPE | MIIM_STATE | MIIM_ID;
+    mii.fType = MFT_STRING;
+    mii.fState = MFS_ENABLED;
+
+    guid = _ILGetGUIDPointer(This->dcm.apidl[0]);
+    if (guid) 
+    {
+        /* the cpl is registered as a namespace extension */
+        dwSize = sizeof(SFGAOF);
+        wcscpy(szClass, L"CLSID\\");
+        if (SUCCEEDED(StringFromCLSID(guid, &pwszCLSID)))
+        {
+            wcscpy(&szClass[6], pwszCLSID);
+            length = strlenW(szClass);
+
+            CoTaskMemFree(pwszCLSID);
+
+            /* check if the CLSID is a folder */
+            wcscat(szClass, L"\\ShellFolder");
+
+            if (RegGetValueW(HKEY_CLASSES_ROOT, szClass, L"Attributes", RRF_RT_REG_BINARY, NULL, &attributes, &dwSize) == ERROR_SUCCESS)
+            {
+                if (attributes & SFGAO_FOLDER)
+                {
+                    WCHAR szBuffer[100];
+                    /* insert explore string */
+                    LoadStringW(shell32_hInstance, FCIDM_SHVIEW_EXPLORE, szBuffer, sizeof(szBuffer) / sizeof(WCHAR));
+                    szBuffer[99] = 0;
+                    mii.wID = FCIDM_SHVIEW_EXPLORE;
+                    mii.dwTypeData = szBuffer;
+                    mii.fState |= MFS_DEFAULT;
+                    InsertMenuItem(hMenu, indexMenu++, TRUE, &mii);
+                    mii.fState = MFS_ENABLED;
+                }
+            }
+
+            /* add static handlers*/
+            szClass[length] = 0;
+            SH_AddStaticEntryForFileClass(This, szClass);         
+            indexMenu = AddStaticContextMenusToMenu(hMenu, indexMenu, This);
+        }
+    }
+    else
+    {
+        /* cpl is registered with full path */
+        SH_AddStaticEntryForFileClass(This, L".cpl");
+    }
+
+    if (AppendMenu(hMenu, MF_SEPARATOR, -1, NULL))
+    {
+        LoadStringW(shell32_hInstance, FCIDM_SHVIEW_CREATELINK, szClass, sizeof(szClass) / sizeof(WCHAR));
+        szClass[79] = 0;
+        InsertMenuItem(hMenu, indexMenu++, TRUE, &mii);
+    }
+}
+#endif
+
+UINT
+BuildShellItemContextMenu(
+    IDefaultContextMenuImpl * This,
+    HMENU hMenu,
+    UINT iIdCmdFirst,
+    UINT iIdCmdLast,
+    UINT uFlags)
+{
+    WCHAR szExt[10];
+    char sBuffer[100];
+    HKEY hKey;
+    UINT indexMenu;
+    SFGAOF rfg;
+    HRESULT hr;
+    BOOL bAddSep;
+    HMENU hLocalMenu;
+    GUID * guid;
+
+    TRACE("BuildShellItemContextMenu entered\n");
+
+    if (_ILGetExtension(This->dcm.apidl[0], &sBuffer[1], sizeof(sBuffer)))
+    {
+        sBuffer[9] = 0;
+        sBuffer[0] = '.';
+
+        if (MultiByteToWideChar( CP_ACP, 0, sBuffer, -1, (LPWSTR)szExt, 10))
+        {
+            TRACE("szExt %d\n", debugstr_w(szExt));
+            SH_AddStaticEntryForFileClass(This, szExt);
+            if (RegOpenKeyExW(HKEY_CLASSES_ROOT, szExt, 0, KEY_READ, &hKey) == ERROR_SUCCESS)
+            {
+                EnumerateDynamicContextHandlerForKey(This, hKey);
+                RegCloseKey(hKey);
+            }
+        }
+        if (RegOpenKeyExW(HKEY_CLASSES_ROOT, L"*", 0, KEY_READ, &hKey) == ERROR_SUCCESS)
+        {
+            /* load default extensions */
+            EnumerateDynamicContextHandlerForKey(This, hKey);
+            RegCloseKey(hKey);
+        }
+    }
+
+    if (!_ILIsPidlSimple(This->dcm.apidl[0])|| _ILIsFolder(This->dcm.apidl[0]))
+    {
+        /* add the default verbs open / explore */
+        SH_AddStaticEntryForFileClass(This, L"Folder");
+        if (RegOpenKeyExW(HKEY_CLASSES_ROOT, L"Folder", 0, KEY_READ, &hKey) == ERROR_SUCCESS)
+        {
+            EnumerateDynamicContextHandlerForKey(This, hKey);
+            RegCloseKey(hKey);
+        }
+    }
+
+    guid = _ILGetGUIDPointer(This->dcm.apidl[0]);
+    if (guid)
+    {
+        LPOLESTR pwszCLSID;
+        WCHAR buffer[60];
+
+        wcscpy(buffer, L"CLSID\\");
+        hr = StringFromCLSID(guid, &pwszCLSID);
+        if (hr == S_OK)
+        {
+            wcscpy(&buffer[6], pwszCLSID);
+            TRACE("buffer %s\n", debugstr_w(buffer));
+            if (RegOpenKeyExW(HKEY_CLASSES_ROOT, buffer, 0, KEY_READ, &hKey) == ERROR_SUCCESS)
+            {
+                EnumerateDynamicContextHandlerForKey(This, hKey);
+                SH_AddStaticEntryForFileClass(This, buffer);
+                RegCloseKey(hKey);
+            }
+            CoTaskMemFree(pwszCLSID);
+        }
+    }
+
+
+    if (_ILIsDrive(This->dcm.apidl[0]))
+    {
+        SH_AddStaticEntryForFileClass(This, L"Drive");
+        if (RegOpenKeyExW(HKEY_CLASSES_ROOT, L"Drive", 0, KEY_READ, &hKey) == ERROR_SUCCESS)
+        {
+            EnumerateDynamicContextHandlerForKey(This, hKey);
+            RegCloseKey(hKey);
+        }
+    }
+    
+
+    /* add static actions */
+    rfg = SFGAO_BROWSABLE | SFGAO_CANCOPY | SFGAO_CANLINK | SFGAO_CANMOVE | SFGAO_CANDELETE | SFGAO_CANRENAME | SFGAO_HASPROPSHEET | SFGAO_FILESYSTEM;
+	hr = IShellFolder_GetAttributesOf(This->dcm.psf, This->dcm.cidl, This->dcm.apidl, &rfg);
+    if (!SUCCEEDED(hr))
+        rfg = 0;
+
+    if (rfg & SFGAO_FILESYSTEM)
+    {
+        if (RegOpenKeyExW(HKEY_CLASSES_ROOT, L"AllFilesystemObjects", 0, KEY_READ, &hKey) == ERROR_SUCCESS)
+        {
+            /* sendto service is registered there */
+            EnumerateDynamicContextHandlerForKey(This, hKey);
+            RegCloseKey(hKey);
+        }
+    }
+
+    /* add static context menu handlers */
+    indexMenu = AddStaticContextMenusToMenu(hMenu, 0, This);
+    /* now process dynamic context menu handlers */
+    indexMenu = InsertMenuItemsOfDynamicContextMenuExtension(This, hMenu, indexMenu, iIdCmdFirst, iIdCmdLast);
+    TRACE("indexMenu %d\n", indexMenu);
+
+    hLocalMenu = LoadMenuW(shell32_hInstance, L"MENU_SHV_FILE");
+    if (!hLocalMenu)
+    {
+        return iIdCmdLast;
+    }
+
+	if (rfg & (SFGAO_CANCOPY | SFGAO_CANMOVE))
+	{
+	      _InsertMenuItem(hMenu, indexMenu++, TRUE, 0, MFT_SEPARATOR, NULL, 0);
+          if (rfg & SFGAO_CANMOVE)
+	          _InsertMenuItem(hMenu, indexMenu++, TRUE, FCIDM_SHVIEW_CUT, MFT_STRING, GetLocalizedString(hLocalMenu, FCIDM_SHVIEW_CUT, sBuffer), MFS_ENABLED);
+		      if (rfg & SFGAO_CANCOPY)
+	          _InsertMenuItem(hMenu, indexMenu++, TRUE, FCIDM_SHVIEW_COPY, MFT_STRING, GetLocalizedString(hLocalMenu, FCIDM_SHVIEW_COPY, sBuffer), MFS_ENABLED);
+	}
+
+    bAddSep = TRUE;
+    if (rfg & SFGAO_CANLINK)
+    {
+        bAddSep = FALSE;
+        _InsertMenuItem(hMenu, indexMenu++, TRUE, 0, MFT_SEPARATOR, NULL, 0);
+        _InsertMenuItem(hMenu, indexMenu++, TRUE, FCIDM_SHVIEW_CREATELINK, MFT_STRING, GetLocalizedString(hLocalMenu, FCIDM_SHVIEW_CREATELINK, sBuffer), MFS_ENABLED);
+    }
+
+
+    if (rfg & SFGAO_CANDELETE)
+	{
+        if (bAddSep)
+        {
+            bAddSep = FALSE;
+            _InsertMenuItem(hMenu, indexMenu++, TRUE, 0, MFT_SEPARATOR, NULL, 0);
+        }
+        _InsertMenuItem(hMenu, indexMenu++, TRUE, FCIDM_SHVIEW_DELETE, MFT_STRING, GetLocalizedString(hLocalMenu, FCIDM_SHVIEW_DELETE, sBuffer), MFS_ENABLED);
+	}
+
+    if (rfg & SFGAO_CANRENAME)
+    {
+        if (bAddSep)
+        {
+            bAddSep = FALSE;
+            _InsertMenuItem(hMenu, indexMenu++, TRUE, 0, MFT_SEPARATOR, NULL, 0);
+        }
+        _InsertMenuItem(hMenu, indexMenu++, TRUE, FCIDM_SHVIEW_RENAME, MFT_STRING, GetLocalizedString(hLocalMenu, FCIDM_SHVIEW_RENAME, sBuffer), MFS_ENABLED);
+    }
+
+    _InsertMenuItem(hMenu, indexMenu++, TRUE, 0, MFT_SEPARATOR, NULL, 0);
+    _InsertMenuItem(hMenu, indexMenu++, TRUE, FCIDM_SHVIEW_PROPERTIES, MFT_STRING, GetLocalizedString(hLocalMenu, FCIDM_SHVIEW_PROPERTIES, sBuffer), MFS_ENABLED);
+
+    DestroyMenu(hLocalMenu);
+    return iIdCmdLast;
+}
+
+static
+HRESULT
+WINAPI
+IDefaultContextMenu_fnQueryContextMenu(
+	IContextMenu2 *iface,
+	HMENU hmenu,
+	UINT indexMenu,
+	UINT idCmdFirst,
+	UINT idCmdLast,
+	UINT uFlags)
+{
+    IDefaultContextMenuImpl * This = impl_from_IContextMenu(iface);
+
+    if (This->dcm.cidl)
+    {
+        idCmdFirst = BuildShellItemContextMenu(This, hmenu, idCmdFirst, idCmdLast, uFlags);
+    }
+    else
+    {
+        idCmdFirst = BuildBackgroundContextMenu(This, hmenu, idCmdFirst, idCmdLast, uFlags);
+    }
+
+    return S_OK;
+}
+
+static
+HRESULT
+NotifyShellViewWindow(LPCMINVOKECOMMANDINFO lpcmi)
+{
+	LPSHELLBROWSER	lpSB;
+	LPSHELLVIEW lpSV = NULL;
+    HWND hwndSV = NULL;
+
+	if((lpSB = (LPSHELLBROWSER)SendMessageA(lpcmi->hwnd, CWM_GETISHELLBROWSER,0,0)))
+	{
+        if(SUCCEEDED(IShellBrowser_QueryActiveShellView(lpSB, &lpSV)))
+        {
+            IShellView_GetWindow(lpSV, &hwndSV);
+        }
+	}
+
+    if (LOWORD(lpcmi->lpVerb) == FCIDM_SHVIEW_REFRESH)
+    {
+        if (lpSV)
+            IShellView_Refresh(lpSV);
+
+        return S_OK;
+    }
+
+    SendMessageW(hwndSV, WM_COMMAND, MAKEWPARAM(LOWORD(lpcmi->lpVerb), 0), 0);
+
+    return S_OK;
+}
+
+static
+HRESULT
+DoPaste(
+	IDefaultContextMenuImpl *iface,
+	LPCMINVOKECOMMANDINFO lpcmi)
+{
+
+
+    return E_FAIL;
+}
+
+static
+HRESULT
+DoOpenOrExplore(
+	IDefaultContextMenuImpl *iface,
+	LPCMINVOKECOMMANDINFO lpcmi)
+{
+
+
+    return E_FAIL;
+}
+
+static
+HRESULT
+DoCopyOrCut(
+	IDefaultContextMenuImpl *iface,
+	LPCMINVOKECOMMANDINFO lpcmi)
+{
+
+
+    return E_FAIL;
+}
+
+static
+HRESULT
+DoCreateLink(
+	IDefaultContextMenuImpl *iface)
+{
+
+
+    return E_FAIL;
+}
+
+static
+HRESULT
+DoDelete(
+	IDefaultContextMenuImpl *iface)
+{
+
+
+    return E_FAIL;
+}
+
+static
+HRESULT
+DoRename(
+	IDefaultContextMenuImpl *iface)
+{
+
+
+    return E_FAIL;
+}
+
+static
+HRESULT
+DoProperties(
+	IDefaultContextMenuImpl *iface,
+	LPCMINVOKECOMMANDINFO lpcmi)
+{
+
+
+    return E_FAIL;
+}
+
+static
+HRESULT
+DoDynamicShellExtensions(
+	IDefaultContextMenuImpl *iface,
+	LPCMINVOKECOMMANDINFO lpcmi)
+{
+
+
+    return E_FAIL;
+}
+
+
+static
+HRESULT
+DoStaticShellExtensions(
+	IDefaultContextMenuImpl *This,
+	LPCMINVOKECOMMANDINFO lpcmi)
+{
+    SHELLEXECUTEINFOW sei;
+    PStaticShellEntry pCurrent = This->shead;
+    int verb = LOWORD(lpcmi->lpVerb) - This->iIdSCMFirst;
+
+    
+    while(pCurrent && verb-- > 0)
+       pCurrent = pCurrent->Next;
+
+    if (verb > 0)
+        return E_FAIL;
+
+
+	ZeroMemory(&sei, sizeof(sei));
+	sei.cbSize = sizeof(sei);
+	sei.fMask = SEE_MASK_CLASSNAME;
+	sei.lpClass = pCurrent->szClass;
+	sei.hwnd = lpcmi->hwnd;
+	sei.nShow = SW_SHOWNORMAL;
+	sei.lpVerb = pCurrent->szVerb;
+	ShellExecuteExW(&sei);
+    return S_OK;    
+
+
+}
+
+static
+HRESULT
+WINAPI
+IDefaultContextMenu_fnInvokeCommand(
+	IContextMenu2 *iface,
+	LPCMINVOKECOMMANDINFO lpcmi)
+{
+    IDefaultContextMenuImpl * This = impl_from_IContextMenu(iface);
+
+    switch(LOWORD(lpcmi->lpVerb))
+    {
+        case FCIDM_SHVIEW_BIGICON:
+        case FCIDM_SHVIEW_SMALLICON:
+        case FCIDM_SHVIEW_LISTVIEW:
+        case FCIDM_SHVIEW_REPORTVIEW:
+        case 0x30: /* FIX IDS in resource files */
+        case 0x31:
+        case 0x32:
+        case 0x33:
+        case FCIDM_SHVIEW_AUTOARRANGE:
+        case FCIDM_SHVIEW_SNAPTOGRID:
+        case FCIDM_SHVIEW_REFRESH:
+            return NotifyShellViewWindow(lpcmi);
+        case FCIDM_SHVIEW_INSERT:
+        case FCIDM_SHVIEW_INSERTLINK:
+            return DoPaste(This, lpcmi);
+        case FCIDM_SHVIEW_OPEN:
+        case FCIDM_SHVIEW_EXPLORE:
+            return DoOpenOrExplore(This, lpcmi);
+        case FCIDM_SHVIEW_COPY:
+        case FCIDM_SHVIEW_CUT:
+            return DoCopyOrCut(This, lpcmi);
+        case FCIDM_SHVIEW_CREATELINK:
+            return DoCreateLink(This);
+        case FCIDM_SHVIEW_DELETE:
+            return DoDelete(This);
+        case FCIDM_SHVIEW_RENAME:
+            return DoRename(This);
+        case FCIDM_SHVIEW_PROPERTIES:
+            return DoProperties(This, lpcmi);
+    }
+
+    if (This->iIdSHEFirst && This->iIdSHELast)
+    {
+        if (LOWORD(lpcmi->lpVerb) >= This->iIdSHEFirst && LOWORD(lpcmi->lpVerb) <= This->iIdSHELast)
+        {
+            return DoDynamicShellExtensions(This, lpcmi);
+        }
+    }
+
+    if (This->iIdSCMFirst && This->iIdSCMLast)
+    {
+        if (LOWORD(lpcmi->lpVerb) >= This->iIdSCMFirst && LOWORD(lpcmi->lpVerb) <= This->iIdSCMLast)
+        {
+            return DoStaticShellExtensions(This, lpcmi);
+        }
+    }
+
+    FIXME("Unhandled Verb %xl\n",LOWORD(lpcmi->lpVerb));
+    return E_UNEXPECTED;
+}
+
+static
+HRESULT
+WINAPI
+IDefaultContextMenu_fnGetCommandString(
+	IContextMenu2 *iface,
+	UINT_PTR idCommand,
+	UINT uFlags,
+	UINT* lpReserved,
+	LPSTR lpszName,
+	UINT uMaxNameLen)
+{
+
+    return S_OK;
+}
+
+static
+HRESULT
+WINAPI
+IDefaultContextMenu_fnHandleMenuMsg(
+	IContextMenu2 *iface,
+	UINT uMsg,
+	WPARAM wParam,
+	LPARAM lParam)
+{
+
+    return S_OK;
+}
+
+static const IContextMenu2Vtbl cmvt =
+{
+	IDefaultContextMenu_fnQueryInterface,
+	IDefaultContextMenu_fnAddRef,
+	IDefaultContextMenu_fnRelease,
+	IDefaultContextMenu_fnQueryContextMenu,
+	IDefaultContextMenu_fnInvokeCommand,
+	IDefaultContextMenu_fnGetCommandString,
+	IDefaultContextMenu_fnHandleMenuMsg
+};
+
+static 
+HRESULT
+IDefaultContextMenu_Constructor( 
+	const DEFCONTEXTMENU *pdcm,
+	REFIID riid,
+	void **ppv)
+{
+   IDefaultContextMenuImpl * This;
+   HRESULT hr = E_FAIL;
+   IDataObject * pDataObj;
+
+   This = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDefaultContextMenuImpl));
+   if (This)
+   {
+       This->lpVtbl = &cmvt;
+       This->ref = 1;
+       TRACE("cidl %u\n", This->dcm.cidl);
+       if (SUCCEEDED(SHCreateDataObject(pdcm->pidlFolder, pdcm->cidl, pdcm->apidl, NULL, &IID_IDataObject, (void**)&pDataObj)))
+       {
+            This->pDataObj = pDataObj;
+       }
+       CopyMemory(&This->dcm, pdcm, sizeof(DEFCONTEXTMENU));
+       hr = IDefaultContextMenu_fnQueryInterface((IContextMenu2*)This, riid, ppv);
+   }
+
+   TRACE("This(%p)(%x) cidl %u\n",This, hr, This->dcm.cidl);
+   return hr;
+}
+
+
+/*************************************************************************
+ * SHCreateDefaultContextMenu			[SHELL32.325] Vista API
+ *
+ */
+
+HRESULT
+WINAPI
+SHCreateDefaultContextMenu(
+	const DEFCONTEXTMENU *pdcm,
+	REFIID riid,
+	void **ppv)
+{
+#if 1
+   HRESULT hr = E_FAIL;
+
+   *ppv = NULL;
+   hr = IDefaultContextMenu_Constructor( pdcm, riid, ppv );
+
+   TRACE("pcm %p hr %x\n", pdcm, hr);
+   return hr;
+#else
+   HRESULT hr;
+   IContextMenu2 * pcm;
+
+   if (pdcm->cidl > 0)
+      pcm = ISvItemCm_Constructor( pdcm->psf, pdcm->pidlFolder, pdcm->apidl, pdcm->cidl );
+   else
+      pcm = ISvBgCm_Constructor( pdcm->psf, TRUE );
+
+   hr = S_OK;
+   *ppv = pcm;
+
+   return hr;
+#endif
+}
+
+/*************************************************************************
+ * CDefFolderMenu_Create2			[SHELL32.701]
+ *
+ */
+
+INT
+WINAPI
+CDefFolderMenu_Create2(
+	LPCITEMIDLIST pidlFolder,
+	HWND hwnd,
+	UINT cidl,
+	LPCITEMIDLIST *apidl,
+	IShellFolder *psf,
+	LPFNDFMCALLBACK lpfn,
+	UINT nKeys,
+	HKEY *ahkeyClsKeys,
+	IContextMenu **ppcm)
+{
+   DEFCONTEXTMENU pdcm;
+   HRESULT hr;
+
+   pdcm.hwnd = hwnd;
+   pdcm.pcmcb = NULL;
+   pdcm.pidlFolder = pidlFolder;
+   pdcm.psf = psf;
+   pdcm.cidl = cidl;
+   pdcm.apidl = apidl;
+   pdcm.punkAssociationInfo = NULL;
+   pdcm.cKeys = nKeys;
+   pdcm.aKeys = ahkeyClsKeys;
+
+   hr = SHCreateDefaultContextMenu(&pdcm, &IID_IContextMenu, (void**)ppcm);
+   return hr;
+}
+

Propchange: trunk/reactos/dll/win32/shell32/shv_default_context_menu.c
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: trunk/reactos/dll/win32/shell32/shv_item_cmenu.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/shell32/shv_item_cmenu.c?rev=31547&r1=31546&r2=31547&view=diff
==============================================================================
--- trunk/reactos/dll/win32/shell32/shv_item_cmenu.c (original)
+++ trunk/reactos/dll/win32/shell32/shv_item_cmenu.c Wed Jan  2 02:34:28 2008
@@ -1262,62 +1262,3 @@
    RegCloseKey(hKey);
    return index;
 }
-
-/*************************************************************************
- * SHCreateDefaultContextMenu			[SHELL32.325] Vista API
- *
- */
-
-HRESULT WINAPI SHCreateDefaultContextMenu(
-	const DEFCONTEXTMENU *pdcm,
-	REFIID riid,
-	void **ppv)
-{
-   HRESULT hr;
-   IContextMenu2 * pcm;
-
-   if (pdcm->cidl > 0)
-      pcm = ISvItemCm_Constructor( pdcm->psf, pdcm->pidlFolder, pdcm->apidl, pdcm->cidl );
-   else
-      pcm = ISvBgCm_Constructor( pdcm->psf, TRUE );
-
-   hr = S_OK;
-   *ppv = pcm;
-
-   return hr;
-}
-
-/*************************************************************************
- * CDefFolderMenu_Create2			[SHELL32.701]
- *
- */
-
-INT 
-WINAPI
-CDefFolderMenu_Create2(
-	LPCITEMIDLIST pidlFolder,
-	HWND hwnd,
-	UINT cidl,
-	LPCITEMIDLIST *apidl,
-	IShellFolder *psf,
-	LPFNDFMCALLBACK lpfn,
-	UINT nKeys,
-	HKEY *ahkeyClsKeys,
-	IContextMenu **ppcm)
-{
-   DEFCONTEXTMENU pdcm;
-   HRESULT hr;
-
-   pdcm.hwnd = hwnd;
-   pdcm.pcmcb = NULL; //FIXME
-   pdcm.pidlFolder = pidlFolder;
-   pdcm.psf = psf;
-   pdcm.cidl = cidl;
-   pdcm.apidl = apidl;
-   pdcm.punkAssociationInfo = NULL;
-   pdcm.cKeys = nKeys;
-   pdcm.aKeys = ahkeyClsKeys;
-
-   hr = SHCreateDefaultContextMenu(&pdcm, &IID_IContextMenu, (void**)ppcm);
-   return hr;
-}




More information about the Ros-diffs mailing list