Skip to content

Commit 789f6c5

Browse files
authored
[FONTEXT] Implement paste operation (reactos#8615)
Support paste operation on Fonts folder. JIRA issue: CORE-12861 - Add CFontBackgroundMenu.cpp and CFontBackgroundMenu.h to support background menu. - Modify CFontExt::CreateViewObject and CFontExt::GetUIObjectOf methods. - Re-implement foreground menu by using CDefFolderMenu_Create2 and CFontExt::MenuCallBack. - Delete needless CFontMenu.cpp. - Add IDS_PROPERTIES resource string.
1 parent 2865b63 commit 789f6c5

File tree

18 files changed

+437
-292
lines changed

18 files changed

+437
-292
lines changed
Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
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: Fonts folder shell extension background menu
5+
* COPYRIGHT: Copyright 2026 Katayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com>
6+
*/
7+
8+
#include "precomp.h"
9+
#include <shlwapi_undoc.h>
10+
11+
WINE_DEFAULT_DEBUG_CHANNEL(fontext);
12+
13+
CFontBackgroundMenu::CFontBackgroundMenu()
14+
{
15+
}
16+
17+
CFontBackgroundMenu::~CFontBackgroundMenu()
18+
{
19+
}
20+
21+
HRESULT WINAPI CFontBackgroundMenu::Initialize(CFontExt* pFontExt, const DEFCONTEXTMENU *pdcm)
22+
{
23+
m_pFontExt = pFontExt;
24+
m_psf = pdcm->psf;
25+
m_pmcb = pdcm->pcmcb;
26+
m_hwnd = pdcm->hwnd;
27+
return S_OK;
28+
}
29+
30+
// IContextMenu
31+
STDMETHODIMP CFontBackgroundMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu, UINT idCmdFirst, UINT idCmdLast, UINT uFlags)
32+
{
33+
TRACE("%d\n", idCmdFirst);
34+
CString strProp(MAKEINTRESOURCEW(IDS_PROPERTIES));
35+
INT idCmd = idCmdFirst;
36+
AppendMenuW(hMenu, MF_STRING, idCmd++, strProp);
37+
return MAKE_HRESULT(SEVERITY_SUCCESS, 0, idCmd - idCmdFirst);
38+
}
39+
40+
STDMETHODIMP CFontBackgroundMenu::InvokeCommand(LPCMINVOKECOMMANDINFO lpcmi)
41+
{
42+
INT idCmd = IS_INTRESOURCE(lpcmi->lpVerb) ? LOWORD(lpcmi->lpVerb) : -1;
43+
TRACE("%d\n", idCmd);
44+
45+
if (idCmd == 0 || (idCmd == -1 && !lstrcmpiA(lpcmi->lpVerb, "properties")))
46+
{
47+
// Open "Fonts" properties
48+
LPITEMIDLIST pidl = NULL;
49+
HRESULT hr = SHGetSpecialFolderLocation(m_hwnd, CSIDL_FONTS, &pidl);
50+
if (FAILED_UNEXPECTEDLY(hr) || !pidl)
51+
return E_FAIL;
52+
53+
SHELLEXECUTEINFOW sei = {
54+
sizeof(sei), SEE_MASK_INVOKEIDLIST | SEE_MASK_ASYNCOK, NULL, L"properties",
55+
NULL, NULL, NULL, SW_SHOWNORMAL, NULL, const_cast<LPITEMIDLIST>(pidl)
56+
};
57+
BOOL bOK = ShellExecuteExW(&sei);
58+
if (pidl)
59+
CoTaskMemFree(pidl);
60+
return bOK ? S_OK : E_FAIL;
61+
}
62+
63+
if (idCmd == FCIDM_SHVIEW_INSERT || (idCmd == -1 && !lstrcmpiA(lpcmi->lpVerb, "paste")))
64+
{
65+
CComPtr<IDataObject> pDataObj;
66+
HRESULT hr = OleGetClipboard(&pDataObj);
67+
if (FAILED_UNEXPECTEDLY(hr) || !CheckDataObject(pDataObj))
68+
{
69+
// Show error message
70+
CStringW text, title;
71+
title.LoadStringW(IDS_REACTOS_FONTS_FOLDER);
72+
text.LoadStringW(IDS_INSTALL_FAILED);
73+
MessageBoxW(m_hwnd, text, title, MB_ICONERROR);
74+
return E_FAIL;
75+
}
76+
77+
return SHSimulateDrop(m_pFontExt, pDataObj, 0, NULL, NULL);
78+
}
79+
80+
return S_OK;
81+
}
82+
83+
STDMETHODIMP CFontBackgroundMenu::GetCommandString(UINT_PTR idCommand, UINT uFlags, UINT *lpReserved, LPSTR lpszName, UINT uMaxNameLen)
84+
{
85+
TRACE("%d\n", idCommand);
86+
if (idCommand == 0)
87+
{
88+
lstrcpynA(lpszName, "properties", uMaxNameLen);
89+
return S_OK;
90+
}
91+
return E_FAIL;
92+
}
93+
94+
// IContextMenu2
95+
STDMETHODIMP CFontBackgroundMenu::HandleMenuMsg(UINT uMsg, WPARAM wParam, LPARAM lParam)
96+
{
97+
return HandleMenuMsg2(uMsg, wParam, lParam, NULL);
98+
}
99+
100+
// IContextMenu3
101+
STDMETHODIMP CFontBackgroundMenu::HandleMenuMsg2(UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *plResult)
102+
{
103+
if (uMsg == WM_INITMENUPOPUP)
104+
{
105+
HMENU hMenu = (HMENU)wParam;
106+
::DeleteMenu(hMenu, FCIDM_SHVIEW_INSERTLINK, MF_BYCOMMAND);
107+
return S_OK;
108+
}
109+
return E_NOTIMPL;
110+
}
111+
112+
HRESULT
113+
APIENTRY
114+
CFontBackgroundMenu_Create(
115+
CFontExt* pFontExt,
116+
HWND hwnd,
117+
IShellFolder* psf,
118+
IContextMenu** ppcm)
119+
{
120+
DEFCONTEXTMENU dcm;
121+
ZeroMemory(&dcm, sizeof(dcm));
122+
dcm.hwnd = hwnd;
123+
dcm.psf = psf;
124+
return ShellObjectCreatorInit<CFontBackgroundMenu>(pFontExt, &dcm, IID_PPV_ARG(IContextMenu, ppcm));
125+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
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: Fonts folder shell extension background menu
5+
* COPYRIGHT: Copyright 2026 Katayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com>
6+
*/
7+
8+
#pragma once
9+
10+
class CFontBackgroundMenu
11+
: public CComObjectRootEx<CComMultiThreadModelNoCS>
12+
, public IContextMenu3
13+
{
14+
HWND m_hwnd = nullptr;
15+
CFontExt* m_pFontExt = nullptr;
16+
CComPtr<IShellFolder> m_psf;
17+
CComPtr<IContextMenuCB> m_pmcb;
18+
LPFNDFMCALLBACK m_pfnmcb = nullptr;
19+
20+
public:
21+
CFontBackgroundMenu();
22+
virtual ~CFontBackgroundMenu();
23+
HRESULT WINAPI Initialize(CFontExt* pFontExt, const DEFCONTEXTMENU *pdcm);
24+
25+
// IContextMenu
26+
STDMETHODIMP QueryContextMenu(HMENU hMenu, UINT indexMenu, UINT idCmdFirst, UINT idCmdLast, UINT uFlags) override;
27+
STDMETHODIMP InvokeCommand(LPCMINVOKECOMMANDINFO lpcmi) override;
28+
STDMETHODIMP GetCommandString(UINT_PTR idCommand, UINT uFlags, UINT *lpReserved, LPSTR lpszName, UINT uMaxNameLen) override;
29+
30+
// IContextMenu2
31+
STDMETHODIMP HandleMenuMsg(UINT uMsg, WPARAM wParam, LPARAM lParam) override;
32+
33+
// IContextMenu3
34+
STDMETHODIMP HandleMenuMsg2(UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *plResult) override;
35+
36+
BEGIN_COM_MAP(CFontBackgroundMenu)
37+
COM_INTERFACE_ENTRY_IID(IID_IContextMenu, IContextMenu)
38+
COM_INTERFACE_ENTRY_IID(IID_IContextMenu2, IContextMenu2)
39+
COM_INTERFACE_ENTRY_IID(IID_IContextMenu3, IContextMenu3)
40+
END_COM_MAP()
41+
};

0 commit comments

Comments
 (0)