Skip to content

Commit 91e63ee

Browse files
committed
[FONTEXT] Cache attributes, handle sorting
1 parent cb9b538 commit 91e63ee

File tree

11 files changed

+268
-97
lines changed

11 files changed

+268
-97
lines changed

dll/shellext/fontext/CDataObject.cpp

Lines changed: 4 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
* PROJECT: ReactOS Font Shell Extension
33
* LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
44
* PURPOSE: CFontMenu implementation
5-
* COPYRIGHT: Copyright 2019,2020 Mark Jansen ([email protected])
5+
* COPYRIGHT: Copyright 2019-2021 Mark Jansen <[email protected]>
66
*/
77

88
#include "precomp.h"
@@ -58,7 +58,7 @@ HRESULT _CDataObject_CreateInstance(PCIDLIST_ABSOLUTE folder, UINT cidl, PCUITEM
5858
const FontPidlEntry* fontEntry = _FontFromIL(apidl[n]);
5959
if (fontEntry)
6060
{
61-
CStringW File = g_FontCache->Filename(fontEntry, true);
61+
CStringW File = g_FontCache->Filename(g_FontCache->Find(fontEntry), true);
6262
if (!File.IsEmpty())
6363
{
6464
// Now append the path (+ nullterminator) to the buffer
@@ -94,36 +94,8 @@ HRESULT _CDataObject_CreateInstance(PCIDLIST_ABSOLUTE folder, UINT cidl, PCUITEM
9494
pDrop->pt.x = pDrop->pt.y = 0;
9595
pDrop-> fNC = NULL;
9696

97-
// Prepare the format descriptors
98-
STGMEDIUM medium = {0};
99-
medium.tymed = TYMED_HGLOBAL;
100-
101-
// Copy the data to an HGLOBAL
102-
medium.hGlobal = GlobalAlloc(GHND, offset);
103-
if (medium.hGlobal)
104-
{
105-
LPVOID blob = GlobalLock(medium.hGlobal);
106-
if (blob)
107-
{
108-
CopyMemory(blob, (BYTE*)data, offset);
109-
GlobalUnlock(medium.hGlobal);
110-
111-
CComPtr<IDataObject> spDataObject(*(IDataObject**)ppvOut);
112-
if (spDataObject)
113-
{
114-
FORMATETC etc = { CF_HDROP, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
115-
hr = spDataObject->SetData(&etc, &medium, TRUE);
116-
}
117-
}
118-
else
119-
{
120-
ERR("Unable to lock the hGlobal?!\n");
121-
}
122-
}
123-
else
124-
{
125-
ERR("Unable to allocate %u bytes for the hGlobal\n", offset);
126-
}
97+
hr = DataObject_SetData(*(IDataObject**)ppvOut, CF_HDROP, data, offset);
98+
FAILED_UNEXPECTEDLY(hr);
12799

128100
return hr;
129101
}

dll/shellext/fontext/CEnumFonts.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
* PROJECT: ReactOS Font Shell Extension
33
* LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
44
* PURPOSE: CEnumFonts implementation
5-
* COPYRIGHT: Copyright 2019 Mark Jansen ([email protected])
5+
* COPYRIGHT: Copyright 2019 Mark Jansen <[email protected]>
66
*/
77

88
#include "precomp.h"

dll/shellext/fontext/CFontCache.cpp

Lines changed: 72 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
* PROJECT: ReactOS Font Shell Extension
33
* LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
44
* PURPOSE: font list cache handling
5-
* COPYRIGHT: Copyright 2019,2020 Mark Jansen ([email protected])
5+
* COPYRIGHT: Copyright 2019-2021 Mark Jansen <[email protected]>
66
*/
77

88
#include "precomp.h"
@@ -14,7 +14,11 @@ CFontCache* g_FontCache = NULL;
1414
CFontInfo::CFontInfo(LPCWSTR name)
1515
: m_Name(name)
1616
, m_FileRead(false)
17+
, m_AttrsRead(false)
18+
, m_FileWriteTime({})
19+
, m_dwFileAttributes(0)
1720
{
21+
m_FileSize.QuadPart = 0;
1822
}
1923

2024
const CStringW& CFontInfo::Name() const
@@ -62,7 +66,52 @@ const CStringW& CFontInfo::File()
6266
return m_File;
6367
}
6468

69+
void CFontInfo::ReadAttrs()
70+
{
71+
CStringW File = g_FontCache->Filename(this, true);
72+
73+
m_AttrsRead = true;
74+
75+
WIN32_FIND_DATAW findFileData;
76+
HANDLE hFile = FindFirstFileW(File, &findFileData);
77+
if (hFile != INVALID_HANDLE_VALUE)
78+
{
79+
80+
// File write time
81+
FileTimeToLocalFileTime(&findFileData.ftLastWriteTime, &m_FileWriteTime);
82+
83+
// File size
84+
m_FileSize.HighPart = findFileData.nFileSizeHigh;
85+
m_FileSize.LowPart = findFileData.nFileSizeLow;
86+
87+
m_dwFileAttributes = findFileData.dwFileAttributes;
88+
FindClose(hFile);
89+
}
90+
}
91+
92+
const LARGE_INTEGER& CFontInfo::FileSize()
93+
{
94+
if (!m_AttrsRead)
95+
ReadAttrs();
96+
97+
return m_FileSize;
98+
}
99+
100+
const FILETIME& CFontInfo::FileWriteTime()
101+
{
102+
if (!m_AttrsRead)
103+
ReadAttrs();
104+
105+
return m_FileWriteTime;
106+
}
107+
108+
DWORD CFontInfo::FileAttributes()
109+
{
110+
if (!m_AttrsRead)
111+
ReadAttrs();
65112

113+
return m_dwFileAttributes;
114+
}
66115

67116
CFontCache::CFontCache()
68117
{
@@ -93,30 +142,39 @@ CStringW CFontCache::Name(size_t Index)
93142
return m_Fonts[Index].Name();
94143
}
95144

96-
CStringW CFontCache::Filename(const FontPidlEntry* fontEntry, bool alwaysFullPath)
145+
CFontInfo* CFontCache::Find(const FontPidlEntry* fontEntry)
97146
{
98-
CStringW File;
99-
100147
if (fontEntry->Index < m_Fonts.GetCount())
101148
{
102-
CFontInfo& info = m_Fonts[fontEntry->Index];
103-
104-
if (info.Name().CompareNoCase(fontEntry->Name) == 0)
105-
File = info.File();
149+
if (m_Fonts[fontEntry->Index].Name().CompareNoCase(fontEntry->Name) == 0)
150+
return &m_Fonts[fontEntry->Index];
106151
}
107152

108-
for (UINT n = 0; File.IsEmpty() && n < Size(); ++n)
153+
for (UINT n = 0; n < Size(); ++n)
109154
{
110155
if (m_Fonts[n].Name().CompareNoCase(fontEntry->Name) == 0)
111-
File = m_Fonts[n].File();
156+
{
157+
return &m_Fonts[n];
158+
}
112159
}
160+
return nullptr;
161+
}
113162

114-
if (!File.IsEmpty() && alwaysFullPath)
163+
164+
CStringW CFontCache::Filename(CFontInfo* info, bool alwaysFullPath)
165+
{
166+
CStringW File;
167+
if (info)
115168
{
116-
// Ensure this is a full path
117-
if (PathIsRelativeW(File))
169+
File = info->File();
170+
171+
if (!File.IsEmpty() && alwaysFullPath)
118172
{
119-
File = m_FontFolderPath + File;
173+
// Ensure this is a full path
174+
if (PathIsRelativeW(File))
175+
{
176+
File = m_FontFolderPath + File;
177+
}
120178
}
121179
}
122180

dll/shellext/fontext/CFontCache.hpp

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
* PROJECT: ReactOS Font Shell Extension
33
* LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
44
* PURPOSE: font list cache handling
5-
* COPYRIGHT: Copyright 2019,2020 Mark Jansen ([email protected])
5+
* COPYRIGHT: Copyright 2019-2021 Mark Jansen <[email protected]>
66
*/
77

88
#pragma once
@@ -14,12 +14,24 @@ class CFontInfo
1414
CStringW m_Name;
1515
CStringW m_File;
1616
bool m_FileRead;
17+
18+
bool m_AttrsRead;
19+
LARGE_INTEGER m_FileSize;
20+
FILETIME m_FileWriteTime;
21+
DWORD m_dwFileAttributes;
22+
23+
void ReadAttrs();
24+
1725
public:
1826
CFontInfo(LPCWSTR name = L"");
1927

20-
const CStringW& Name() const;
21-
const CStringW& File();
28+
const CStringW& Name() const; // Font display name stored in the registry
2229
const bool Valid() const;
30+
31+
const CStringW& File(); // Full path or file, depending on how it's stored in the registry
32+
const LARGE_INTEGER& FileSize();
33+
const FILETIME& FileWriteTime();
34+
DWORD FileAttributes();
2335
};
2436

2537

@@ -40,8 +52,10 @@ class CFontCache
4052
const CStringW& FontPath() const { return m_FontFolderPath; }
4153

4254
size_t Size();
43-
CStringW Name(size_t Index);
44-
CStringW Filename(const FontPidlEntry* fontEntry, bool alwaysFullPath = false);
55+
CStringW Name(size_t Index); // Font display name stored in the registry
56+
57+
CFontInfo* Find(const FontPidlEntry* fontEntry);
58+
CStringW Filename(CFontInfo* info, bool alwaysFullPath = false);
4559

4660
friend class CFontExtModule;
4761
};

0 commit comments

Comments
 (0)