mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 01:55:19 +00:00
[SHELLEXT][FONTEXT] An attempt to implement IDropTarget (#2019)
CORE-12861
This commit is contained in:
parent
d037003511
commit
c214c04964
6 changed files with 211 additions and 19 deletions
|
@ -9,10 +9,6 @@
|
|||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(fontext);
|
||||
|
||||
|
||||
#define FONT_HIVE HKEY_LOCAL_MACHINE
|
||||
#define FONT_KEY L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Fonts"
|
||||
|
||||
CFontCache* g_FontCache = NULL;
|
||||
|
||||
CFontInfo::CFontInfo(LPCWSTR name)
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
* LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
|
||||
* PURPOSE: CFontExt implementation
|
||||
* COPYRIGHT: Copyright 2019 Mark Jansen (mark.jansen@reactos.org)
|
||||
* Copyright 2019 Katayama Hirofumi MZ (katayama.hirofumi.mz@gmail.com)
|
||||
*/
|
||||
|
||||
#include "precomp.h"
|
||||
|
@ -196,9 +197,10 @@ STDMETHODIMP CFontExt::CreateViewObject(HWND hwndOwner, REFIID riid, LPVOID *ppv
|
|||
|
||||
if (IsEqualIID(riid, IID_IDropTarget))
|
||||
{
|
||||
// Needed to drop files into the fonts folder, we should probably install them?
|
||||
ERR("IDropTarget not implemented\n");
|
||||
hr = E_NOTIMPL;
|
||||
*ppvOut = static_cast<IDropTarget *>(this);
|
||||
AddRef();
|
||||
hr = S_OK;
|
||||
}
|
||||
else if (IsEqualIID(riid, IID_IContextMenu))
|
||||
{
|
||||
|
@ -363,3 +365,170 @@ STDMETHODIMP CFontExt::GetClassID(CLSID *lpClassId)
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
// *** IDropTarget methods ***
|
||||
STDMETHODIMP CFontExt::DragEnter(IDataObject* pDataObj, DWORD grfKeyState, POINTL pt, DWORD* pdwEffect)
|
||||
{
|
||||
*pdwEffect = DROPEFFECT_NONE;
|
||||
|
||||
CComHeapPtr<CIDA> cida;
|
||||
HRESULT hr = _GetCidlFromDataObject(pDataObj, &cida);
|
||||
if (FAILED_UNEXPECTEDLY(hr))
|
||||
return hr;
|
||||
|
||||
#if 1 // Please implement DoGetFontTitle
|
||||
return DRAGDROP_S_CANCEL;
|
||||
#else
|
||||
*pdwEffect = DROPEFFECT_COPY;
|
||||
return S_OK;
|
||||
#endif
|
||||
}
|
||||
|
||||
STDMETHODIMP CFontExt::DragOver(DWORD grfKeyState, POINTL pt, DWORD* pdwEffect)
|
||||
{
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CFontExt::DragLeave()
|
||||
{
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CFontExt::Drop(IDataObject* pDataObj, DWORD grfKeyState, POINTL pt, DWORD* pdwEffect)
|
||||
{
|
||||
*pdwEffect = DROPEFFECT_NONE;
|
||||
|
||||
WCHAR szFontsDir[MAX_PATH];
|
||||
HRESULT hr = SHGetFolderPathW(NULL, CSIDL_FONTS, NULL, 0, szFontsDir);
|
||||
if (FAILED_UNEXPECTEDLY(hr))
|
||||
return E_FAIL;
|
||||
|
||||
CComHeapPtr<CIDA> cida;
|
||||
hr = _GetCidlFromDataObject(pDataObj, &cida);
|
||||
if (FAILED_UNEXPECTEDLY(hr))
|
||||
return hr;
|
||||
|
||||
PCUIDLIST_ABSOLUTE pidlParent = HIDA_GetPIDLFolder(cida);
|
||||
if (!pidlParent)
|
||||
{
|
||||
ERR("pidlParent is NULL\n");
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
BOOL bOK = TRUE;
|
||||
CAtlArray<CStringW> FontPaths;
|
||||
for (UINT n = 0; n < cida->cidl; ++n)
|
||||
{
|
||||
PCUIDLIST_RELATIVE pidlRelative = HIDA_GetPIDLItem(cida, n);
|
||||
if (!pidlRelative)
|
||||
continue;
|
||||
|
||||
PIDLIST_ABSOLUTE pidl = ILCombine(pidlParent, pidlRelative);
|
||||
if (!pidl)
|
||||
{
|
||||
ERR("ILCombine failed\n");
|
||||
bOK = FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
WCHAR szPath[MAX_PATH];
|
||||
BOOL ret = SHGetPathFromIDListW(pidl, szPath);
|
||||
ILFree(pidl);
|
||||
|
||||
if (!ret)
|
||||
{
|
||||
ERR("SHGetPathFromIDListW failed\n");
|
||||
bOK = FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
if (PathIsDirectoryW(szPath))
|
||||
{
|
||||
ERR("PathIsDirectory\n");
|
||||
bOK = FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
LPCWSTR pchDotExt = PathFindExtensionW(szPath);
|
||||
if (!IsFontDotExt(pchDotExt))
|
||||
{
|
||||
ERR("'%S' is not supported\n", pchDotExt);
|
||||
bOK = FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
FontPaths.Add(szPath);
|
||||
}
|
||||
|
||||
if (!bOK)
|
||||
return E_FAIL;
|
||||
|
||||
CRegKey keyFonts;
|
||||
if (keyFonts.Open(FONT_HIVE, FONT_KEY, KEY_WRITE) != ERROR_SUCCESS)
|
||||
{
|
||||
ERR("keyFonts.Open failed\n");
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
for (size_t iItem = 0; iItem < FontPaths.GetCount(); ++iItem)
|
||||
{
|
||||
HRESULT hr = DoInstallFontFile(FontPaths[iItem], szFontsDir, keyFonts.m_hKey);
|
||||
if (FAILED_UNEXPECTEDLY(hr))
|
||||
{
|
||||
bOK = FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: update g_FontCache
|
||||
|
||||
SendMessageW(HWND_BROADCAST, WM_FONTCHANGE, 0, 0);
|
||||
|
||||
// TODO: Show message
|
||||
|
||||
return bOK ? S_OK : E_FAIL;
|
||||
}
|
||||
|
||||
HRESULT CFontExt::DoInstallFontFile(LPCWSTR pszFontPath, LPCWSTR pszFontsDir, HKEY hkeyFonts)
|
||||
{
|
||||
WCHAR szDestFile[MAX_PATH];
|
||||
LPCWSTR pszFileTitle = PathFindFileName(pszFontPath);
|
||||
|
||||
WCHAR szFontName[512];
|
||||
if (!DoGetFontTitle(pszFontPath, szFontName))
|
||||
return E_FAIL;
|
||||
|
||||
RemoveFontResourceW(pszFileTitle);
|
||||
|
||||
StringCchCopyW(szDestFile, sizeof(szDestFile), pszFontsDir);
|
||||
PathAppendW(szDestFile, pszFileTitle);
|
||||
if (!CopyFileW(pszFontPath, szDestFile, FALSE))
|
||||
{
|
||||
ERR("CopyFileW('%S', '%S') failed\n", pszFontPath, szDestFile);
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
if (!AddFontResourceW(pszFileTitle))
|
||||
{
|
||||
ERR("AddFontResourceW('%S') failed\n", pszFileTitle);
|
||||
DeleteFileW(szDestFile);
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
DWORD cbData = (wcslen(pszFileTitle) + 1) * sizeof(WCHAR);
|
||||
LONG nError = RegSetValueExW(hkeyFonts, szFontName, 0, REG_SZ, (const BYTE *)szFontName, cbData);
|
||||
if (nError)
|
||||
{
|
||||
ERR("RegSetValueExW failed with %ld\n", nError);
|
||||
RemoveFontResourceW(pszFileTitle);
|
||||
DeleteFileW(szDestFile);
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT CFontExt::DoGetFontTitle(LPCWSTR pszFontPath, LPCWSTR pszFontName)
|
||||
{
|
||||
// TODO:
|
||||
return E_FAIL;
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
* LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
|
||||
* PURPOSE: CFontExt definition
|
||||
* COPYRIGHT: Copyright 2019 Mark Jansen (mark.jansen@reactos.org)
|
||||
* Copyright 2019 Katayama Hirofumi MZ (katayama.hirofumi.mz@gmail.com)
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
@ -11,7 +12,8 @@ class CFontExt :
|
|||
public CComCoClass<CFontExt, &CLSID_CFontExt>,
|
||||
public CComObjectRootEx<CComMultiThreadModelNoCS>,
|
||||
public IShellFolder2,
|
||||
public IPersistFolder2
|
||||
public IPersistFolder2,
|
||||
public IDropTarget
|
||||
{
|
||||
CComHeapPtr<ITEMIDLIST> m_Folder;
|
||||
|
||||
|
@ -51,6 +53,11 @@ public:
|
|||
// *** IPersist methods ***
|
||||
virtual STDMETHODIMP GetClassID(CLSID *lpClassId);
|
||||
|
||||
// *** IDropTarget methods ***
|
||||
virtual STDMETHODIMP DragEnter(IDataObject* pDataObj, DWORD grfKeyState, POINTL pt, DWORD* pdwEffect);
|
||||
virtual STDMETHODIMP DragOver(DWORD grfKeyState, POINTL pt, DWORD* pdwEffect);
|
||||
virtual STDMETHODIMP DragLeave();
|
||||
virtual STDMETHODIMP Drop(IDataObject* pDataObj, DWORD grfKeyState, POINTL pt, DWORD* pdwEffect);
|
||||
|
||||
#if 0
|
||||
static HRESULT WINAPI log_stuff(void* pv, REFIID riid, LPVOID* ppv, DWORD_PTR dw)
|
||||
|
@ -79,6 +86,10 @@ public:
|
|||
COM_INTERFACE_ENTRY_IID(IID_IShellFolder, IShellFolder)
|
||||
COM_INTERFACE_ENTRY_IID(IID_IPersistFolder2, IPersistFolder2)
|
||||
COM_INTERFACE_ENTRY_IID(IID_IPersistFolder, IPersistFolder)
|
||||
COM_INTERFACE_ENTRY_IID(IID_IDropTarget, IDropTarget)
|
||||
//COM_INTERFACE_ENTRY_FUNC_BLIND(0, log_stuff)
|
||||
END_COM_MAP()
|
||||
|
||||
HRESULT DoInstallFontFile(LPCWSTR pszFontPath, LPCWSTR pszFontsDir, HKEY hkeyFonts);
|
||||
HRESULT DoGetFontTitle(LPCWSTR pszFontPath, LPCWSTR pszFontName);
|
||||
};
|
||||
|
|
|
@ -9,18 +9,8 @@
|
|||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(fontext);
|
||||
|
||||
|
||||
static inline PCUIDLIST_ABSOLUTE HIDA_GetPIDLFolder(CIDA const* pida)
|
||||
{
|
||||
return (PCUIDLIST_ABSOLUTE)(((LPBYTE)pida) + (pida)->aoffset[0]);
|
||||
}
|
||||
|
||||
static inline PCUIDLIST_RELATIVE HIDA_GetPIDLItem(CIDA const* pida, SIZE_T i)
|
||||
{
|
||||
return (PCUIDLIST_RELATIVE)(((LPBYTE)pida) + (pida)->aoffset[i + 1]);
|
||||
}
|
||||
|
||||
static CLIPFORMAT g_cfHIDA;
|
||||
|
||||
HRESULT _GetCidlFromDataObject(IDataObject *pDataObject, CIDA** ppcida)
|
||||
{
|
||||
if (g_cfHIDA == NULL)
|
||||
|
|
|
@ -32,7 +32,7 @@ add_library(fontext MODULE
|
|||
|
||||
set_module_type(fontext win32dll UNICODE)
|
||||
target_link_libraries(fontext uuid wine)
|
||||
add_delay_importlibs(fontext ole32 oleaut32 shlwapi)
|
||||
add_delay_importlibs(fontext ole32 oleaut32 shlwapi gdi32)
|
||||
add_importlibs(fontext shell32 advapi32 user32 msvcrt kernel32 ntdll)
|
||||
add_pch(fontext precomp.h SOURCE)
|
||||
add_cd_file(TARGET fontext DESTINATION reactos/system32 FOR all)
|
||||
|
|
|
@ -27,6 +27,8 @@ extern LONG g_ModuleRefCnt;
|
|||
#include "CFontCache.hpp"
|
||||
#include "CFontExt.hpp"
|
||||
|
||||
#define FONT_HIVE HKEY_LOCAL_MACHINE
|
||||
#define FONT_KEY L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Fonts"
|
||||
|
||||
HRESULT _CEnumFonts_CreateInstance(CFontExt* zip, DWORD flags, REFIID riid, LPVOID* ppvOut);
|
||||
HRESULT _CFontMenu_CreateInstance(HWND hwnd, UINT cidl, PCUITEMID_CHILD_ARRAY apidl,
|
||||
|
@ -34,6 +36,30 @@ HRESULT _CFontMenu_CreateInstance(HWND hwnd, UINT cidl, PCUITEMID_CHILD_ARRAY ap
|
|||
HRESULT _CDataObject_CreateInstance(PCIDLIST_ABSOLUTE folder, UINT cidl, PCUITEMID_CHILD_ARRAY apidl,
|
||||
REFIID riid, LPVOID* ppvOut);
|
||||
|
||||
HRESULT _GetCidlFromDataObject(IDataObject *pDataObject, CIDA** ppcida);
|
||||
|
||||
inline PCUIDLIST_ABSOLUTE HIDA_GetPIDLFolder(CIDA const* pida)
|
||||
{
|
||||
return (PCUIDLIST_ABSOLUTE)(((LPBYTE)pida) + (pida)->aoffset[0]);
|
||||
}
|
||||
|
||||
inline PCUIDLIST_RELATIVE HIDA_GetPIDLItem(CIDA const* pida, SIZE_T i)
|
||||
{
|
||||
return (PCUIDLIST_RELATIVE)(((LPBYTE)pida) + (pida)->aoffset[i + 1]);
|
||||
}
|
||||
|
||||
inline BOOL IsFontDotExt(LPCWSTR pchDotExt)
|
||||
{
|
||||
static const LPCWSTR array[] =
|
||||
{
|
||||
L".ttf", L".ttc", L".otf", L".otc", L".fon", L".fnt", NULL
|
||||
};
|
||||
for (const LPCWSTR *pp = array; *pp; ++pp)
|
||||
{
|
||||
if (!_wcsicmp(*pp, pchDotExt))
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
#endif /* FONTEXT_PRECOMP_H */
|
||||
|
|
Loading…
Reference in a new issue