[SDK][SHELL32] Augment the internally used IDataObject with some extra formats
authorMark Jansen <mark.jansen@reactos.org>
Sat, 19 Oct 2019 22:44:03 +0000 (00:44 +0200)
committerMark Jansen <mark.jansen@reactos.org>
Sun, 20 Oct 2019 15:10:12 +0000 (17:10 +0200)
This is needed because our code seems to use CF_HDROP a lot, instead of HIDA...

dll/win32/shell32/CIDLDataObj.cpp
dll/win32/shell32/folders/CControlPanelFolder.cpp
dll/win32/shell32/folders/CDesktopFolder.cpp
dll/win32/shell32/folders/CDrivesFolder.cpp
dll/win32/shell32/folders/CFSFolder.cpp
dll/win32/shell32/folders/CNetFolder.cpp
dll/win32/shell32/folders/CRegFolder.cpp
dll/win32/shell32/wine/shell32_main.h
dll/win32/shell32/wine/shellord.c
sdk/include/reactos/shellutils.h

index b1704ff..8e1993e 100644 (file)
@@ -143,7 +143,7 @@ private:
 public:
     CIDLDataObj();
     ~CIDLDataObj();
-    HRESULT WINAPI Initialize(HWND hwndOwner, PCIDLIST_ABSOLUTE pMyPidl, PCUIDLIST_RELATIVE_ARRAY apidlx, UINT cidlx);
+    HRESULT WINAPI Initialize(HWND hwndOwner, PCIDLIST_ABSOLUTE pMyPidl, PCUIDLIST_RELATIVE_ARRAY apidlx, UINT cidlx, BOOL bAddAdditionalFormats);
 
     // *** IDataObject methods ***
     virtual HRESULT WINAPI GetData(LPFORMATETC pformatetcIn, STGMEDIUM *pmedium);
@@ -187,7 +187,7 @@ CIDLDataObj::~CIDLDataObj()
     m_Storage.RemoveAll();
 }
 
