mirror of
https://github.com/reactos/reactos.git
synced 2024-11-01 04:11:30 +00:00
6a68717c58
CORE-17691
137 lines
4.2 KiB
C++
137 lines
4.2 KiB
C++
/*
|
|
* 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-2021 Mark Jansen <mark.jansen@reactos.org>
|
|
*/
|
|
|
|
#include "precomp.h"
|
|
|
|
WINE_DEFAULT_DEBUG_CHANNEL(fontext);
|
|
|
|
|
|
const char* DFM_TO_STR(UINT uMsg)
|
|
{
|
|
switch(uMsg)
|
|
{
|
|
case DFM_MERGECONTEXTMENU: return "DFM_MERGECONTEXTMENU";
|
|
case DFM_INVOKECOMMAND: return "DFM_INVOKECOMMAND";
|
|
case DFM_MODIFYQCMFLAGS: return "DFM_MODIFYQCMFLAGS";
|
|
case DFM_MERGECONTEXTMENU_TOP: return "DFM_MERGECONTEXTMENU_TOP";
|
|
case DFM_MERGECONTEXTMENU_BOTTOM: return "DFM_MERGECONTEXTMENU_BOTTOM";
|
|
case DFM_GETHELPTEXTW: return "DFM_GETHELPTEXTW";
|
|
case DFM_GETVERBW: return "DFM_GETVERBW";
|
|
case DFM_GETVERBA: return "DFM_GETVERBA";
|
|
case DFM_WM_INITMENUPOPUP: return "DFM_WM_INITMENUPOPUP";
|
|
case DFM_INVOKECOMMANDEX: return "DFM_INVOKECOMMANDEX";
|
|
case DFM_GETDEFSTATICID: return "DFM_GETDEFSTATICID";
|
|
case 3: return "MENU_BEGIN";
|
|
case 4: return "MENU_END";
|
|
default: return "";
|
|
}
|
|
}
|
|
|
|
|
|
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(g_FontCache->Find(fontEntry), true);
|
|
if (!Path.IsEmpty())
|
|
{
|
|
// '/d' disables the install button
|
|
StringCchPrintfW(FontPathArg, _countof(FontPathArg), L"/d %s", Path.GetString());
|
|
PathQuoteSpacesW(FontPathArg + 3);
|
|
|
|
SHELLEXECUTEINFOW si = { sizeof(si) };
|
|
si.fMask = SEE_MASK_DOENVSUBST;
|
|
si.hwnd = hwnd;
|
|
si.lpFile = FontViewerPath;
|
|
si.lpParameters = FontPathArg;
|
|
si.nShow = SW_SHOWNORMAL;
|
|
ShellExecuteExW(&si);
|
|
}
|
|
}
|
|
|
|
static HRESULT CALLBACK FontFolderMenuCallback(IShellFolder *psf, HWND hwnd, IDataObject *pdtobj,
|
|
UINT uMsg, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
TRACE("FontFolderMenuCallback(%u {%s})\n", uMsg, DFM_TO_STR(uMsg));
|
|
switch (uMsg)
|
|
{
|
|
case DFM_MERGECONTEXTMENU:
|
|
{
|
|
QCMINFO *pqcminfo = (QCMINFO *)lParam;
|
|
|
|
CStringW menuText(MAKEINTRESOURCEW(IDS_FONT_PREVIEW));
|
|
MENUITEMINFOW cmi = { sizeof(cmi) };
|
|
cmi.fMask = MIIM_ID | MIIM_STRING | MIIM_STATE;
|
|
cmi.fType = MFT_STRING;
|
|
cmi.fState = MFS_DEFAULT;
|
|
cmi.wID = pqcminfo->idCmdFirst++;
|
|
cmi.dwTypeData = (LPWSTR)menuText.GetString();
|
|
InsertMenuItemW(pqcminfo->hmenu, pqcminfo->indexMenu, TRUE, &cmi);
|
|
|
|
return S_OK;
|
|
}
|
|
case DFM_INVOKECOMMAND:
|
|
// Preview is the only item we handle
|
|
if (wParam == 0)
|
|
{
|
|
CDataObjectHIDA cida(pdtobj);
|
|
|
|
if (FAILED_UNEXPECTEDLY(cida.hr()))
|
|
return cida.hr();
|
|
|
|
for (UINT n = 0; n < cida->cidl; ++n)
|
|
{
|
|
const FontPidlEntry* fontEntry = _FontFromIL(HIDA_GetPIDLItem(cida, n));
|
|
RunFontViewer(hwnd, fontEntry);
|
|
}
|
|
return S_OK;
|
|
}
|
|
else if (wParam == DFM_CMD_PROPERTIES)
|
|
{
|
|
TRACE("Default properties handling!\n");
|
|
return S_FALSE;
|
|
}
|
|
else
|
|
{
|
|
ERR("Unhandled DFM_INVOKECOMMAND(wParam=0x%x)\n", wParam);
|
|
}
|
|
return S_FALSE;
|
|
|
|
case DFM_INVOKECOMMANDEX:
|
|
return E_NOTIMPL;
|
|
case DFM_GETDEFSTATICID: // Required for Windows 7 to pick a default
|
|
return S_FALSE;
|
|
}
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
|
|
HRESULT _CFontMenu_CreateInstance(HWND hwnd, UINT cidl, PCUITEMID_CHILD_ARRAY apidl,
|
|
IShellFolder *psf, REFIID riid, LPVOID* ppvOut)
|
|
{
|
|
if (cidl > 0)
|
|
{
|
|
HKEY keys[1] = {0};
|
|
int nkeys = 0;
|
|
CComPtr<IContextMenu> spMenu;
|
|
|
|
// Use the default context menu handler, but augment it from the callbacks
|
|
HRESULT hr = CDefFolderMenu_Create2(NULL, hwnd, cidl, apidl, psf, FontFolderMenuCallback, nkeys, keys, &spMenu);
|
|
|
|
if (FAILED_UNEXPECTEDLY(hr))
|
|
return hr;
|
|
|
|
// See if the requested interface (e.g. IContextMenu3) is also available
|
|
return spMenu->QueryInterface(riid, ppvOut);
|
|
}
|
|
|
|
// We can't create a background menu
|
|
return E_FAIL;
|
|
}
|
|
|