Windows: afs_shl_ext folder bkgrnd context menu
authorStefan Kueng <tortoisesvn@gmail.com>
Fri, 3 Dec 2010 20:24:33 +0000 (21:24 +0100)
committerJeffrey Altman <jaltman@openafs.org>
Sun, 5 Dec 2010 19:47:08 +0000 (11:47 -0800)
Make the context menu handler also work for folder backgrounds
and on Win7 for library folder backgrounds

For folder backgrounds, the shell passes the PIDL of the folder
instead of a data object.  Extract the path from that PIDL. Also
extended the register function of the dll to add the required
registry keys.

Change-Id: I8928efd25058dced3820478a2858ce20336b4301
Reviewed-on: http://gerrit.openafs.org/3443
Tested-by: BuildBot <buildbot@rampaginggeek.com>
Tested-by: Stefan Kueng <tortoisesvn@gmail.com>
Reviewed-by: Stefan Kueng <tortoisesvn@gmail.com>
Reviewed-by: Jeffrey Altman <jaltman@openafs.org>
Tested-by: Jeffrey Altman <jaltman@openafs.org>

src/WINNT/client_exp/afs_shl_ext.cpp
src/WINNT/client_exp/shell_ext.cpp

index a6bed8e..70ef806 100644 (file)
@@ -223,6 +223,12 @@ STDAPI DllRegisterServer(void)
     wsprintf(szSubKey, TEXT("Folder\\shellex\\ContextMenuHandlers\\%s"),STR_EXT_TITLE);
     if ((lResult=DoRegCLSID(HKEY_CLASSES_ROOT,szSubKey,szCLSID))!=NOERROR)
         return lResult;
