https://git.reactos.org/?p=reactos.git;a=commitdiff;h=91e63ee0b5a28f5a0e56f…
commit 91e63ee0b5a28f5a0e56f4c56b701888d12692f3
Author: Mark Jansen <mark.jansen(a)reactos.org>
AuthorDate: Thu Jul 15 22:45:19 2021 +0200
Commit: Mark Jansen <mark.jansen(a)reactos.org>
CommitDate: Fri Jul 23 22:10:30 2021 +0200
[FONTEXT] Cache attributes, handle sorting
---
dll/shellext/fontext/CDataObject.cpp | 36 ++--------
dll/shellext/fontext/CEnumFonts.cpp | 2 +-
dll/shellext/fontext/CFontCache.cpp | 86 ++++++++++++++++++++----
dll/shellext/fontext/CFontCache.hpp | 24 +++++--
dll/shellext/fontext/CFontExt.cpp | 125 +++++++++++++++++++++++++----------
dll/shellext/fontext/CFontExt.hpp | 4 +-
dll/shellext/fontext/CFontMenu.cpp | 15 ++++-
dll/shellext/fontext/fontext.cpp | 2 +-
dll/shellext/fontext/fontpidl.cpp | 2 +-
dll/shellext/fontext/fontpidl.hpp | 4 +-
sdk/include/reactos/shellutils.h | 65 ++++++++++++++++++
11 files changed, 268 insertions(+), 97 deletions(-)
diff --git a/dll/shellext/fontext/CDataObject.cpp b/dll/shellext/fontext/CDataObject.cpp
index f6851f19985..bff70910043 100644
--- a/dll/shellext/fontext/CDataObject.cpp
+++ b/dll/shellext/fontext/CDataObject.cpp
@@ -2,7 +2,7 @@
* PROJECT: ReactOS Font Shell Extension
* LICENSE: GPL-2.0-or-later (
https://spdx.org/licenses/GPL-2.0-or-later)
* PURPOSE: CFontMenu implementation
- * COPYRIGHT: Copyright 2019,2020 Mark Jansen (mark.jansen(a)reactos.org)
+ * COPYRIGHT: Copyright 2019-2021 Mark Jansen <mark.jansen(a)reactos.org>
*/
#include "precomp.h"
@@ -58,7 +58,7 @@ HRESULT _CDataObject_CreateInstance(PCIDLIST_ABSOLUTE folder, UINT cidl,
PCUITEM
const FontPidlEntry* fontEntry = _FontFromIL(apidl[n]);
if (fontEntry)
{
- CStringW File = g_FontCache->Filename(fontEntry, true);
+ CStringW File = g_FontCache->Filename(g_FontCache->Find(fontEntry),
true);
if (!File.IsEmpty())
{
// Now append the path (+ nullterminator) to the buffer
@@ -94,36 +94,8 @@ HRESULT _CDataObject_CreateInstance(PCIDLIST_ABSOLUTE folder, UINT
cidl, PCUITEM
pDrop->pt.x = pDrop->pt.y = 0;
pDrop-> fNC = NULL;
- // Prepare the format descriptors
- STGMEDIUM medium = {0};
- medium.tymed = TYMED_HGLOBAL;
-
- // Copy the data to an HGLOBAL
- medium.hGlobal = GlobalAlloc(GHND, offset);
- if (medium.hGlobal)
- {
- LPVOID blob = GlobalLock(medium.hGlobal);
- if (blob)
- {
- CopyMemory(blob, (BYTE*)data, offset);
- GlobalUnlock(medium.hGlobal);
-
- CComPtr<IDataObject> spDataObject(*(IDataObject**)ppvOut);
- if (spDataObject)
- {
- FORMATETC etc = { CF_HDROP, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
- hr = spDataObject->SetData(&etc, &medium, TRUE);
- }
- }
- else
- {
- ERR("Unable to lock the hGlobal?!\n");
- }
- }
- else
- {
- ERR("Unable to allocate %u bytes for the hGlobal\n", offset);
- }
+ hr = DataObject_SetData(*(IDataObject**)ppvOut, CF_HDROP, data, offset);
+ FAILED_UNEXPECTEDLY(hr);
return hr;
}
diff --git a/dll/shellext/fontext/CEnumFonts.cpp b/dll/shellext/fontext/CEnumFonts.cpp
index 7e197187cdf..1b81a09318b 100644
--- a/dll/shellext/fontext/CEnumFonts.cpp
+++ b/dll/shellext/fontext/CEnumFonts.cpp
@@ -2,7 +2,7 @@
* PROJECT: ReactOS Font Shell Extension
* LICENSE: GPL-2.0-or-later (
https://spdx.org/licenses/GPL-2.0-or-later)
* PURPOSE: CEnumFonts implementation
- * COPYRIGHT: Copyright 2019 Mark Jansen (mark.jansen(a)reactos.org)
+ * COPYRIGHT: Copyright 2019 Mark Jansen <mark.jansen(a)reactos.org>
*/
#include "precomp.h"
diff --git a/dll/shellext/fontext/CFontCache.cpp b/dll/shellext/fontext/CFontCache.cpp
index 218be7bb638..53a7a5a6aec 100644
--- a/dll/shellext/fontext/CFontCache.cpp
+++ b/dll/shellext/fontext/CFontCache.cpp
@@ -2,7 +2,7 @@
* PROJECT: ReactOS Font Shell Extension
* LICENSE: GPL-2.0-or-later (
https://spdx.org/licenses/GPL-2.0-or-later)
* PURPOSE: font list cache handling
- * COPYRIGHT: Copyright 2019,2020 Mark Jansen (mark.jansen(a)reactos.org)
+ * COPYRIGHT: Copyright 2019-2021 Mark Jansen <mark.jansen(a)reactos.org>
*/
#include "precomp.h"
@@ -14,7 +14,11 @@ CFontCache* g_FontCache = NULL;
CFontInfo::CFontInfo(LPCWSTR name)
: m_Name(name)
, m_FileRead(false)
+ , m_AttrsRead(false)
+ , m_FileWriteTime({})
+ , m_dwFileAttributes(0)
{
+ m_FileSize.QuadPart = 0;
}
const CStringW& CFontInfo::Name() const
@@ -62,7 +66,52 @@ const CStringW& CFontInfo::File()
return m_File;
}
+void CFontInfo::ReadAttrs()
+{
+ CStringW File = g_FontCache->Filename(this, true);
+
+ m_AttrsRead = true;
+
+ WIN32_FIND_DATAW findFileData;
+ HANDLE hFile = FindFirstFileW(File, &findFileData);
+ if (hFile != INVALID_HANDLE_VALUE)
+ {
+
+ // File write time
+ FileTimeToLocalFileTime(&findFileData.ftLastWriteTime,
&m_FileWriteTime);
+
+ // File size
+ m_FileSize.HighPart = findFileData.nFileSizeHigh;
+ m_FileSize.LowPart = findFileData.nFileSizeLow;
+
+ m_dwFileAttributes = findFileData.dwFileAttributes;
+ FindClose(hFile);
+ }
+}
+
+const LARGE_INTEGER& CFontInfo::FileSize()
+{
+ if (!m_AttrsRead)
+ ReadAttrs();
+
+ return m_FileSize;
+}
+
+const FILETIME& CFontInfo::FileWriteTime()
+{
+ if (!m_AttrsRead)
+ ReadAttrs();
+
+ return m_FileWriteTime;
+}
+
+DWORD CFontInfo::FileAttributes()
+{
+ if (!m_AttrsRead)
+ ReadAttrs();
+ return m_dwFileAttributes;
+}
CFontCache::CFontCache()
{
@@ -93,30 +142,39 @@ CStringW CFontCache::Name(size_t Index)
return m_Fonts[Index].Name();
}
-CStringW CFontCache::Filename(const FontPidlEntry* fontEntry, bool alwaysFullPath)
+CFontInfo* CFontCache::Find(const FontPidlEntry* fontEntry)
{
- CStringW File;
-
if (fontEntry->Index < m_Fonts.GetCount())
{
- CFontInfo& info = m_Fonts[fontEntry->Index];
-
- if (info.Name().CompareNoCase(fontEntry->Name) == 0)
- File = info.File();
+ if (m_Fonts[fontEntry->Index].Name().CompareNoCase(fontEntry->Name) == 0)
+ return &m_Fonts[fontEntry->Index];
}
- for (UINT n = 0; File.IsEmpty() && n < Size(); ++n)
+ for (UINT n = 0; n < Size(); ++n)
{
if (m_Fonts[n].Name().CompareNoCase(fontEntry->Name) == 0)
- File = m_Fonts[n].File();
+ {
+ return &m_Fonts[n];
+ }
}
+ return nullptr;
+}
- if (!File.IsEmpty() && alwaysFullPath)
+
+CStringW CFontCache::Filename(CFontInfo* info, bool alwaysFullPath)
+{
+ CStringW File;
+ if (info)
{
- // Ensure this is a full path
- if (PathIsRelativeW(File))
+ File = info->File();
+
+ if (!File.IsEmpty() && alwaysFullPath)
{
- File = m_FontFolderPath + File;
+ // Ensure this is a full path
+ if (PathIsRelativeW(File))
+ {
+ File = m_FontFolderPath + File;
+ }
}
}
diff --git a/dll/shellext/fontext/CFontCache.hpp b/dll/shellext/fontext/CFontCache.hpp
index 9454660a653..e047e6b4b1d 100644
--- a/dll/shellext/fontext/CFontCache.hpp
+++ b/dll/shellext/fontext/CFontCache.hpp
@@ -2,7 +2,7 @@
* PROJECT: ReactOS Font Shell Extension
* LICENSE: GPL-2.0-or-later (
https://spdx.org/licenses/GPL-2.0-or-later)
* PURPOSE: font list cache handling
- * COPYRIGHT: Copyright 2019,2020 Mark Jansen (mark.jansen(a)reactos.org)
+ * COPYRIGHT: Copyright 2019-2021 Mark Jansen <mark.jansen(a)reactos.org>
*/
#pragma once
@@ -14,12 +14,24 @@ private:
CStringW m_Name;
CStringW m_File;
bool m_FileRead;
+
+ bool m_AttrsRead;
+ LARGE_INTEGER m_FileSize;
+ FILETIME m_FileWriteTime;
+ DWORD m_dwFileAttributes;
+
+ void ReadAttrs();
+
public:
CFontInfo(LPCWSTR name = L"");
- const CStringW& Name() const;
- const CStringW& File();
+ const CStringW& Name() const; // Font display name stored in the registry
const bool Valid() const;
+
+ const CStringW& File(); // Full path or file, depending on how it's
stored in the registry
+ const LARGE_INTEGER& FileSize();
+ const FILETIME& FileWriteTime();
+ DWORD FileAttributes();
};
@@ -40,8 +52,10 @@ public:
const CStringW& FontPath() const { return m_FontFolderPath; }
size_t Size();
- CStringW Name(size_t Index);
- CStringW Filename(const FontPidlEntry* fontEntry, bool alwaysFullPath = false);
+ CStringW Name(size_t Index); // Font display name stored in the registry
+
+ CFontInfo* Find(const FontPidlEntry* fontEntry);
+ CStringW Filename(CFontInfo* info, bool alwaysFullPath = false);
friend class CFontExtModule;
};
diff --git a/dll/shellext/fontext/CFontExt.cpp b/dll/shellext/fontext/CFontExt.cpp
index 03d03f420b1..b2681055cd2 100644
--- a/dll/shellext/fontext/CFontExt.cpp
+++ b/dll/shellext/fontext/CFontExt.cpp
@@ -2,7 +2,7 @@
* PROJECT: ReactOS Font Shell Extension
* LICENSE: GPL-2.0-or-later (
https://spdx.org/licenses/GPL-2.0-or-later)
* PURPOSE: CFontExt implementation
- * COPYRIGHT: Copyright 2019,2020 Mark Jansen (mark.jansen(a)reactos.org)
+ * COPYRIGHT: Copyright 2019-2021 Mark Jansen <mark.jansen(a)reactos.org>
* Copyright 2019 Katayama Hirofumi MZ (katayama.hirofumi.mz(a)gmail.com)
*/
@@ -11,6 +11,9 @@
WINE_DEFAULT_DEBUG_CHANNEL(fontext);
+#ifndef SHCIDS_ALLFIELDS
+#define SHCIDS_ALLFIELDS 0x80000000L
+#endif
struct FolderViewColumns
{
@@ -20,6 +23,15 @@ struct FolderViewColumns
int fmt;
};
+enum font_columns
+{
+ FONTEXT_COL_NAME,
+ FONTEXT_COL_FILENAME,
+ FONTEXT_COL_SIZE,
+ FONTEXT_COL_MODIFIED,
+ FONTEXT_COL_ATTR,
+};
+
static FolderViewColumns g_ColumnDefs[] =
{
{ IDS_COL_NAME, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, 25, LVCFMT_LEFT
},
@@ -140,7 +152,7 @@ STDMETHODIMP CFontExt::GetDetailsOf(PCUITEMID_CHILD pidl, UINT
iColumn, SHELLDET
}
// Name, ReactOS specific?
- if (iColumn == 0)
+ if (iColumn == FONTEXT_COL_NAME)
return GetDisplayNameOf(pidl, 0, &psd->str);
const FontPidlEntry* fontEntry = _FontFromIL(pidl);
@@ -151,41 +163,28 @@ STDMETHODIMP CFontExt::GetDetailsOf(PCUITEMID_CHILD pidl, UINT
iColumn, SHELLDET
}
// If we got here, we are in details view!
- // Let's see if we got info about this file that we can re-use
- if (m_LastDetailsFontName != fontEntry->Name)
+ auto info = g_FontCache->Find(fontEntry);
+ if (info == nullptr)
{
- CStringW File = g_FontCache->Filename(fontEntry, true);
- HANDLE hFile = FindFirstFileW(File, &m_LastDetailsFileData);
- if (hFile == INVALID_HANDLE_VALUE)
- {
- m_LastDetailsFontName.Empty();
- ERR("Unable to query info about %S\n", File.GetString());
- return HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
- }
- FindClose(hFile);
- m_LastDetailsFontName = fontEntry->Name;
+ ERR("Unable to query info about %S\n", fontEntry->Name);
+ return HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
}
- // Most code borrowed from CFSFolder::GetDetailsOf
- FILETIME lft;
- SYSTEMTIME time;
int ret;
- LARGE_INTEGER FileSize;
CStringA AttrLetters;
+ DWORD dwAttributes;
+ SYSTEMTIME time;
switch (iColumn)
{
- case 1: // Filename
- return SHSetStrRet(&psd->str, m_LastDetailsFileData.cFileName);
- case 2: // Size
+ case FONTEXT_COL_FILENAME:
+ return SHSetStrRet(&psd->str, PathFindFileNameW(info->File()));
+ case FONTEXT_COL_SIZE:
psd->str.uType = STRRET_CSTR;
- FileSize.HighPart = m_LastDetailsFileData.nFileSizeHigh;
- FileSize.LowPart = m_LastDetailsFileData.nFileSizeLow;
- StrFormatKBSizeA(FileSize.QuadPart, psd->str.cStr, MAX_PATH);
+ StrFormatKBSizeA(info->FileSize().QuadPart, psd->str.cStr, MAX_PATH);
return S_OK;
- case 3: // Modified
- FileTimeToLocalFileTime(&m_LastDetailsFileData.ftLastWriteTime, &lft);
- FileTimeToSystemTime (&lft, &time);
+ case FONTEXT_COL_MODIFIED:
psd->str.uType = STRRET_CSTR;
+ FileTimeToSystemTime(&info->FileWriteTime(), &time);
ret = GetDateFormatA(LOCALE_USER_DEFAULT, DATE_SHORTDATE, &time, NULL,
psd->str.cStr, MAX_PATH);
if (ret < 1)
{
@@ -195,7 +194,7 @@ STDMETHODIMP CFontExt::GetDetailsOf(PCUITEMID_CHILD pidl, UINT
iColumn, SHELLDET
psd->str.cStr[ret-1] = ' ';
GetTimeFormatA(LOCALE_USER_DEFAULT, TIME_NOSECONDS, &time, NULL,
&psd->str.cStr[ret], MAX_PATH - ret);
return S_OK;
- case 4: // Attributes
+ case FONTEXT_COL_ATTR:
AttrLetters.LoadString(IDS_COL_ATTR_LETTERS);
if (AttrLetters.GetLength() != 5)
{
@@ -203,16 +202,17 @@ STDMETHODIMP CFontExt::GetDetailsOf(PCUITEMID_CHILD pidl, UINT
iColumn, SHELLDET
return E_FAIL;
}
psd->str.uType = STRRET_CSTR;
+ dwAttributes = info->FileAttributes();
ret = 0;
- if (m_LastDetailsFileData.dwFileAttributes & FILE_ATTRIBUTE_READONLY)
+ if (dwAttributes & FILE_ATTRIBUTE_READONLY)
psd->str.cStr[ret++] = AttrLetters[0];
- if (m_LastDetailsFileData.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN)
+ if (dwAttributes & FILE_ATTRIBUTE_HIDDEN)
psd->str.cStr[ret++] = AttrLetters[1];
- if (m_LastDetailsFileData.dwFileAttributes & FILE_ATTRIBUTE_SYSTEM)
+ if (dwAttributes & FILE_ATTRIBUTE_SYSTEM)
psd->str.cStr[ret++] = AttrLetters[2];
- if (m_LastDetailsFileData.dwFileAttributes & FILE_ATTRIBUTE_ARCHIVE)
+ if (dwAttributes & FILE_ATTRIBUTE_ARCHIVE)
psd->str.cStr[ret++] = AttrLetters[3];
- if (m_LastDetailsFileData.dwFileAttributes & FILE_ATTRIBUTE_COMPRESSED)
+ if (dwAttributes & FILE_ATTRIBUTE_COMPRESSED)
psd->str.cStr[ret++] = AttrLetters[4];
psd->str.cStr[ret] = '\0';
return S_OK;
@@ -262,7 +262,53 @@ STDMETHODIMP CFontExt::CompareIDs(LPARAM lParam, PCUIDLIST_RELATIVE
pidl1, PCUID
if (!fontEntry1 || !fontEntry2)
return E_INVALIDARG;
- int result = (int)fontEntry1->Index - (int)fontEntry2->Index;
+ int result;
+ DWORD sortMode = lParam & 0xFFFF0000;
+ DWORD column = lParam & 0x0000FFFF;
+ if (sortMode == SHCIDS_ALLFIELDS)
+ {
+ UNIMPLEMENTED;
+ result = (int)fontEntry1->Index - (int)fontEntry2->Index;
+ }
+ else
+ {
+ auto info1 = g_FontCache->Find(fontEntry1);
+ auto info2 = g_FontCache->Find(fontEntry2);
+
+ if (!info1 || !info2)
+ {
+ ERR("Unable to find font %S or %S in cache!\n",
fontEntry1->Name, fontEntry2->Name);
+ return E_INVALIDARG;
+ }
+
+ switch (column)
+ {
+ case 0xffff:
+ /* ROS bug? */
+ case FONTEXT_COL_NAME:
+ // These items are already ordered by name
+ result = (int)fontEntry1->Index - (int)fontEntry2->Index;
+ break;
+ case FONTEXT_COL_FILENAME:
+ result = wcsicmp(PathFindFileNameW(info1->File()),
PathFindFileNameW(info2->File()));
+ break;
+ case FONTEXT_COL_SIZE:
+ result = (int)info1->FileSize().HighPart - info2->FileSize().HighPart;
+ if (result == 0)
+ result = (int)info1->FileSize().LowPart -
info2->FileSize().LowPart;
+ break;
+ case FONTEXT_COL_MODIFIED:
+ result = CompareFileTime(&info1->FileWriteTime(),
&info2->FileWriteTime());
+ break;
+ case FONTEXT_COL_ATTR:
+ // FIXME: how to compare attributes?
+ result = (int)info1->FileAttributes() - info2->FileAttributes();
+ break;
+ default:
+ ERR("Unimplemented column %u\n", column);
+ return E_INVALIDARG;
+ }
+ }
return MAKE_COMPARE_HRESULT(result);
}
@@ -341,7 +387,7 @@ STDMETHODIMP CFontExt::GetUIObjectOf(HWND hwndOwner, UINT cidl,
PCUITEMID_CHILD_
if (fontEntry)
{
DWORD dwAttributes = FILE_ATTRIBUTE_NORMAL;
- CStringW File = g_FontCache->Filename(fontEntry);
+ CStringW File =
g_FontCache->Filename(g_FontCache->Find(fontEntry));
// Just create a default icon extractor based on the filename
// We might want to create a preview with the font to get really fancy
one day.
return SHCreateFileExtractIconW(File, dwAttributes, riid, ppvOut);
@@ -385,6 +431,15 @@ STDMETHODIMP CFontExt::GetDisplayNameOf(PCUITEMID_CHILD pidl, DWORD
dwFlags, LPS
if (!fontEntry)
return E_FAIL;
+ if (dwFlags == SHGDN_FORPARSING)
+ {
+ CStringW File = g_FontCache->Filename(g_FontCache->Find(fontEntry), true);
+ if (!File.IsEmpty())
+ {
+ return SHSetStrRet(strRet, File);
+ }
+ }
+
return SHSetStrRet(strRet, fontEntry->Name);
}
diff --git a/dll/shellext/fontext/CFontExt.hpp b/dll/shellext/fontext/CFontExt.hpp
index ba868628957..a3e5431c90f 100644
--- a/dll/shellext/fontext/CFontExt.hpp
+++ b/dll/shellext/fontext/CFontExt.hpp
@@ -2,7 +2,7 @@
* PROJECT: ReactOS Font Shell Extension
* LICENSE: GPL-2.0-or-later (
https://spdx.org/licenses/GPL-2.0-or-later)
* PURPOSE: CFontExt definition
- * COPYRIGHT: Copyright 2019,2020 Mark Jansen (mark.jansen(a)reactos.org)
+ * COPYRIGHT: Copyright 2019,2020 Mark Jansen <mark.jansen(a)reactos.org>
* Copyright 2019 Katayama Hirofumi MZ (katayama.hirofumi.mz(a)gmail.com)
*/
@@ -16,8 +16,6 @@ class CFontExt :
public IDropTarget
{
CComHeapPtr<ITEMIDLIST> m_Folder;
- CStringW m_LastDetailsFontName;
- WIN32_FIND_DATAW m_LastDetailsFileData;
public:
diff --git a/dll/shellext/fontext/CFontMenu.cpp b/dll/shellext/fontext/CFontMenu.cpp
index 05b968e27d3..62464a099ee 100644
--- a/dll/shellext/fontext/CFontMenu.cpp
+++ b/dll/shellext/fontext/CFontMenu.cpp
@@ -2,7 +2,7 @@
* PROJECT: ReactOS Font Shell Extension
* LICENSE: GPL-2.0-or-later (
https://spdx.org/licenses/GPL-2.0-or-later)
* PURPOSE: CFontMenu implementation
- * COPYRIGHT: Copyright 2019,2020 Mark Jansen (mark.jansen(a)reactos.org)
+ * COPYRIGHT: Copyright 2019,2020 Mark Jansen <mark.jansen(a)reactos.org>
*/
#include "precomp.h"
@@ -69,7 +69,7 @@ static void RunFontViewer(HWND hwnd, const FontPidlEntry* fontEntry)
WCHAR FontViewerPath[MAX_PATH] = L"%SystemRoot%\\System32\\fontview.exe";
WCHAR FontPathArg[MAX_PATH + 3];
- CStringW Path = g_FontCache->Filename(fontEntry, true);
+ CStringW Path = g_FontCache->Filename(g_FontCache->Find(fontEntry), true);
if (!Path.IsEmpty())
{
// '/d' disables the install button
@@ -108,7 +108,7 @@ static HRESULT CALLBACK FontFolderMenuCallback(IShellFolder *psf, HWND
hwnd, IDa
return S_OK;
}
case DFM_INVOKECOMMAND:
- // Preview is the only item we can handle
+ // Preview is the only item we handle
if (wParam == 0)
{
CComHeapPtr<CIDA> cida;
@@ -123,6 +123,15 @@ static HRESULT CALLBACK FontFolderMenuCallback(IShellFolder *psf,
HWND hwnd, IDa
}
return S_OK;
}
+ else if (wParam == DFM_CMD_PROPERTIES)
+ {
+ ERR("Default properties handling!\n");
+ return S_FALSE;
+ }
+ else
+ {
+ ERR("Unhandled DFM_INVOKECOMMAND(wParam=0x%x)\n", wParam);
+ }
return S_FALSE;
case DFM_INVOKECOMMANDEX:
diff --git a/dll/shellext/fontext/fontext.cpp b/dll/shellext/fontext/fontext.cpp
index d3659199e2d..0b68e40a7cb 100644
--- a/dll/shellext/fontext/fontext.cpp
+++ b/dll/shellext/fontext/fontext.cpp
@@ -2,7 +2,7 @@
* PROJECT: ReactOS Font Shell Extension
* LICENSE: GPL-2.0-or-later (
https://spdx.org/licenses/GPL-2.0-or-later)
* PURPOSE: Shell extension entry point
- * COPYRIGHT: Copyright 2019,2020 Mark Jansen (mark.jansen(a)reactos.org)
+ * COPYRIGHT: Copyright 2019,2020 Mark Jansen <mark.jansen(a)reactos.org>
*/
#include "precomp.h"
diff --git a/dll/shellext/fontext/fontpidl.cpp b/dll/shellext/fontext/fontpidl.cpp
index 38bb7814c84..6354e848bf2 100644
--- a/dll/shellext/fontext/fontpidl.cpp
+++ b/dll/shellext/fontext/fontpidl.cpp
@@ -2,7 +2,7 @@
* PROJECT: ReactOS Font Shell Extension
* LICENSE: GPL-2.0-or-later (
https://spdx.org/licenses/GPL-2.0-or-later)
* PURPOSE: pidl handling
- * COPYRIGHT: Copyright 2019,2020 Mark Jansen (mark.jansen(a)reactos.org)
+ * COPYRIGHT: Copyright 2019,2020 Mark Jansen <mark.jansen(a)reactos.org>
*/
#include "precomp.h"
diff --git a/dll/shellext/fontext/fontpidl.hpp b/dll/shellext/fontext/fontpidl.hpp
index f5ef556ddff..1546f646f78 100644
--- a/dll/shellext/fontext/fontpidl.hpp
+++ b/dll/shellext/fontext/fontpidl.hpp
@@ -2,7 +2,7 @@
* PROJECT: ReactOS Font Shell Extension
* LICENSE: GPL-2.0-or-later (
https://spdx.org/licenses/GPL-2.0-or-later)
* PURPOSE: pidl handling
- * COPYRIGHT: Copyright 2019 Mark Jansen (mark.jansen(a)reactos.org)
+ * COPYRIGHT: Copyright 2019 Mark Jansen <mark.jansen(a)reactos.org>
*/
#pragma once
@@ -12,7 +12,7 @@ struct FontPidlEntry
{
WORD cb;
WORD Magic;
- ULONG Index; // Informative only
+ ULONG Index; // Informative only, used for sorting
WCHAR Name[1];
};
diff --git a/sdk/include/reactos/shellutils.h b/sdk/include/reactos/shellutils.h
index 82f2f708eee..c4e4026fd14 100644
--- a/sdk/include/reactos/shellutils.h
+++ b/sdk/include/reactos/shellutils.h
@@ -546,4 +546,69 @@ static inline PCUIDLIST_RELATIVE HIDA_GetPIDLItem(CIDA const* pida,
SIZE_T i)
}
+#ifdef __cplusplus
+
+inline
+HRESULT DataObject_GetData(IDataObject* pDataObject, CLIPFORMAT clipformat, PVOID
pBuffer, SIZE_T dwBufferSize)
+{
+ FORMATETC fmt = { clipformat, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
+ STGMEDIUM medium = { TYMED_NULL };
+
+ HRESULT hr = pDataObject->GetData(&fmt, &medium);
+ if (SUCCEEDED(hr))
+ {
+ LPVOID blob = GlobalLock(medium.hGlobal);
+ if (blob)
+ {
+ SIZE_T size = GlobalSize(medium.hGlobal);
+ if (size <= dwBufferSize)
+ {
+ CopyMemory(pBuffer, blob, size);
+ hr = S_OK;
+ }
+ else
+ {
+ hr = E_OUTOFMEMORY;
+ }
+ GlobalUnlock(medium.hGlobal);
+ }
+ else
+ {
+ hr = STG_E_INVALIDHANDLE;
+ }
+
+ ReleaseStgMedium(&medium);
+ }
+ return hr;
+}
+
+inline
+HRESULT DataObject_SetData(IDataObject* pDataObject, CLIPFORMAT clipformat, PVOID
pBuffer, SIZE_T dwBufferSize)
+{
+ STGMEDIUM medium = { TYMED_HGLOBAL };
+
+ medium.hGlobal = GlobalAlloc(GHND, dwBufferSize);
+ if (!medium.hGlobal)
+ return E_OUTOFMEMORY;
+
+ HRESULT hr = E_UNEXPECTED;
+ LPVOID blob = GlobalLock(medium.hGlobal);
+ if (blob)
+ {
+ CopyMemory(blob, pBuffer, dwBufferSize);
+ GlobalUnlock(medium.hGlobal);
+
+ FORMATETC etc = { clipformat, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
+ hr = pDataObject->SetData(&etc, &medium, TRUE);
+ }
+
+ if (FAILED(hr))
+ GlobalFree(medium.hGlobal);
+
+ return hr;
+}
+
+#endif
+
+
#endif /* __ROS_SHELL_UTILS_H */