-HRESULT WINAPI CIDLDataObj::Initialize(HWND hwndOwner, PCIDLIST_ABSOLUTE pMyPidl, PCUIDLIST_RELATIVE_ARRAY apidlx, UINT cidlx)
+HRESULT WINAPI CIDLDataObj::Initialize(HWND hwndOwner, PCIDLIST_ABSOLUTE pMyPidl, PCUIDLIST_RELATIVE_ARRAY apidlx, UINT cidlx, BOOL bAddAdditionalFormats)
 {
     HGLOBAL hida = RenderSHELLIDLIST((LPITEMIDLIST)pMyPidl, (LPITEMIDLIST*)apidlx, cidlx);
     if (!hida)
@@ -198,12 +198,33 @@ HRESULT WINAPI CIDLDataObj::Initialize(HWND hwndOwner, PCIDLIST_ABSOLUTE pMyPidl
 
     m_cfShellIDList = RegisterClipboardFormatW(CFSTR_SHELLIDLIST);
 
-    FORMATETC HIDAFormat = { (CLIPFORMAT)m_cfShellIDList, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
+    FORMATETC Format = { (CLIPFORMAT)m_cfShellIDList, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
     STGMEDIUM medium = {0};
     medium.tymed = TYMED_HGLOBAL;
     medium.hGlobal = hida;
+    HRESULT hr = SetData(&Format, &medium, TRUE);
+    if (!FAILED_UNEXPECTEDLY(hr) && bAddAdditionalFormats)
+    {
+        Format.cfFormat = CF_HDROP;
+        medium.hGlobal = RenderHDROP((LPITEMIDLIST)pMyPidl, (LPITEMIDLIST*)apidlx, cidlx);
+        hr = SetData(&Format, &medium, TRUE);
+        if (FAILED_UNEXPECTEDLY(hr))
+            return hr;
+
+        Format.cfFormat = RegisterClipboardFormatA(CFSTR_FILENAMEA);
+        medium.hGlobal = RenderFILENAMEA((LPITEMIDLIST)pMyPidl, (LPITEMIDLIST*)apidlx, cidlx);
+        hr = SetData(&Format, &medium, TRUE);
+        if (FAILED_UNEXPECTEDLY(hr))
+            return hr;
+
+        Format.cfFormat = RegisterClipboardFormatW(CFSTR_FILENAMEW);
+        medium.hGlobal = RenderFILENAMEW((LPITEMIDLIST)pMyPidl, (LPITEMIDLIST*)apidlx, cidlx);
+        hr = SetData(&Format, &medium, TRUE);
+        if (FAILED_UNEXPECTEDLY(hr))
+            return hr;
+    }
 
-    return SetData(&HIDAFormat, &medium, TRUE);
+    return hr;
 }
 
 
@@ -355,11 +376,11 @@ HRESULT WINAPI CIDLDataObj::EndOperation(HRESULT hResult, IBindCtx *pbcReserved,
 /**************************************************************************
  *  IDataObject_Constructor
  */
-HRESULT IDataObject_Constructor(HWND hwndOwner, PCIDLIST_ABSOLUTE pMyPidl, PCUIDLIST_RELATIVE_ARRAY apidl, UINT cidl, IDataObject **dataObject)
+HRESULT IDataObject_Constructor(HWND hwndOwner, PCIDLIST_ABSOLUTE pMyPidl, PCUIDLIST_RELATIVE_ARRAY apidl, UINT cidl, BOOL bExtendedObject, IDataObject **dataObject)
 {
     if (!dataObject)
         return E_INVALIDARG;
-    return ShellObjectCreatorInit<CIDLDataObj>(hwndOwner, pMyPidl, apidl, cidl, IID_PPV_ARG(IDataObject, dataObject));
+    return ShellObjectCreatorInit<CIDLDataObj>(hwndOwner, pMyPidl, apidl, cidl, bExtendedObject, IID_PPV_ARG(IDataObject, dataObject));
 }
 
 /*************************************************************************
@@ -373,7 +394,7 @@ HRESULT WINAPI SHCreateDataObject(PCIDLIST_ABSOLUTE pidlFolder, UINT cidl, PCUIT
     {
         if (pdtInner)
             UNIMPLEMENTED;
-        return CIDLData_CreateFromIDArray(pidlFolder, cidl, apidl, (IDataObject **)ppv);
+        return IDataObject_Constructor(NULL, pidlFolder, apidl, cidl, TRUE, (IDataObject **)ppv);
     }
     return E_FAIL;
 }
index 53bd9cb..84e2abe 100644 (file)
@@ -459,7 +459,7 @@ HRESULT WINAPI CControlPanelFolder::GetUIObjectOf(HWND hwndOwner,
             else
                 hr = m_regFolder->GetUIObjectOf(hwndOwner, cidl, apidl, riid, prgfInOut, &pObj);
         } else if (IsEqualIID(riid, IID_IDataObject) && (cidl >= 1)) {
-            hr = IDataObject_Constructor(hwndOwner, pidlRoot, apidl, cidl, (IDataObject **)&pObj);
+            hr = IDataObject_Constructor(hwndOwner, pidlRoot, apidl, cidl, TRUE, (IDataObject **)&pObj);
         } else if ((IsEqualIID(riid, IID_IExtractIconA) || IsEqualIID(riid, IID_IExtractIconW)) && (cidl == 1)) {
             if (_ILGetCPanelPointer(apidl[0]))
                 hr = CCPLExtractIcon_CreateInstance(this, apidl[0], riid, &pObj);
index 20c5f66..f2d6c32 100644 (file)
@@ -636,7 +636,7 @@ HRESULT WINAPI CDesktopFolder::GetUIObjectOf(
     }
     else if (IsEqualIID (riid, IID_IDataObject) && (cidl >= 1))
     {
-        hr = IDataObject_Constructor( hwndOwner, pidlRoot, apidl, cidl, (IDataObject **)&pObj);
+        hr = IDataObject_Constructor( hwndOwner, pidlRoot, apidl, cidl, TRUE, (IDataObject **)&pObj);
     }
     else if ((IsEqualIID (riid, IID_IExtractIconA) || IsEqualIID (riid, IID_IExtractIconW)) && (cidl == 1))
     {
index d8c35a7..35f6a7d 100644 (file)
@@ -784,7 +784,7 @@ HRESULT WINAPI CDrivesFolder::GetUIObjectOf(HWND hwndOwner,
     else if (IsEqualIID (riid, IID_IDataObject) && (cidl >= 1))
     {
         hr = IDataObject_Constructor (hwndOwner,
-                                      pidlRoot, apidl, cidl, (IDataObject **)&pObj);
+                                      pidlRoot, apidl, cidl, TRUE, (IDataObject **)&pObj);
     }
     else if ((IsEqualIID (riid, IID_IExtractIconA) || IsEqualIID (riid, IID_IExtractIconW)) && (cidl == 1))
     {
index f3c758d..a356bb9 100644 (file)
@@ -1064,7 +1064,7 @@ HRESULT WINAPI CFSFolder::GetUIObjectOf(HWND hwndOwner,
         {
             if (cidl >= 1) 
             {
-                hr = IDataObject_Constructor (hwndOwner, pidlRoot, apidl, cidl, (IDataObject **)&pObj);
+                hr = IDataObject_Constructor (hwndOwner, pidlRoot, apidl, cidl, TRUE, (IDataObject **)&pObj);
             }
             else
             {
index 93d91ab..5479ded 100644 (file)
@@ -427,7 +427,7 @@ HRESULT WINAPI CNetFolder::GetUIObjectOf(HWND hwndOwner, UINT cidl, PCUITEMID_CH
     else if (IsEqualIID(riid, IID_IDataObject) && (cidl >= 1))
     {
         IDataObject * pDo = NULL;
-        hr = IDataObject_Constructor (hwndOwner, pidlRoot, apidl, cidl, &pDo);
+        hr = IDataObject_Constructor (hwndOwner, pidlRoot, apidl, cidl, TRUE, &pDo);
         pObj = pDo;
     }
     else if ((IsEqualIID(riid, IID_IExtractIconA) || IsEqualIID(riid, IID_IExtractIconW)) && (cidl == 1))
index 3353981..6398109 100644 (file)
@@ -533,7 +533,7 @@ HRESULT WINAPI CRegFolder::GetUIObjectOf(HWND hwndOwner, UINT cidl, PCUITEMID_CH
     }
     else if (IsEqualIID (riid, IID_IDataObject) && (cidl >= 1))
     {
-        hr = IDataObject_Constructor (hwndOwner, m_pidlRoot, apidl, cidl, (IDataObject **)&pObj);
+        hr = IDataObject_Constructor (hwndOwner, m_pidlRoot, apidl, cidl, TRUE, (IDataObject **)&pObj);
     }
     else
     {
index 1653697..1585f60 100644 (file)
@@ -63,7 +63,7 @@ DWORD WINAPI ParseFieldW(LPCWSTR src, DWORD nField, LPWSTR dst, DWORD len) DECLS
 /****************************************************************************
  * Class constructors
  */
-HRESULT IDataObject_Constructor(HWND hwndOwner, LPCITEMIDLIST pMyPidl, PCUITEMID_CHILD_ARRAY apidl, UINT cidl, IDataObject **dataObject);
+HRESULT IDataObject_Constructor(HWND hwndOwner, LPCITEMIDLIST pMyPidl, PCUITEMID_CHILD_ARRAY apidl, UINT cidl, BOOL bExtendedObject, IDataObject **dataObject);
 HRESULT IEnumFORMATETC_Constructor(UINT cfmt, const FORMATETC afmt[], IEnumFORMATETC **enumerator);
 
 LPCLASSFACTORY IClassFactory_Constructor(REFCLSID);
index fac2d20..71f35e4 100644 (file)
@@ -1791,7 +1791,7 @@ HRESULT WINAPI CIDLData_CreateFromIDArray(
        pdump (pidlFolder);
        for (i=0; i<cpidlFiles; i++) pdump (lppidlFiles[i]);
     }
-    hResult = IDataObject_Constructor(hwnd, pidlFolder, lppidlFiles, cpidlFiles, ppdataObject);
+    hResult = IDataObject_Constructor(hwnd, pidlFolder, lppidlFiles, cpidlFiles, FALSE, ppdataObject);
     return hResult;
 }
 
index 2f5d72e..467f142 100644 (file)
@@ -378,6 +378,28 @@ HRESULT inline ShellObjectCreatorInit(T1 initArg1, T2 initArg2, T3 initArg3, T4
     return hResult;
 }
 
+template<class T, class T1, class T2, class T3, class T4, class T5>
+HRESULT inline ShellObjectCreatorInit(T1 initArg1, T2 initArg2, T3 initArg3, T4 initArg4, T5 initArg5, REFIID riid, void ** ppv)
+{
+    _CComObject<T> *pobj;
+    HRESULT hResult;
+
+    hResult = _CComObject<T>::CreateInstance(&pobj);
+    if (FAILED(hResult))
+        return hResult;
+
+    pobj->AddRef(); /* CreateInstance returns object with 0 ref count */
+
+    hResult = pobj->Initialize(initArg1, initArg2, initArg3, initArg4, initArg5);
+
+    if (SUCCEEDED(hResult))
+        hResult = pobj->QueryInterface(riid, reinterpret_cast<void **>(ppv));
+
+    pobj->Release(); /* In case of failure the object will be released */
+
+    return hResult;
+}
+
 HRESULT inline SHSetStrRet(LPSTRRET pStrRet, LPCSTR pstrValue)
 {
     pStrRet->uType = STRRET_CSTR;