+    wsprintf(szSubKey, TEXT("Directory\\Background\\shellex\\ContextMenuHandlers\\%s"),STR_EXT_TITLE);
+    if ((lResult=DoRegCLSID(HKEY_CLASSES_ROOT,szSubKey,szCLSID))!=NOERROR)
+        return lResult;
+    wsprintf(szSubKey, TEXT("LibraryFolder\\background\\shellex\\ContextMenuHandlers\\%s"),STR_EXT_TITLE);
+    if ((lResult=DoRegCLSID(HKEY_CLASSES_ROOT,szSubKey,szCLSID))!=NOERROR)
+        return lResult;
 
     /*
     Register InfoTip
index 7f6fa1c..f821b34 100644 (file)
@@ -11,6 +11,8 @@
 #include "stdafx.h"
 #include <winsock2.h>
 #include <ws2tcpip.h>
+#include <shtypes.h>
+#include <shlwapi.h>
 
 extern "C" {
 #include <afs/param.h>
@@ -571,58 +573,87 @@ STDMETHODIMP CShellExt::XShellInit::Initialize(LPCITEMIDLIST pidlFolder, IDataOb
     STGMEDIUM medium;
 
     // We must have a data object
-    if (pdobj == NULL)
-           return E_FAIL;
+    if ((pdobj == NULL) && (pidlFolder == NULL))
+        return E_FAIL;
 
-    //  Use the given IDataObject to get a list of filenames (CF_HDROP)
-    hres = pdobj->GetData(&fmte, &medium);
-    if (FAILED(hres)) {
-       return E_FAIL;
+    if (pdobj) {
+        //  Use the given IDataObject to get a list of filenames (CF_HDROP)
+        hres = pdobj->GetData(&fmte, &medium);
+        if (FAILED(hres)) {
+        return E_FAIL;
+        }
+
+        int nNumFiles = DragQueryFile((HDROP)medium.hGlobal, 0xFFFFFFFF, NULL, 0);
+        if (nNumFiles == 0)
+            hres = E_FAIL;
+        else {
+            pThis->m_bDirSelected = FALSE;
+
+            for (int ii = 0; ii < nNumFiles; ii++) {
+                CString strFileName;
+
+                // Get the size of the file name string
+                int nNameLen = DragQueryFile((HDROP)medium.hGlobal, ii, 0, 0);
+
+                // Make room for it in our string object
+                LPTSTR pszFileNameBuf = strFileName.GetBuffer(nNameLen + 1);   // +1 for the terminating NULL
+                ASSERT(pszFileNameBuf);
+
+                // Get the file name
+                DragQueryFile((HDROP)medium.hGlobal, ii, pszFileNameBuf, nNameLen + 1);
+
+                strFileName.ReleaseBuffer();
+                if (!IsPathInAfs(strFileName)) {
+                pThis->m_astrFileNames.RemoveAll();
+                break;
+                } else {
+                pThis->m_bIsSymlink=IsSymlink(strFileName);
+                }
+
+                if (IsADir(strFileName))
+                pThis->m_bDirSelected = TRUE;
+
+                pThis->m_astrFileNames.Add(strFileName);
+            }
+            // Release the data
+            ReleaseStgMedium(&medium);
+        }
+    }
+    if ((pThis->m_astrFileNames.GetSize() == 0)&&(pidlFolder)) {
+        // if there are no valid files selected, try the folder background
+        IShellFolder *parentFolder = NULL;
+        STRRET name;
+        TCHAR * szDisplayName = NULL;
+
+        hres = ::SHGetDesktopFolder(&parentFolder);
+        if (FAILED(hres))
+            return hres;
+
+        hres = parentFolder->GetDisplayNameOf(pidlFolder, SHGDN_NORMAL | SHGDN_FORPARSING, &name);
+        if (FAILED(hres)) {
+            parentFolder->Release();
+            return hres;
+        }
+
+        hres = StrRetToStr (&name, pidlFolder, &szDisplayName);
+        if (FAILED(hres))
+            return hres;
+        parentFolder->Release();
+        if (szDisplayName) {
+            pThis->m_bDirSelected = TRUE;
+            CString strFileName = CString(szDisplayName);
+            if (IsPathInAfs(strFileName)) {
+                pThis->m_bIsSymlink=IsSymlink(strFileName);
+                pThis->m_astrFileNames.Add(strFileName);
+            }
+            CoTaskMemFree(szDisplayName);
+        }
     }
-
-    int nNumFiles = DragQueryFile((HDROP)medium.hGlobal, 0xFFFFFFFF, NULL, 0);
-    if (nNumFiles == 0)
-       hres = E_FAIL;
-    else {
-       pThis->m_bDirSelected = FALSE;
-
-       for (int ii = 0; ii < nNumFiles; ii++) {
-           CString strFileName;
-
-           // Get the size of the file name string
-           int nNameLen = DragQueryFile((HDROP)medium.hGlobal, ii, 0, 0);
-
-           // Make room for it in our string object
-           LPTSTR pszFileNameBuf = strFileName.GetBuffer(nNameLen + 1);        // +1 for the terminating NULL
-           ASSERT(pszFileNameBuf);
-
-           // Get the file name
-           DragQueryFile((HDROP)medium.hGlobal, ii, pszFileNameBuf, nNameLen + 1);
-
-           strFileName.ReleaseBuffer();
-
-           if (!IsPathInAfs(strFileName)) {
-               pThis->m_astrFileNames.RemoveAll();
-               break;
-           } else {
-               pThis->m_bIsSymlink=IsSymlink(strFileName);
-           }
-
-           if (IsADir(strFileName))
-               pThis->m_bDirSelected = TRUE;
-
-           pThis->m_astrFileNames.Add(strFileName);
-       }
-
        if (pThis->m_astrFileNames.GetSize() > 0)
            hres = NOERROR;
        else
            hres = E_FAIL;
-    }
  
-    // Release the data
-    ReleaseStgMedium(&medium);
-
     return hres;
 }
 
@@ -790,4 +821,4 @@ STDMETHODIMP CShellExt::XPersistFileExt::SaveCompleted(LPCOLESTR)
 STDMETHODIMP CShellExt::XPersistFileExt::GetCurFile(LPOLESTR FAR*)
 { 
     return E_NOTIMPL; 
-}
+}
\ No newline at end of file