ReactOS  0.4.15-dev-4853-g3a72a52
CFontMenu.cpp
Go to the documentation of this file.
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 
11 
12 
13 const char* DFM_TO_STR(UINT uMsg)
14 {
15  switch(uMsg)
16  {
17  case DFM_MERGECONTEXTMENU: return "DFM_MERGECONTEXTMENU";
18  case DFM_INVOKECOMMAND: return "DFM_INVOKECOMMAND";
19  case DFM_MODIFYQCMFLAGS: return "DFM_MODIFYQCMFLAGS";
20  case DFM_MERGECONTEXTMENU_TOP: return "DFM_MERGECONTEXTMENU_TOP";
21  case DFM_MERGECONTEXTMENU_BOTTOM: return "DFM_MERGECONTEXTMENU_BOTTOM";
22  case DFM_GETHELPTEXTW: return "DFM_GETHELPTEXTW";
23  case DFM_GETVERBW: return "DFM_GETVERBW";
24  case DFM_GETVERBA: return "DFM_GETVERBA";
25  case DFM_WM_INITMENUPOPUP: return "DFM_WM_INITMENUPOPUP";
26  case DFM_INVOKECOMMANDEX: return "DFM_INVOKECOMMANDEX";
27  case DFM_GETDEFSTATICID: return "DFM_GETDEFSTATICID";
28  case 3: return "MENU_BEGIN";
29  case 4: return "MENU_END";
30  default: return "";
31  }
32 }
33 
34 
35 static void RunFontViewer(HWND hwnd, const FontPidlEntry* fontEntry)
36 {
37  WCHAR FontViewerPath[MAX_PATH] = L"%SystemRoot%\\System32\\fontview.exe";
38  WCHAR FontPathArg[MAX_PATH + 3];
39 
40  CStringW Path = g_FontCache->Filename(g_FontCache->Find(fontEntry), true);
41  if (!Path.IsEmpty())
42  {
43  // '/d' disables the install button
44  StringCchPrintfW(FontPathArg, _countof(FontPathArg), L"/d %s", Path.GetString());
45  PathQuoteSpacesW(FontPathArg + 3);
46 
47  SHELLEXECUTEINFOW si = { sizeof(si) };
49  si.hwnd = hwnd;
50  si.lpFile = FontViewerPath;
51  si.lpParameters = FontPathArg;
52  si.nShow = SW_SHOWNORMAL;
53  ShellExecuteExW(&si);
54  }
55 }
56 
59 {
60  TRACE("FontFolderMenuCallback(%u {%s})\n", uMsg, DFM_TO_STR(uMsg));
61  switch (uMsg)
62  {
64  {
65  QCMINFO *pqcminfo = (QCMINFO *)lParam;
66 
68  MENUITEMINFOW cmi = { sizeof(cmi) };
70  cmi.fType = MFT_STRING;
71  cmi.fState = MFS_DEFAULT;
72  cmi.wID = pqcminfo->idCmdFirst++;
73  cmi.dwTypeData = (LPWSTR)menuText.GetString();
74  InsertMenuItemW(pqcminfo->hmenu, pqcminfo->indexMenu, TRUE, &cmi);
75 
76  return S_OK;
77  }
78  case DFM_INVOKECOMMAND:
79  // Preview is the only item we handle
80  if (wParam == 0)
81  {
82  CDataObjectHIDA cida(pdtobj);
83 
84  if (FAILED_UNEXPECTEDLY(cida.hr()))
85  return cida.hr();
86 
87  for (UINT n = 0; n < cida->cidl; ++n)
88  {
89  const FontPidlEntry* fontEntry = _FontFromIL(HIDA_GetPIDLItem(cida, n));
90  RunFontViewer(hwnd, fontEntry);
91  }
92  return S_OK;
93  }
94  else if (wParam == DFM_CMD_PROPERTIES)
95  {
96  TRACE("Default properties handling!\n");
97  return S_FALSE;
98  }
99  else
100  {
101  ERR("Unhandled DFM_INVOKECOMMAND(wParam=0x%x)\n", wParam);
102  }
103  return S_FALSE;
104 
105  case DFM_INVOKECOMMANDEX:
106  return E_NOTIMPL;
107  case DFM_GETDEFSTATICID: // Required for Windows 7 to pick a default
108  return S_FALSE;
109  }
110  return E_NOTIMPL;
111 }
112 
113 
115  IShellFolder *psf, REFIID riid, LPVOID* ppvOut)
116 {
117  if (cidl > 0)
118  {
119  HKEY keys[1] = {0};
120  int nkeys = 0;
121  CComPtr<IContextMenu> spMenu;
122 
123  // Use the default context menu handler, but augment it from the callbacks
124  HRESULT hr = CDefFolderMenu_Create2(NULL, hwnd, cidl, apidl, psf, FontFolderMenuCallback, nkeys, keys, &spMenu);
125 
126  if (FAILED_UNEXPECTEDLY(hr))
127  return hr;
128 
129  // See if the requested interface (e.g. IContextMenu3) is also available
130  return spMenu->QueryInterface(riid, ppvOut);
131  }
132 
133  // We can't create a background menu
134  return E_FAIL;
135 }
136 
#define MFT_STRING
Definition: winuser.h:741
#define REFIID
Definition: guiddef.h:118
HRESULT hr
Definition: shlfolder.c:183
#define TRUE
Definition: types.h:120
REFIID riid
Definition: precomp.h:44
#define CALLBACK
Definition: compat.h:35
static PCUIDLIST_RELATIVE HIDA_GetPIDLItem(CIDA const *pida, SIZE_T i)
Definition: shellutils.h:554
HMENU hmenu
Definition: shlobj.h:1315
GLdouble n
Definition: glext.h:7729
const FontPidlEntry * _FontFromIL(LPCITEMIDLIST pidl)
Definition: fontpidl.cpp:32
LPWSTR dwTypeData
Definition: winuser.h:3249
WINE_DEFAULT_DEBUG_CHANNEL(fontext)
UINT_PTR WPARAM
Definition: windef.h:207
#define MFS_DEFAULT
Definition: winuser.h:743
#define DFM_MERGECONTEXTMENU_BOTTOM
Definition: shlobj.h:2443
#define E_FAIL
Definition: ddrawi.h:102
WPARAM wParam
Definition: combotst.c:138
#define DFM_MODIFYQCMFLAGS
Definition: shlobj.h:2444
#define L(x)
Definition: ntvdm.h:50
const PCUITEMID_CHILD * PCUITEMID_CHILD_ARRAY
Definition: shtypes.idl:71
#define MIIM_STATE
Definition: winuser.h:716
#define DFM_GETVERBW
Definition: shlobj.h:2441
#define S_FALSE
Definition: winerror.h:2357
#define DFM_INVOKECOMMAND
Definition: precomp.h:45
LONG_PTR LPARAM
Definition: windef.h:208
HRESULT _CFontMenu_CreateInstance(HWND hwnd, UINT cidl, PCUITEMID_CHILD_ARRAY apidl, IShellFolder *psf, REFIID riid, LPVOID *ppvOut)
Definition: CFontMenu.cpp:114
UINT indexMenu
Definition: shlobj.h:1316
BOOL WINAPI DECLSPEC_HOTPATCH ShellExecuteExW(LPSHELLEXECUTEINFOW sei)
Definition: shlexec.cpp:2343
#define DFM_WM_INITMENUPOPUP
Definition: shlobj.h:2436
#define MIIM_ID
Definition: winuser.h:717
#define DFM_GETHELPTEXTW
Definition: shlobj.h:2439
static HRESULT CALLBACK FontFolderMenuCallback(IShellFolder *psf, HWND hwnd, IDataObject *pdtobj, UINT uMsg, WPARAM wParam, LPARAM lParam)
Definition: CFontMenu.cpp:57
#define TRACE(s)
Definition: solgame.cpp:4
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define DFM_GETDEFSTATICID
Definition: precomp.h:47
LONG HRESULT
Definition: typedefs.h:79
UINT idCmdFirst
Definition: shlobj.h:1317
#define _countof(array)
Definition: sndvol32.h:68
#define FAILED_UNEXPECTEDLY(hr)
Definition: shellutils.h:82
#define MAX_PATH
Definition: compat.h:34
PCXSTR GetString() const
Definition: atlsimpstr.h:361
#define SEE_MASK_DOENVSUBST
Definition: shellapi.h:35
#define DFM_MERGECONTEXTMENU
Definition: precomp.h:44
#define DFM_CMD_PROPERTIES
Definition: shlobj.h:2451
const char * DFM_TO_STR(UINT uMsg)
Definition: CFontMenu.cpp:13
CFontCache * g_FontCache
Definition: CFontCache.cpp:12
#define ERR(fmt,...)
Definition: debug.h:110
#define MIIM_STRING
Definition: winuser.h:722
#define S_OK
Definition: intsafe.h:52
#define SW_SHOWNORMAL
Definition: winuser.h:764
PRTL_UNICODE_STRING_BUFFER Path
static void RunFontViewer(HWND hwnd, const FontPidlEntry *fontEntry)
Definition: CFontMenu.cpp:35
#define IDS_FONT_PREVIEW
Definition: resource.h:13
LPCWSTR lpParameters
Definition: shellapi.h:331
STRSAFEAPI StringCchPrintfW(STRSAFE_LPWSTR pszDest, size_t cchDest, STRSAFE_LPCWSTR pszFormat,...)
Definition: strsafe.h:530
#define E_NOTIMPL
Definition: ddrawi.h:99
#define DFM_MERGECONTEXTMENU_TOP
Definition: shlobj.h:2438
BOOL WINAPI InsertMenuItemW(_In_ HMENU, _In_ UINT, _In_ BOOL, _In_ LPCMENUITEMINFOW)
unsigned int UINT
Definition: ndis.h:50
#define NULL
Definition: types.h:112
CFontInfo * Find(const FontPidlEntry *fontEntry)
Definition: CFontCache.cpp:145
#define DFM_INVOKECOMMANDEX
Definition: precomp.h:46
CStringW Filename(CFontInfo *info, bool alwaysFullPath=false)
Definition: CFontCache.cpp:164
#define MAKEINTRESOURCEW(i)
Definition: winuser.h:582
VOID WINAPI PathQuoteSpacesW(LPWSTR lpszPath)
Definition: path.c:978
WCHAR * LPWSTR
Definition: xmlstorage.h:184
_In_ LONG _In_ HWND hwnd
Definition: winddi.h:4022
#define DFM_GETVERBA
Definition: shlobj.h:2442
LPARAM lParam
Definition: combotst.c:139
HRESULT WINAPI CDefFolderMenu_Create2(PCIDLIST_ABSOLUTE pidlFolder, HWND hwnd, UINT cidl, PCUITEMID_CHILD_ARRAY apidl, IShellFolder *psf, LPFNDFMCALLBACK lpfn, UINT nKeys, const HKEY *ahkeyClsKeys, IContextMenu **ppcm)