1 /* 2 * PROJECT: ReactOS Font Shell Extension 3 * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later) 4 * PURPOSE: CFontMenu implementation 5 * COPYRIGHT: Copyright 2019-2021 Mark Jansen <mark.jansen@reactos.org> 6 */ 7 8 #include "precomp.h" 9 10 WINE_DEFAULT_DEBUG_CHANNEL(fontext); 11 12 13 #if 0 14 static inline void DumpDataObjectFormats(IDataObject* pObject) 15 { 16 CComPtr<IEnumFORMATETC> pEnumFmt; 17 HRESULT hr = pObject->EnumFormatEtc(DATADIR_GET, &pEnumFmt); 18 19 if (FAILED_UNEXPECTEDLY(hr)) 20 return; 21 22 FORMATETC fmt; 23 while (S_OK == pEnumFmt->Next(1, &fmt, NULL)) 24 { 25 char szBuf[512]; 26 GetClipboardFormatNameA(fmt.cfFormat, szBuf, sizeof(szBuf)); 27 ERR("Format: %s\n", szBuf); 28 ERR("Tymed: %u\n", fmt.tymed); 29 if (fmt.tymed & TYMED_HGLOBAL) 30 { 31 ERR("TYMED_HGLOBAL supported\n"); 32 } 33 } 34 } 35 #endif 36 37 38 HRESULT _CDataObject_CreateInstance(PCIDLIST_ABSOLUTE folder, UINT cidl, PCUITEMID_CHILD_ARRAY apidl, 39 REFIID riid, LPVOID* ppvOut) 40 { 41 HRESULT hr = CIDLData_CreateFromIDArray(folder, cidl, apidl, (IDataObject**)ppvOut); 42 if (FAILED_UNEXPECTEDLY(hr)) 43 return hr; 44 45 // Now that we have an IDataObject with the shell itemid list (CFSTR_SHELLIDLIST, aka HIDA) format 46 // we will augment this IDataObject with the CF_HDROP format. (Full filepaths) 47 // This enabled the objects for the 'copy' and drag to copy actions 48 49 CComHeapPtr<BYTE> data; 50 51 // First we allocate room for the DROPFILES structure 52 data.AllocateBytes(sizeof(DROPFILES)); 53 UINT offset = sizeof(DROPFILES); 54 55 // Then we walk all files 56 for (UINT n = 0; n < cidl; ++n) 57 { 58 const FontPidlEntry* fontEntry = _FontFromIL(apidl[n]); 59 if (fontEntry) 60 { 61 CStringW File = g_FontCache->Filename(g_FontCache->Find(fontEntry), true); 62 if (!File.IsEmpty()) 63 { 64 // Now append the path (+ nullterminator) to the buffer 65 UINT len = offset + (File.GetLength() + 1) * sizeof(WCHAR); 66 data.ReallocateBytes(len); 67 if (!data) 68 { 69 ERR("Unable to allocate memory for the CF_HDROP\n"); 70 return hr; 71 } 72 BYTE* dataPtr = data; 73 StringCbCopyW((STRSAFE_LPWSTR)(dataPtr + offset), len - offset, File); 74 offset = len; 75 } 76 else 77 { 78 ERR("No file found for %S\n", fontEntry->Name); 79 } 80 } 81 } 82 83 // Append the final nullterminator (double null terminated list) 84 data.ReallocateBytes(offset + sizeof(UNICODE_NULL)); 85 LPWSTR str = (LPWSTR)((BYTE*)data + offset); 86 *str = UNICODE_NULL; 87 offset += sizeof(UNICODE_NULL); 88 89 // Fill in the required fields 90 DROPFILES* pDrop = (DROPFILES*)(BYTE*)data; 91 pDrop->fWide = 1; 92 pDrop->pFiles = sizeof(DROPFILES); 93 // Zero out the rest 94 pDrop->pt.x = pDrop->pt.y = 0; 95 pDrop-> fNC = NULL; 96 97 hr = DataObject_SetData(*(IDataObject**)ppvOut, CF_HDROP, data, offset); 98 FAILED_UNEXPECTEDLY(hr); 99 100 return hr; 101 } 102 103