ReactOS 0.4.15-dev-7942-gd23573b
CDefaultContextMenu Class Reference
Inheritance diagram for CDefaultContextMenu:
Collaboration diagram for CDefaultContextMenu:

Public Member Functions

 CDefaultContextMenu ()
 
 ~CDefaultContextMenu ()
 
HRESULT WINAPI Initialize (const DEFCONTEXTMENU *pdcm, LPFNDFMCALLBACK lpfn)
 
STDMETHOD() QueryContextMenu (HMENU hMenu, UINT indexMenu, UINT idCmdFirst, UINT idCmdLast, UINT uFlags) override
 
STDMETHOD() InvokeCommand (LPCMINVOKECOMMANDINFO lpcmi) override
 
STDMETHOD() GetCommandString (UINT_PTR idCommand, UINT uFlags, UINT *lpReserved, LPSTR lpszName, UINT uMaxNameLen) override
 
STDMETHOD() HandleMenuMsg (UINT uMsg, WPARAM wParam, LPARAM lParam) override
 
STDMETHOD() HandleMenuMsg2 (UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *plResult) override
 
STDMETHOD() SetSite (IUnknown *pUnkSite) override
 
STDMETHOD() GetSite (REFIID riid, void **ppvSite) override
 
virtual HRESULT STDMETHODCALLTYPE QueryService (REFGUID svc, REFIID riid, void **ppv)
 
- Public Member Functions inherited from ATL::CComObjectRootEx< CComMultiThreadModelNoCS >
 ~CComObjectRootEx ()
 
ULONG InternalAddRef ()
 
ULONG InternalRelease ()
 
void Lock ()
 
void Unlock ()
 
HRESULT _AtlInitialConstruct ()
 
- Public Member Functions inherited from ATL::CComObjectRootBase
 CComObjectRootBase ()
 
 ~CComObjectRootBase ()
 
void SetVoid (void *)
 
HRESULT _AtlFinalConstruct ()
 
HRESULT FinalConstruct ()
 
void InternalFinalConstructAddRef ()
 
void InternalFinalConstructRelease ()
 
void FinalRelease ()
 
HRESULT HandleMenuMsg2 ([in] UINT uMsg, [in] WPARAM wParam, [in] LPARAM lParam, [out] LRESULT *plResult)
 
HRESULT HandleMenuMsg ([in] UINT uMsg, [in] WPARAM wParam, [in] LPARAM lParam)
 
HRESULT QueryContextMenu ([in] HMENU hmenu, [in] UINT indexMenu, [in] UINT idCmdFirst, [in] UINT idCmdLast, [in] UINT uFlags)
 
HRESULT InvokeCommand ([in] LPCMINVOKECOMMANDINFO lpici)
 
HRESULT GetCommandString ([in] UINT_PTR idCmd, [in] UINT uType, [out] UINT *pwReserved, [out, size_is(cchMax)] LPSTR pszName, [in] UINT cchMax)
 
- Public Member Functions inherited from IUnknown
HRESULT QueryInterface ([in] REFIID riid, [out, iid_is(riid)] void **ppvObject)
 
ULONG AddRef ()
 
ULONG Release ()
 
- Public Member Functions inherited from IObjectWithSite
HRESULT SetSite ([in] IUnknown *pUnkSite)
 
HRESULT GetSite ([in] REFIID riid, [out, iid_is(riid)] PVOID *ppvSite)
 
- Public Member Functions inherited from IServiceProvider
HRESULT QueryService ([in] REFGUID guidService, [in] REFIID riid, [out] void **ppvObject)
 
HRESULT RemoteQueryService ([in] REFGUID guidService, [in] REFIID riid, [out, iid_is(riid)] IUnknown **ppvObject)
 

Private Member Functions

HRESULT _DoCallback (UINT uMsg, WPARAM wParam, LPVOID lParam)
 
void AddStaticEntry (const HKEY hkeyClass, const WCHAR *szVerb, UINT uFlags)
 
void AddStaticEntriesForKey (HKEY hKey, UINT uFlags)
 
void TryPickDefault (HMENU hMenu, UINT idCmdFirst, UINT DfltOffset, UINT uFlags)
 
BOOL IsShellExtensionAlreadyLoaded (REFCLSID clsid)
 
HRESULT LoadDynamicContextMenuHandler (HKEY hKey, REFCLSID clsid)
 
BOOL EnumerateDynamicContextHandlerForKey (HKEY hRootKey)
 
UINT AddShellExtensionsToMenu (HMENU hMenu, UINT *pIndexMenu, UINT idCmdFirst, UINT idCmdLast, UINT uFlags)
 
UINT AddStaticContextMenusToMenu (HMENU hMenu, UINT *IndexMenu, UINT iIdCmdFirst, UINT iIdCmdLast, UINT uFlags)
 
HRESULT DoPaste (LPCMINVOKECOMMANDINFOEX lpcmi, BOOL bLink)
 
HRESULT DoOpenOrExplore (LPCMINVOKECOMMANDINFOEX lpcmi)
 
HRESULT DoCreateLink (LPCMINVOKECOMMANDINFOEX lpcmi)
 
HRESULT DoDelete (LPCMINVOKECOMMANDINFOEX lpcmi)
 
HRESULT DoCopyOrCut (LPCMINVOKECOMMANDINFOEX lpcmi, BOOL bCopy)
 
HRESULT DoRename (LPCMINVOKECOMMANDINFOEX lpcmi)
 
HRESULT DoProperties (LPCMINVOKECOMMANDINFOEX lpcmi)
 
HRESULT DoUndo (LPCMINVOKECOMMANDINFOEX lpcmi)
 
HRESULT DoCreateNewFolder (LPCMINVOKECOMMANDINFOEX lpici)
 
HRESULT DoCopyToMoveToFolder (LPCMINVOKECOMMANDINFOEX lpici, BOOL bCopy)
 
HRESULT InvokeShellExt (LPCMINVOKECOMMANDINFOEX lpcmi)
 
HRESULT InvokeRegVerb (LPCMINVOKECOMMANDINFOEX lpcmi)
 
DWORD BrowserFlagsFromVerb (LPCMINVOKECOMMANDINFOEX lpcmi, PStaticShellEntry pEntry)
 
HRESULT TryToBrowse (LPCMINVOKECOMMANDINFOEX lpcmi, LPCITEMIDLIST pidl, DWORD wFlags)
 
HRESULT InvokePidl (LPCMINVOKECOMMANDINFOEX lpcmi, LPCITEMIDLIST pidl, PStaticShellEntry pEntry)
 
PDynamicShellEntry GetDynamicEntry (UINT idCmd)
 
BOOL MapVerbToCmdId (PVOID Verb, PUINT idCmd, BOOL IsUnicode)
 

Private Attributes

CComPtr< IUnknownm_site
 
CComPtr< IShellFolderm_psf
 
CComPtr< IContextMenuCBm_pmcb
 
LPFNDFMCALLBACK m_pfnmcb
 
UINT m_cidl
 
PCUITEMID_CHILD_ARRAY m_apidl
 
CComPtr< IDataObjectm_pDataObj
 
HKEYm_aKeys
 
UINT m_cKeys
 
PIDLIST_ABSOLUTE m_pidlFolder
 
DWORD m_bGroupPolicyActive
 
CAtlList< DynamicShellEntrym_DynamicEntries
 
UINT m_iIdSHEFirst
 
UINT m_iIdSHELast
 
CAtlList< StaticShellEntrym_StaticEntries
 
UINT m_iIdSCMFirst
 
UINT m_iIdSCMLast
 
UINT m_iIdCBFirst
 
UINT m_iIdCBLast
 
UINT m_iIdDfltFirst
 
UINT m_iIdDfltLast
 
HWND m_hwnd
 

Additional Inherited Members

- Public Types inherited from IContextMenu3
typedef IContextMenu3LPCONTEXTMENU3
 
- Public Types inherited from IContextMenu2
typedef IContextMenu2LPCONTEXTMENU2
 
- Public Types inherited from IContextMenu
typedef IContextMenuLPCONTEXTMENU
 
typedef struct IContextMenu::tagCMINVOKECOMMANDINFO CMINVOKECOMMANDINFO
 
typedef struct IContextMenu::tagCMINVOKECOMMANDINFOLPCMINVOKECOMMANDINFO
 
typedef struct IContextMenu::tagCMInvokeCommandInfoEx CMINVOKECOMMANDINFOEX
 
typedef struct IContextMenu::tagCMInvokeCommandInfoExLPCMINVOKECOMMANDINFOEX
 
- Public Types inherited from IUnknown
typedef IUnknownLPUNKNOWN
 
- Public Types inherited from IObjectWithSite
typedef IObjectWithSiteLPOBJECTWITHSITE
 
- Public Types inherited from IServiceProvider
typedef IServiceProviderLPSERVICEPROVIDER
 
- Static Public Member Functions inherited from ATL::CComObjectRootBase
static void WINAPI ObjectMain (bool)
 
static const struct _ATL_CATMAP_ENTRYGetCategoryMap ()
 
static HRESULT WINAPI InternalQueryInterface (void *pThis, const _ATL_INTMAP_ENTRY *pEntries, REFIID iid, void **ppvObject)
 
- Public Attributes inherited from ATL::CComObjectRootBase
LONG m_dwRef
 
- Static Public Attributes inherited from IContextMenu
static const WCHAR CMDSTR_NEWFOLDERW [] = {'N','e','w','F','o','l','d','e','r',0}
 
static const WCHAR CMDSTR_VIEWLISTW [] = {'V','i','e','w','L','i','s','t',0}
 
static const WCHAR CMDSTR_VIEWDETAILSW [] = {'V','i','e','w','D','e','t','a','i','l','s',0}
 

Detailed Description

Definition at line 83 of file CDefaultContextMenu.cpp.

Constructor & Destructor Documentation

◆ CDefaultContextMenu()

CDefaultContextMenu::CDefaultContextMenu ( )

Definition at line 175 of file CDefaultContextMenu.cpp.

175 :
176 m_psf(NULL),
177 m_pmcb(NULL),
178 m_pfnmcb(NULL),
179 m_cidl(0),
180 m_apidl(NULL),
182 m_aKeys(NULL),
183 m_cKeys(NULL),
186 m_iIdSHEFirst(0),
187 m_iIdSHELast(0),
188 m_iIdSCMFirst(0),
189 m_iIdSCMLast(0),
190 m_iIdCBFirst(0),
191 m_iIdCBLast(0),
193 m_iIdDfltLast(0),
194 m_hwnd(NULL)
195{
196}
CComPtr< IDataObject > m_pDataObj
CComPtr< IShellFolder > m_psf
PCUITEMID_CHILD_ARRAY m_apidl
CComPtr< IContextMenuCB > m_pmcb
PIDLIST_ABSOLUTE m_pidlFolder
#define NULL
Definition: types.h:112

◆ ~CDefaultContextMenu()

CDefaultContextMenu::~CDefaultContextMenu ( )

Definition at line 198 of file CDefaultContextMenu.cpp.

199{
200 m_DynamicEntries.RemoveAll();
201 m_StaticEntries.RemoveAll();
202
203 for (UINT i = 0; i < m_cKeys; i++)
206
207 if (m_pidlFolder)
209 _ILFreeaPidl(const_cast<PITEMID_CHILD *>(m_apidl), m_cidl);
210}
#define RegCloseKey(hKey)
Definition: registry.h:49
CAtlList< StaticShellEntry > m_StaticEntries
CAtlList< DynamicShellEntry > m_DynamicEntries
#define GetProcessHeap()
Definition: compat.h:736
#define HeapFree(x, y, z)
Definition: compat.h:735
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
VOID WINAPI CoTaskMemFree(LPVOID ptr)
Definition: ifs.c:442
unsigned int UINT
Definition: ndis.h:50
void _ILFreeaPidl(LPITEMIDLIST *apidl, UINT cidl)
Definition: pidl.c:2690

Member Function Documentation

◆ _DoCallback()

HRESULT CDefaultContextMenu::_DoCallback ( UINT  uMsg,
WPARAM  wParam,
LPVOID  lParam 
)
private

Definition at line 260 of file CDefaultContextMenu.cpp.

261{
262 if (m_pmcb)
263 {
264 return m_pmcb->CallBack(m_psf, m_hwnd, m_pDataObj, uMsg, wParam, (LPARAM)lParam);
265 }
266 else if(m_pfnmcb)
267 {
269 }
270
271 return E_FAIL;
272}
WPARAM wParam
Definition: combotst.c:138
LPARAM lParam
Definition: combotst.c:139
#define E_FAIL
Definition: ddrawi.h:102
LONG_PTR LPARAM
Definition: windef.h:208

Referenced by DoProperties(), InvokeCommand(), QueryContextMenu(), and TryPickDefault().

◆ AddShellExtensionsToMenu()

UINT CDefaultContextMenu::AddShellExtensionsToMenu ( HMENU  hMenu,
UINT pIndexMenu,
UINT  idCmdFirst,
UINT  idCmdLast,
UINT  uFlags 
)
private

Definition at line 462 of file CDefaultContextMenu.cpp.

463{
464 UINT cIds = 0;
465
466 if (m_DynamicEntries.IsEmpty())
467 return cIds;
468
469 POSITION it = m_DynamicEntries.GetHeadPosition();
470 while (it != NULL)
471 {
473
474 HRESULT hr = info.pCM->QueryContextMenu(hMenu, *pIndexMenu, idCmdFirst + cIds, idCmdLast, uFlags);
475 if (SUCCEEDED(hr))
476 {
477 info.iIdCmdFirst = cIds;
478 info.NumIds = HRESULT_CODE(hr);
479 (*pIndexMenu) += info.NumIds;
480
481 cIds += info.NumIds;
482 if (idCmdFirst + cIds >= idCmdLast)
483 break;
484 }
485 TRACE("pEntry hr %x contextmenu %p cmdfirst %x num ids %x\n", hr, info.pCM.p, info.iIdCmdFirst, info.NumIds);
486 }
487 return cIds;
488}
UINT uFlags
Definition: api.c:59
#define SUCCEEDED(hr)
Definition: intsafe.h:50
HRESULT hr
Definition: shlfolder.c:183
#define TRACE(s)
Definition: solgame.cpp:4
#define HRESULT_CODE(hr)
Definition: winerror.h:76

Referenced by QueryContextMenu().

◆ AddStaticContextMenusToMenu()

UINT CDefaultContextMenu::AddStaticContextMenusToMenu ( HMENU  hMenu,
UINT IndexMenu,
UINT  iIdCmdFirst,
UINT  iIdCmdLast,
UINT  uFlags 
)
private

Definition at line 491 of file CDefaultContextMenu.cpp.

497{
499 MENUITEMINFOW mii = { sizeof(mii) };
500 UINT idResource;
501 WCHAR wszVerb[40];
502 UINT fState;
503 UINT cIds = 0, indexFirst = *pIndexMenu;
504
506 mii.fType = MFT_STRING;
507
508 POSITION it = m_StaticEntries.GetHeadPosition();
509 bool first = true;
510 while (it != NULL)
511 {
513 BOOL forceFirstPos = FALSE;
514
515 fState = MFS_ENABLED;
516
517 /* set first entry as default */
518 if (first)
519 {
520 fState |= MFS_DEFAULT;
521 first = false;
522 }
523
524 if (info.Verb.CompareNoCase(L"open") == 0)
525 {
526 idResource = IDS_OPEN_VERB;
527 fState |= MFS_DEFAULT; /* override default when open verb is found */
528 forceFirstPos++;
529 }
530 else if (info.Verb.CompareNoCase(L"explore") == 0)
531 {
532 idResource = IDS_EXPLORE_VERB;
533 if (uFlags & CMF_EXPLORE)
534 {
535 fState |= MFS_DEFAULT;
536 forceFirstPos++;
537 }
538 }
539 else if (info.Verb.CompareNoCase(L"runas") == 0)
540 idResource = IDS_RUNAS_VERB;
541 else if (info.Verb.CompareNoCase(L"edit") == 0)
542 idResource = IDS_EDIT_VERB;
543 else if (info.Verb.CompareNoCase(L"find") == 0)
544 idResource = IDS_FIND_VERB;
545 else if (info.Verb.CompareNoCase(L"print") == 0)
546 idResource = IDS_PRINT_VERB;
547 else if (info.Verb.CompareNoCase(L"printto") == 0)
548 continue;
549 else
550 idResource = 0;
551
552 /* By default use verb for menu item name */
553 mii.dwTypeData = (LPWSTR)info.Verb.GetString();
554
555 WCHAR wszKey[sizeof("shell\\") + MAX_VERB];
556 HRESULT hr;
557 hr = StringCbPrintfW(wszKey, sizeof(wszKey), L"shell\\%s", info.Verb.GetString());
559 {
560 continue;
561 }
562
563 UINT cmdFlags = 0;
564 bool hide = false;
565 HKEY hkVerb;
566 if (idResource > 0)
567 {
568 if (!(uFlags & CMF_OPTIMIZEFORINVOKE))
569 {
570 if (LoadStringW(shell32_hInstance, idResource, wszVerb, _countof(wszVerb)))
571 mii.dwTypeData = wszVerb; /* use translated verb */
572 else
573 ERR("Failed to load string\n");
574 }
575
576 if (RegOpenKeyW(info.hkClass, wszKey, &hkVerb) != ERROR_SUCCESS)
577 hkVerb = NULL;
578 }
579 else
580 {
581 if (RegOpenKeyW(info.hkClass, wszKey, &hkVerb) == ERROR_SUCCESS)
582 {
583 if (!(uFlags & CMF_OPTIMIZEFORINVOKE))
584 {
585 DWORD cbVerb = sizeof(wszVerb);
586
587 LONG res = RegLoadMUIStringW(hkVerb, L"MUIVerb", wszVerb, cbVerb, NULL, 0, NULL);
588 if (res || !*wszVerb)
589 res = RegLoadMUIStringW(hkVerb, NULL, wszVerb, cbVerb, NULL, 0, NULL);
590
591 if (res == ERROR_SUCCESS && *wszVerb)
592 {
593 /* use description for the menu entry */
594 mii.dwTypeData = wszVerb;
595 }
596 }
597 }
598 else
599 {
600 hkVerb = NULL;
601 }
602 }
603
604 if (hkVerb)
605 {
606 // FIXME: GetAsyncKeyState should not be called here, clients
607 // need to be updated to set the CMF_EXTENDEDVERBS flag.
608 if (!(uFlags & CMF_EXTENDEDVERBS) && GetAsyncKeyState(VK_SHIFT) >= 0)
609 hide = RegValueExists(hkVerb, L"Extended");
610
611 if (!hide)
612 hide = RegValueExists(hkVerb, L"ProgrammaticAccessOnly");
613
614 if (!hide && !(uFlags & CMF_DISABLEDVERBS))
615 hide = RegValueExists(hkVerb, L"LegacyDisable");
616
617 if (RegValueExists(hkVerb, L"NeverDefault"))
618 fState &= ~MFS_DEFAULT;
619
620 if (RegValueExists(hkVerb, L"SeparatorBefore"))
621 cmdFlags |= ECF_SEPARATORBEFORE;
622 if (RegValueExists(hkVerb, L"SeparatorAfter"))
623 cmdFlags |= ECF_SEPARATORAFTER;
624
625 RegCloseKey(hkVerb);
626 }
627
628 if (((uFlags & CMF_NODEFAULT) && ntver >= _WIN32_WINNT_VISTA) ||
629 ((uFlags & CMF_DONOTPICKDEFAULT) && ntver >= _WIN32_WINNT_WIN7))
630 {
631 fState &= ~MFS_DEFAULT;
632 }
633
634 if (!hide)
635 {
636 if (cmdFlags & ECF_SEPARATORBEFORE)
637 {
638 if (InsertMenuItemAt(hMenu, *pIndexMenu, MF_SEPARATOR))
639 (*pIndexMenu)++;
640 }
641
642 mii.fState = fState;
643 mii.wID = iIdCmdFirst + cIds;
644 if (InsertMenuItemW(hMenu, forceFirstPos ? indexFirst : *pIndexMenu, TRUE, &mii))
645 (*pIndexMenu)++;
646
647 if (cmdFlags & ECF_SEPARATORAFTER)
648 {
649 if (InsertMenuItemAt(hMenu, *pIndexMenu, MF_SEPARATOR))
650 (*pIndexMenu)++;
651 }
652 }
653 cIds++; // Always increment the id because it acts as the index into m_StaticEntries
654
655 if (mii.wID >= iIdCmdLast)
656 break;
657 }
658
659 return cIds;
660}
static bool RegValueExists(HKEY hKey, LPCWSTR Name)
static BOOL InsertMenuItemAt(HMENU hMenu, UINT Pos, UINT Flags)
#define MAX_VERB
#define shell32_hInstance
#define ERR(fmt,...)
Definition: debug.h:110
static UINT RosGetProcessEffectiveVersion(VOID)
Definition: compat_undoc.h:39
#define ERROR_SUCCESS
Definition: deptool.c:10
LONG RegLoadMUIStringW(IN HKEY hKey, IN LPCWSTR pszValue OPTIONAL, OUT LPWSTR pszOutBuf, IN DWORD cbOutBuf, OUT LPDWORD pcbData OPTIONAL, IN DWORD Flags, IN LPCWSTR pszDirectory OPTIONAL)
Definition: muireg.c:53
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
LONG WINAPI RegOpenKeyW(HKEY hKey, LPCWSTR lpSubKey, PHKEY phkResult)
Definition: reg.c:3268
#define FAILED_UNEXPECTEDLY(hr)
Definition: precomp.h:121
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
GLuint res
Definition: glext.h:9613
const GLint * first
Definition: glext.h:5794
#define L(x)
Definition: ntvdm.h:50
long LONG
Definition: pedump.c:60
#define _WIN32_WINNT_WIN7
Definition: sdkddkver.h:28
#define _WIN32_WINNT_VISTA
Definition: sdkddkver.h:25
#define IDS_OPEN_VERB
Definition: shresdef.h:212
#define IDS_FIND_VERB
Definition: shresdef.h:216
#define IDS_EXPLORE_VERB
Definition: shresdef.h:213
#define IDS_PRINT_VERB
Definition: shresdef.h:217
#define IDS_RUNAS_VERB
Definition: shresdef.h:214
#define IDS_EDIT_VERB
Definition: shresdef.h:215
#define _countof(array)
Definition: sndvol32.h:68
STRSAFEAPI StringCbPrintfW(STRSAFE_LPWSTR pszDest, size_t cbDest, STRSAFE_LPCWSTR pszFormat,...)
Definition: strsafe.h:557
LPWSTR dwTypeData
Definition: winuser.h:3269
#define MIIM_ID
Definition: winuser.h:722
int WINAPI LoadStringW(_In_opt_ HINSTANCE hInstance, _In_ UINT uID, _Out_writes_to_(cchBufferMax, return+1) LPWSTR lpBuffer, _In_ int cchBufferMax)
#define MIIM_STATE
Definition: winuser.h:721
#define MFS_DEFAULT
Definition: winuser.h:748
#define MF_SEPARATOR
Definition: winuser.h:137
#define MFS_ENABLED
Definition: winuser.h:750
#define VK_SHIFT
Definition: winuser.h:2202
#define MFT_STRING
Definition: winuser.h:746
SHORT WINAPI GetAsyncKeyState(_In_ int)
#define MIIM_DATA
Definition: winuser.h:726
#define MIIM_TYPE
Definition: winuser.h:725
BOOL WINAPI InsertMenuItemW(_In_ HMENU, _In_ UINT, _In_ BOOL, _In_ LPCMENUITEMINFOW)
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR * LPWSTR
Definition: xmlstorage.h:184

Referenced by QueryContextMenu().

◆ AddStaticEntriesForKey()

void CDefaultContextMenu::AddStaticEntriesForKey ( HKEY  hKey,
UINT  uFlags 
)
private

Definition at line 300 of file CDefaultContextMenu.cpp.

301{
302 WCHAR wszName[40];
303 DWORD cchName, dwIndex = 0;
304 HKEY hShellKey;
305
306 LRESULT lres = RegOpenKeyExW(hKey, L"shell", 0, KEY_READ, &hShellKey);
307 if (lres != STATUS_SUCCESS)
308 return;
309
310 while(TRUE)
311 {
312 cchName = _countof(wszName);
313 if (RegEnumKeyExW(hShellKey, dwIndex++, wszName, &cchName, NULL, NULL, NULL, NULL) != ERROR_SUCCESS)
314 break;
315
316 AddStaticEntry(hKey, wszName, uFlags);
317 }
318
319 RegCloseKey(hShellKey);
320}
void AddStaticEntry(const HKEY hkeyClass, const WCHAR *szVerb, UINT uFlags)
LONG WINAPI RegOpenKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult)
Definition: reg.c:3333
LONG WINAPI RegEnumKeyExW(_In_ HKEY hKey, _In_ DWORD dwIndex, _Out_ LPWSTR lpName, _Inout_ LPDWORD lpcbName, _Reserved_ LPDWORD lpReserved, _Out_opt_ LPWSTR lpClass, _Inout_opt_ LPDWORD lpcbClass, _Out_opt_ PFILETIME lpftLastWriteTime)
Definition: reg.c:2504
FxAutoRegKey hKey
#define KEY_READ
Definition: nt_native.h:1023
#define STATUS_SUCCESS
Definition: shellext.h:65
_In_ PSID _Out_writes_to_opt_ cchName LPSTR _Inout_ LPDWORD cchName
Definition: winbase.h:2767
LONG_PTR LRESULT
Definition: windef.h:209

Referenced by QueryContextMenu().

◆ AddStaticEntry()

void CDefaultContextMenu::AddStaticEntry ( const HKEY  hkeyClass,
const WCHAR szVerb,
UINT  uFlags 
)
private

Definition at line 274 of file CDefaultContextMenu.cpp.

275{
276 POSITION it = m_StaticEntries.GetHeadPosition();
277 while (it != NULL)
278 {
279 const StaticShellEntry& info = m_StaticEntries.GetNext(it);
280 if (info.Verb.CompareNoCase(szVerb) == 0)
281 {
282 /* entry already exists */
283 return;
284 }
285 }
286
287 TRACE("adding verb %s\n", debugstr_w(szVerb));
288
289 if (!wcsicmp(szVerb, L"open") && !(uFlags & CMF_NODEFAULT))
290 {
291 /* open verb is always inserted in front */
292 m_StaticEntries.AddHead({ szVerb, hkeyClass });
293 }
294 else
295 {
296 m_StaticEntries.AddTail({ szVerb, hkeyClass });
297 }
298}
#define wcsicmp
Definition: compat.h:15
#define debugstr_w
Definition: kernel32.h:32

Referenced by AddStaticEntriesForKey().

◆ BrowserFlagsFromVerb()

DWORD CDefaultContextMenu::BrowserFlagsFromVerb ( LPCMINVOKECOMMANDINFOEX  lpcmi,
PStaticShellEntry  pEntry 
)
private

Definition at line 1157 of file CDefaultContextMenu.cpp.

1158{
1160 HWND hwndTree;
1161 LPCWSTR FlagsName;
1162 WCHAR wszKey[sizeof("shell\\") + MAX_VERB];
1163 HRESULT hr;
1164 DWORD wFlags;
1165 DWORD cbVerb;
1166
1167 if (!m_site)
1168 return 0;
1169
1170 /* Get a pointer to the shell browser */
1172 if (FAILED(hr))
1173 return 0;
1174
1175 /* See if we are in Explore or Browse mode. If the browser's tree is present, we are in Explore mode.*/
1176 if (SUCCEEDED(psb->GetControlWindow(FCW_TREE, &hwndTree)) && hwndTree)
1177 FlagsName = L"ExplorerFlags";
1178 else
1179 FlagsName = L"BrowserFlags";
1180
1181 /* Try to get the flag from the verb */
1182 hr = StringCbPrintfW(wszKey, sizeof(wszKey), L"shell\\%s", pEntry->Verb.GetString());
1184 return 0;
1185
1186 cbVerb = sizeof(wFlags);
1187 if (RegGetValueW(pEntry->hkClass, wszKey, FlagsName, RRF_RT_REG_DWORD, NULL, &wFlags, &cbVerb) == ERROR_SUCCESS)
1188 {
1189 return wFlags;
1190 }
1191
1192 return 0;
1193}
CComPtr< IUnknown > m_site
LSTATUS WINAPI RegGetValueW(HKEY hKey, LPCWSTR pszSubKey, LPCWSTR pszValue, DWORD dwFlags, LPDWORD pdwType, PVOID pvData, LPDWORD pcbData)
Definition: reg.c:1931
#define RRF_RT_REG_DWORD
Definition: driver.c:578
HRESULT WINAPI IUnknown_QueryService(IUnknown *, REFGUID, REFIID, LPVOID *)
Definition: ordinal.c:1497
PLIST_ENTRY pEntry
Definition: fxioqueue.cpp:4484
#define FAILED(hr)
Definition: intsafe.h:51
#define SID_IShellBrowser
_In_ DWORD _Out_ _In_ WORD wFlags
Definition: wincon.h:531
#define IID_PPV_ARG(Itype, ppType)
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185

Referenced by InvokeRegVerb().

◆ DoCopyOrCut()

HRESULT CDefaultContextMenu::DoCopyOrCut ( LPCMINVOKECOMMANDINFOEX  lpcmi,
BOOL  bCopy 
)
private

Definition at line 921 of file CDefaultContextMenu.cpp.

922{
923 if (!m_cidl || !m_pDataObj)
924 return E_FAIL;
925
926 FORMATETC formatetc;
928 STGMEDIUM medium = {0};
929 medium.tymed = TYMED_HGLOBAL;
930 medium.hGlobal = GlobalAlloc(GHND, sizeof(DWORD));
931 DWORD* pdwFlag = (DWORD*)GlobalLock(medium.hGlobal);
932 if (pdwFlag)
933 *pdwFlag = bCopy ? DROPEFFECT_COPY : DROPEFFECT_MOVE;
934 GlobalUnlock(medium.hGlobal);
935 m_pDataObj->SetData(&formatetc, &medium, TRUE);
936
939 return hr;
940
941 return S_OK;
942}
HRESULT WINAPI OleSetClipboard(IDataObject *data)
Definition: clipboard.c:2199
#define InitFormatEtc(fe, cf, med)
Definition: editor.h:32
LPVOID NTAPI GlobalLock(HGLOBAL hMem)
Definition: heapmem.c:755
BOOL NTAPI GlobalUnlock(HGLOBAL hMem)
Definition: heapmem.c:1190
HGLOBAL NTAPI GlobalAlloc(UINT uFlags, SIZE_T dwBytes)
Definition: heapmem.c:368
#define S_OK
Definition: intsafe.h:52
#define CFSTR_PREFERREDDROPEFFECT
Definition: shlobj.h:553
#define GHND
Definition: winbase.h:297
UINT WINAPI RegisterClipboardFormatW(_In_ LPCWSTR)

Referenced by InvokeCommand().

◆ DoCopyToMoveToFolder()

HRESULT CDefaultContextMenu::DoCopyToMoveToFolder ( LPCMINVOKECOMMANDINFOEX  lpici,
BOOL  bCopy 
)
private

Definition at line 993 of file CDefaultContextMenu.cpp.

994{
995 HRESULT hr = E_FAIL;
996 if (!m_pDataObj)
997 {
998 ERR("m_pDataObj is NULL\n");
999 return hr;
1000 }
1001
1002 CComPtr<IContextMenu> pContextMenu;
1003 if (bCopy)
1004 hr = SHCoCreateInstance(NULL, &CLSID_CopyToMenu, NULL,
1005 IID_PPV_ARG(IContextMenu, &pContextMenu));
1006 else
1007 hr = SHCoCreateInstance(NULL, &CLSID_MoveToMenu, NULL,
1008 IID_PPV_ARG(IContextMenu, &pContextMenu));
1010 return hr;
1011
1013 hr = pContextMenu->QueryInterface(IID_PPV_ARG(IShellExtInit, &pInit));
1015 return hr;
1016
1017 hr = pInit->Initialize(m_pidlFolder, m_pDataObj, NULL);
1019 return hr;
1020
1021 if (bCopy)
1022 lpici->lpVerb = "copyto";
1023 else
1024 lpici->lpVerb = "moveto";
1025
1026 return pContextMenu->InvokeCommand((LPCMINVOKECOMMANDINFO)lpici);
1027}
HRESULT WINAPI SHCoCreateInstance(LPCWSTR aclsid, const CLSID *clsid, LPUNKNOWN pUnkOuter, REFIID refiid, LPVOID *ppv)
Definition: shellole.c:105
PWDFDEVICE_INIT pInit
struct IContextMenu::tagCMINVOKECOMMANDINFO * LPCMINVOKECOMMANDINFO

Referenced by InvokeCommand().

◆ DoCreateLink()

HRESULT CDefaultContextMenu::DoCreateLink ( LPCMINVOKECOMMANDINFOEX  lpcmi)
private

Definition at line 890 of file CDefaultContextMenu.cpp.

891{
892 if (!m_cidl || !m_pDataObj)
893 return E_FAIL;
894
896 HRESULT hr = m_psf->CreateViewObject(NULL, IID_PPV_ARG(IDropTarget, &pDT));
898 return hr;
899
901
902 return S_OK;
903}
BOOL WINAPI SHSimulateDrop(IDropTarget *pDrop, IDataObject *pDataObj, DWORD grfKeyState, PPOINTL lpPt, DWORD *pdwEffect)
Definition: ordinal.c:1824
#define MK_SHIFT
Definition: winuser.h:2369
#define MK_CONTROL
Definition: winuser.h:2370

Referenced by InvokeCommand().

◆ DoCreateNewFolder()

HRESULT CDefaultContextMenu::DoCreateNewFolder ( LPCMINVOKECOMMANDINFOEX  lpici)
private

Definition at line 1031 of file CDefaultContextMenu.cpp.

1033{
1034 WCHAR wszPath[MAX_PATH];
1035 WCHAR wszName[MAX_PATH];
1036 WCHAR wszNewFolder[25];
1037 HRESULT hr;
1038
1039 /* Get folder path */
1042 return hr;
1043
1044 if (!LoadStringW(shell32_hInstance, IDS_NEWFOLDER, wszNewFolder, _countof(wszNewFolder)))
1045 return E_FAIL;
1046
1047 /* Create the name of the new directory */
1048 if (!PathYetAnotherMakeUniqueName(wszName, wszPath, NULL, wszNewFolder))
1049 return E_FAIL;
1050
1051 /* Create the new directory and show the appropriate dialog in case of error */
1052 if (SHCreateDirectory(lpici->hwnd, wszName) != ERROR_SUCCESS)
1053 return E_FAIL;
1054
1055 /* Show and select the new item in the def view */
1056 LPITEMIDLIST pidl;
1057 PITEMID_CHILD pidlNewItem;
1059
1060 /* Notify the view object about the new item */
1062
1063 if (!m_site)
1064 return S_OK;
1065
1066 /* Get a pointer to the shell view */
1069 return S_OK;
1070
1071 /* Attempt to get the pidl of the new item */
1072 hr = SHILCreateFromPathW(wszName, &pidl, NULL);
1074 return hr;
1075
1076 pidlNewItem = ILFindLastID(pidl);
1077
1078 hr = psv->SelectItem(pidlNewItem, SVSI_DESELECTOTHERS | SVSI_EDIT | SVSI_ENSUREVISIBLE |
1079 SVSI_FOCUSED | SVSI_SELECT);
1081 return hr;
1082
1083 SHFree(pidl);
1084
1085 return S_OK;
1086}
EXTERN_C void WINAPI SHChangeNotify(LONG wEventId, UINT uFlags, LPCVOID dwItem1, LPCVOID dwItem2)
#define MAX_PATH
Definition: compat.h:34
void WINAPI SHFree(LPVOID pv)
Definition: shellole.c:326
BOOL WINAPI PathYetAnotherMakeUniqueName(LPWSTR buffer, LPCWSTR path, LPCWSTR shortname, LPCWSTR longname)
Definition: shellpath.c:699
#define IDS_NEWFOLDER
HRESULT WINAPI SHILCreateFromPathW(LPCWSTR path, LPITEMIDLIST *ppidl, DWORD *attributes)
Definition: pidl.c:401
LPITEMIDLIST WINAPI ILFindLastID(LPCITEMIDLIST pidl)
Definition: pidl.c:198
BOOL WINAPI SHGetPathFromIDListW(LPCITEMIDLIST pidl, LPWSTR pszPath)
Definition: pidl.c:1353
int WINAPI SHCreateDirectory(HWND hWnd, LPCWSTR path)
Definition: shlfileop.cpp:847
#define SID_IFolderView
#define SHCNE_MKDIR
Definition: shlobj.h:1878
#define SHCNF_FLUSH
Definition: shlobj.h:1913
#define SHCNF_PATHW
Definition: shlobj.h:1910
ITEMIDLIST UNALIGNED * LPITEMIDLIST
Definition: shtypes.idl:41
CONST void * LPCVOID
Definition: windef.h:191

Referenced by InvokeCommand().

◆ DoDelete()

HRESULT CDefaultContextMenu::DoDelete ( LPCMINVOKECOMMANDINFOEX  lpcmi)
private

Definition at line 905 of file CDefaultContextMenu.cpp.

906{
907 if (!m_cidl || !m_pDataObj)
908 return E_FAIL;
909
913 return hr;
914
915 DWORD grfKeyState = (lpcmi->fMask & CMIC_MASK_SHIFT_DOWN) ? MK_SHIFT : 0;
916 SHSimulateDrop(pDT, m_pDataObj, grfKeyState, NULL, NULL);
917
918 return S_OK;
919}
HRESULT CRecyclerDropTarget_CreateInstance(REFIID riid, LPVOID *ppvOut)

Referenced by InvokeCommand().

◆ DoOpenOrExplore()

HRESULT CDefaultContextMenu::DoOpenOrExplore ( LPCMINVOKECOMMANDINFOEX  lpcmi)
private

Definition at line 884 of file CDefaultContextMenu.cpp.

885{
887 return E_FAIL;
888}
#define UNIMPLEMENTED
Definition: debug.h:115

Referenced by InvokeCommand().

◆ DoPaste()

HRESULT CDefaultContextMenu::DoPaste ( LPCMINVOKECOMMANDINFOEX  lpcmi,
BOOL  bLink 
)
private

Definition at line 831 of file CDefaultContextMenu.cpp.

832{
833 HRESULT hr;
834
836 hr = OleGetClipboard(&pda);
838 return hr;
839
840 FORMATETC formatetc2;
841 STGMEDIUM medium2;
843
844 DWORD dwKey= 0;
845
846 if (SUCCEEDED(pda->GetData(&formatetc2, &medium2)))
847 {
848 DWORD * pdwFlag = (DWORD*)GlobalLock(medium2.hGlobal);
849 if (pdwFlag)
850 {
851 if (*pdwFlag == DROPEFFECT_COPY)
852 dwKey = MK_CONTROL;
853 else
854 dwKey = MK_SHIFT;
855 }
856 else
857 {
858 ERR("No drop effect obtained\n");
859 }
860 GlobalUnlock(medium2.hGlobal);
861 }
862
863 if (bLink)
864 {
865 dwKey = MK_CONTROL|MK_SHIFT;
866 }
867
869 if (m_cidl)
870 hr = m_psf->GetUIObjectOf(NULL, 1, &m_apidl[0], IID_NULL_PPV_ARG(IDropTarget, &pdrop));
871 else
872 hr = m_psf->CreateViewObject(NULL, IID_PPV_ARG(IDropTarget, &pdrop));
873
875 return hr;
876
877 SHSimulateDrop(pdrop, pda, dwKey, NULL, NULL);
878
879 TRACE("CP result %x\n", hr);
880 return S_OK;
881}
HRESULT WINAPI OleGetClipboard(IDataObject **obj)
Definition: clipboard.c:2249
#define IID_NULL_PPV_ARG(Itype, ppType)

Referenced by InvokeCommand().

◆ DoProperties()

HRESULT CDefaultContextMenu::DoProperties ( LPCMINVOKECOMMANDINFOEX  lpcmi)
private

Definition at line 971 of file CDefaultContextMenu.cpp.

973{
975
976 // We are asked to run the default property sheet
977 if (hr == S_FALSE)
978 {
980 }
981
982 return hr;
983}
HRESULT _DoCallback(UINT uMsg, WPARAM wParam, LPVOID lParam)
#define DFM_INVOKECOMMAND
Definition: precomp.h:45
HRESULT WINAPI Shell_DefaultContextMenuCallBack(IShellFolder *psf, IDataObject *pdtobj)
Definition: shlfolder.cpp:497
#define DFM_CMD_PROPERTIES
Definition: shlobj.h:2597
#define S_FALSE
Definition: winerror.h:2357

Referenced by InvokeCommand().

◆ DoRename()

HRESULT CDefaultContextMenu::DoRename ( LPCMINVOKECOMMANDINFOEX  lpcmi)
private

Definition at line 944 of file CDefaultContextMenu.cpp.

945{
947 HRESULT hr;
948
949 if (!m_site || !m_cidl)
950 return E_FAIL;
951
952 /* Get a pointer to the shell browser */
955 return hr;
956
958 hr = psb->QueryActiveShellView(&lpSV);
960 return hr;
961
962 SVSIF selFlags = SVSI_DESELECTOTHERS | SVSI_EDIT | SVSI_ENSUREVISIBLE | SVSI_FOCUSED | SVSI_SELECT;
963 hr = lpSV->SelectItem(m_apidl[0], selFlags);
965 return hr;
966
967 return S_OK;
968}

Referenced by InvokeCommand().

◆ DoUndo()

HRESULT CDefaultContextMenu::DoUndo ( LPCMINVOKECOMMANDINFOEX  lpcmi)
private

Definition at line 986 of file CDefaultContextMenu.cpp.

987{
988 ERR("TODO: Undo\n");
989 return E_NOTIMPL;
990}
#define E_NOTIMPL
Definition: ddrawi.h:99

Referenced by InvokeCommand().

◆ EnumerateDynamicContextHandlerForKey()

BOOL CDefaultContextMenu::EnumerateDynamicContextHandlerForKey ( HKEY  hRootKey)
private

Definition at line 398 of file CDefaultContextMenu.cpp.

399{
400 WCHAR wszName[MAX_PATH], wszBuf[MAX_PATH], *pwszClsid;
402 HRESULT hr;
403 HKEY hKey;
404
405 if (RegOpenKeyExW(hRootKey, L"shellex\\ContextMenuHandlers", 0, KEY_READ, &hKey) != ERROR_SUCCESS)
406 {
407 TRACE("RegOpenKeyExW failed\n");
408 return FALSE;
409 }
410
411 DWORD dwIndex = 0;
412 while (TRUE)
413 {
414 cchName = _countof(wszName);
415 if (RegEnumKeyExW(hKey, dwIndex++, wszName, &cchName, NULL, NULL, NULL, NULL) != ERROR_SUCCESS)
416 break;
417
418 /* Key name or key value is CLSID */
419 CLSID clsid;
420 hr = CLSIDFromString(wszName, &clsid);
421 if (hr == S_OK)
422 pwszClsid = wszName;
423 else
424 {
425 DWORD cchBuf = _countof(wszBuf);
426 if (RegGetValueW(hKey, wszName, NULL, RRF_RT_REG_SZ, NULL, wszBuf, &cchBuf) == ERROR_SUCCESS)
427 hr = CLSIDFromString(wszBuf, &clsid);
428 pwszClsid = wszBuf;
429 }
430
431 if (FAILED(hr))
432 {
433 ERR("CLSIDFromString failed for clsid %S hr 0x%x\n", pwszClsid, hr);
434 continue;
435 }
436
438 {
440 L"Software\\Microsoft\\Windows\\CurrentVersion\\Shell Extensions\\Approved",
441 pwszClsid,
443 NULL,
444 NULL,
446 {
447 ERR("Shell extension %s not approved!\n", pwszClsid);
448 continue;
449 }
450 }
451
453 if (FAILED(hr))
454 WARN("Failed to get context menu entires from shell extension! clsid: %S\n", pwszClsid);
455 }
456
458 return TRUE;
459}
#define WARN(fmt,...)
Definition: debug.h:112
HRESULT LoadDynamicContextMenuHandler(HKEY hKey, REFCLSID clsid)
HRESULT WINAPI CLSIDFromString(LPCOLESTR idstr, LPCLSID id)
Definition: compobj.c:2338
#define RRF_RT_REG_SZ
Definition: driver.c:575
REFCLSID clsid
Definition: msctf.c:82
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12

Referenced by QueryContextMenu().

◆ GetCommandString()

HRESULT WINAPI CDefaultContextMenu::GetCommandString ( UINT_PTR  idCommand,
UINT  uFlags,
UINT lpReserved,
LPSTR  lpszName,
UINT  uMaxNameLen 
)
override

Implements IContextMenu.

Definition at line 1456 of file CDefaultContextMenu.cpp.

1462{
1463 /* We don't handle the help text yet */
1464 if (uFlags == GCS_HELPTEXTA ||
1465 uFlags == GCS_HELPTEXTW ||
1466 HIWORD(idCommand) != 0)
1467 {
1468 return E_NOTIMPL;
1469 }
1470
1471 UINT CmdId = LOWORD(idCommand);
1472
1473 if (!m_DynamicEntries.IsEmpty() && CmdId >= m_iIdSHEFirst && CmdId < m_iIdSHELast)
1474 {
1475 idCommand -= m_iIdSHEFirst;
1477 if (!pEntry)
1478 return E_FAIL;
1479
1480 idCommand -= pEntry->iIdCmdFirst;
1481 return pEntry->pCM->GetCommandString(idCommand,
1482 uFlags,
1483 lpReserved,
1484 lpszName,
1485 uMaxNameLen);
1486 }
1487
1488 if (!m_StaticEntries.IsEmpty() && CmdId >= m_iIdSCMFirst && CmdId < m_iIdSCMLast)
1489 {
1490 /* Validation just returns S_OK on a match. The id exists. */
1491 if (uFlags == GCS_VALIDATEA || uFlags == GCS_VALIDATEW)
1492 return S_OK;
1493
1494 CmdId -= m_iIdSCMFirst;
1495
1496 POSITION it = m_StaticEntries.FindIndex(CmdId);
1497
1498 if (it == NULL)
1499 return E_INVALIDARG;
1500
1502
1503 if (uFlags == GCS_VERBW)
1504 return StringCchCopyW((LPWSTR)lpszName, uMaxNameLen, pEntry->Verb);
1505
1506 if (uFlags == GCS_VERBA)
1507 {
1508 if (SHUnicodeToAnsi(pEntry->Verb, lpszName, uMaxNameLen))
1509 return S_OK;
1510 }
1511
1512 return E_INVALIDARG;
1513 }
1514
1515 //FIXME: Should we handle callbacks here?
1516 if (m_iIdDfltFirst != m_iIdDfltLast && CmdId >= m_iIdDfltFirst && CmdId < m_iIdDfltLast)
1517 {
1518 CmdId -= m_iIdDfltFirst;
1519 /* See the definitions of IDM_CUT and co to see how this works */
1520 CmdId += DCM_FCIDM_SHVIEW_OFFSET;
1521 }
1522
1523 /* Loop looking for a matching Id */
1524 for (UINT i = 0; i < _countof(g_StaticInvokeCmdMap); i++)
1525 {
1526 if (g_StaticInvokeCmdMap[i].IntVerb == CmdId)
1527 {
1528 /* Validation just returns S_OK on a match */
1529 if (uFlags == GCS_VALIDATEA || uFlags == GCS_VALIDATEW)
1530 return S_OK;
1531
1532 /* Return a copy of the ANSI verb */
1533 if (uFlags == GCS_VERBA)
1534 return StringCchCopyA(lpszName, uMaxNameLen, g_StaticInvokeCmdMap[i].szStringVerb);
1535
1536 /* Convert the ANSI verb to unicode and return that */
1537 if (uFlags == GCS_VERBW)
1538 {
1539 if (SHAnsiToUnicode(g_StaticInvokeCmdMap[i].szStringVerb, (LPWSTR)lpszName, uMaxNameLen))
1540 return S_OK;
1541 }
1542 }
1543 }
1544
1545 return E_INVALIDARG;
1546}
static const struct _StaticInvokeCommandMap_ g_StaticInvokeCmdMap[]
#define DCM_FCIDM_SHVIEW_OFFSET
PDynamicShellEntry GetDynamicEntry(UINT idCmd)
#define E_INVALIDARG
Definition: ddrawi.h:101
DWORD WINAPI SHAnsiToUnicode(LPCSTR lpSrcStr, LPWSTR lpDstStr, int iLen)
Definition: string.c:2667
INT WINAPI SHUnicodeToAnsi(LPCWSTR lpSrcStr, LPSTR lpDstStr, INT iLen)
Definition: string.c:2791
#define LOWORD(l)
Definition: pedump.c:82
STRSAFEAPI StringCchCopyW(STRSAFE_LPWSTR pszDest, size_t cchDest, STRSAFE_LPCWSTR pszSrc)
Definition: strsafe.h:149
STRSAFEAPI StringCchCopyA(STRSAFE_LPSTR pszDest, size_t cchDest, STRSAFE_LPCSTR pszSrc)
Definition: strsafe.h:145
#define HIWORD(l)
Definition: typedefs.h:247

◆ GetDynamicEntry()

PDynamicShellEntry CDefaultContextMenu::GetDynamicEntry ( UINT  idCmd)
private

Definition at line 1088 of file CDefaultContextMenu.cpp.

1089{
1090 POSITION it = m_DynamicEntries.GetHeadPosition();
1091 while (it != NULL)
1092 {
1094
1095 if (idCmd >= info.iIdCmdFirst + info.NumIds)
1096 continue;
1097
1098 if (idCmd < info.iIdCmdFirst || idCmd > info.iIdCmdFirst + info.NumIds)
1099 return NULL;
1100
1101 return &info;
1102 }
1103
1104 return NULL;
1105}

Referenced by GetCommandString(), HandleMenuMsg2(), and InvokeShellExt().

◆ GetSite()

HRESULT WINAPI CDefaultContextMenu::GetSite ( REFIID  riid,
void **  ppvSite 
)
override

Definition at line 1643 of file CDefaultContextMenu.cpp.

1644{
1645 if (!m_site)
1646 return E_FAIL;
1647
1648 return m_site->QueryInterface(riid, ppvSite);
1649}
REFIID riid
Definition: atlbase.h:39

◆ HandleMenuMsg()

HRESULT WINAPI CDefaultContextMenu::HandleMenuMsg ( UINT  uMsg,
WPARAM  wParam,
LPARAM  lParam 
)
override

Implements IContextMenu2.

Definition at line 1550 of file CDefaultContextMenu.cpp.

1554{
1555 /* FIXME: Should we implement this as well? */
1556 return S_OK;
1557}

◆ HandleMenuMsg2()

HRESULT WINAPI CDefaultContextMenu::HandleMenuMsg2 ( UINT  uMsg,
WPARAM  wParam,
LPARAM  lParam,
LRESULT plResult 
)
override

Implements IContextMenu3.

Definition at line 1597 of file CDefaultContextMenu.cpp.

1602{
1603 if (uMsg == WM_INITMENUPOPUP)
1604 {
1605 POSITION it = m_DynamicEntries.GetHeadPosition();
1606 while (it != NULL)
1607 {
1609 SHForwardContextMenuMsg(info.pCM, uMsg, wParam, lParam, plResult, TRUE);
1610 }
1611 return S_OK;
1612 }
1613
1614 UINT CmdId;
1615 HRESULT hr = SHGetMenuIdFromMenuMsg(uMsg, lParam, &CmdId);
1616 if (FAILED(hr))
1617 return S_FALSE;
1618
1619 if (CmdId < m_iIdSHEFirst || CmdId >= m_iIdSHELast)
1620 return S_FALSE;
1621
1622 CmdId -= m_iIdSHEFirst;
1624 if (pEntry)
1625 {
1626 SHSetMenuIdInMenuMsg(uMsg, lParam, CmdId - pEntry->iIdCmdFirst);
1627 SHForwardContextMenuMsg(pEntry->pCM, uMsg, wParam, lParam, plResult, TRUE);
1628 }
1629
1630 return S_OK;
1631}
HRESULT SHSetMenuIdInMenuMsg(UINT uMsg, LPARAM lParam, UINT CmdId)
HRESULT SHGetMenuIdFromMenuMsg(UINT uMsg, LPARAM lParam, UINT *CmdId)
HRESULT WINAPI SHForwardContextMenuMsg(IUnknown *pUnk, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *pResult, BOOL useIContextMenu2)
Definition: rosordinal.c:11
#define WM_INITMENUPOPUP
Definition: winuser.h:1746

◆ Initialize()

HRESULT WINAPI CDefaultContextMenu::Initialize ( const DEFCONTEXTMENU pdcm,
LPFNDFMCALLBACK  lpfn 
)

Definition at line 212 of file CDefaultContextMenu.cpp.

213{
214 TRACE("cidl %u\n", pdcm->cidl);
215
216 if (!pdcm->pcmcb && !lpfn)
217 {
218 ERR("CDefaultContextMenu needs a callback!\n");
219 return E_INVALIDARG;
220 }
221
222 m_cidl = pdcm->cidl;
224 if (m_cidl && !m_apidl)
225 return E_OUTOFMEMORY;
226 m_psf = pdcm->psf;
227 m_pmcb = pdcm->pcmcb;
228 m_pfnmcb = lpfn;
229 m_hwnd = pdcm->hwnd;
230
231 m_cKeys = pdcm->cKeys;
232 if (pdcm->cKeys)
233 {
234 m_aKeys = (HKEY*)HeapAlloc(GetProcessHeap(), 0, sizeof(HKEY) * pdcm->cKeys);
235 if (!m_aKeys)
236 return E_OUTOFMEMORY;
237 memcpy(m_aKeys, pdcm->aKeys, sizeof(HKEY) * pdcm->cKeys);
238 }
239
240 m_psf->GetUIObjectOf(pdcm->hwnd, m_cidl, m_apidl, IID_NULL_PPV_ARG(IDataObject, &m_pDataObj));
241
242 if (pdcm->pidlFolder)
243 {
245 }
246 else
247 {
249 if (SUCCEEDED(m_psf->QueryInterface(IID_PPV_ARG(IPersistFolder2, &pf))))
250 {
251 if (FAILED(pf->GetCurFolder(&m_pidlFolder)))
252 ERR("GetCurFolder failed\n");
253 }
254 TRACE("pidlFolder %p\n", m_pidlFolder);
255 }
256
257 return S_OK;
258}
HANDLE HKEY
Definition: registry.h:26
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
#define HeapAlloc
Definition: compat.h:733
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
PITEMID_CHILD * _ILCopyaPidl(PCUITEMID_CHILD_ARRAY apidlsrc, UINT cidl)
Definition: pidl.c:2707
LPITEMIDLIST WINAPI ILClone(LPCITEMIDLIST pidl)
Definition: pidl.c:237
const PCUITEMID_CHILD * PCUITEMID_CHILD_ARRAY
Definition: shtypes.idl:71
IContextMenuCB * pcmcb
Definition: shlobj.h:2535
IShellFolder * psf
Definition: shlobj.h:2537
PCUITEMID_CHILD_ARRAY apidl
Definition: shlobj.h:2539
const HKEY * aKeys
Definition: shlobj.h:2542
PCIDLIST_ABSOLUTE pidlFolder
Definition: shlobj.h:2536

◆ InvokeCommand()

HRESULT WINAPI CDefaultContextMenu::InvokeCommand ( LPCMINVOKECOMMANDINFO  lpcmi)
override

Implements IContextMenu.

Definition at line 1347 of file CDefaultContextMenu.cpp.

1349{
1350 CMINVOKECOMMANDINFOEX LocalInvokeInfo = {};
1352 UINT CmdId;
1353
1354 /* Take a local copy of the fixed members of the
1355 struct as we might need to modify the verb */
1356 memcpy(&LocalInvokeInfo, lpcmi, min(sizeof(LocalInvokeInfo), lpcmi->cbSize));
1357
1358 /* Check if this is a string verb */
1359 if (!IS_INTRESOURCE(LocalInvokeInfo.lpVerb))
1360 {
1361 /* Get the ID which corresponds to this verb, and update our local copy */
1362 if (MapVerbToCmdId((LPVOID)LocalInvokeInfo.lpVerb, &CmdId, FALSE))
1363 LocalInvokeInfo.lpVerb = MAKEINTRESOURCEA(CmdId);
1364 }
1365
1366 CmdId = LOWORD(LocalInvokeInfo.lpVerb);
1367
1368 if (!m_DynamicEntries.IsEmpty() && CmdId >= m_iIdSHEFirst && CmdId < m_iIdSHELast)
1369 {
1370 LocalInvokeInfo.lpVerb -= m_iIdSHEFirst;
1371 Result = InvokeShellExt(&LocalInvokeInfo);
1372 return Result;
1373 }
1374
1375 if (!m_StaticEntries.IsEmpty() && CmdId >= m_iIdSCMFirst && CmdId < m_iIdSCMLast)
1376 {
1377 LocalInvokeInfo.lpVerb -= m_iIdSCMFirst;
1378 Result = InvokeRegVerb(&LocalInvokeInfo);
1379 // TODO: if (FAILED(Result) && !(lpcmi->fMask & CMIC_MASK_FLAG_NO_UI)) SHELL_ErrorBox(m_pSite, Result);
1380 return Result;
1381 }
1382
1383 if (m_iIdCBFirst != m_iIdCBLast && CmdId >= m_iIdCBFirst && CmdId < m_iIdCBLast)
1384 {
1386 return Result;
1387 }
1388
1389 if (m_iIdDfltFirst != m_iIdDfltLast && CmdId >= m_iIdDfltFirst && CmdId < m_iIdDfltLast)
1390 {
1391 CmdId -= m_iIdDfltFirst;
1392 /* See the definitions of IDM_CUT and co to see how this works */
1393 CmdId += DCM_FCIDM_SHVIEW_OFFSET;
1394 }
1395
1396 if (LocalInvokeInfo.cbSize >= sizeof(CMINVOKECOMMANDINFOEX) && (LocalInvokeInfo.fMask & CMIC_MASK_PTINVOKE))
1397 {
1398 if (m_pDataObj && FAILED_UNEXPECTEDLY(DataObject_SetOffset(m_pDataObj, &LocalInvokeInfo.ptInvoke)))
1399 {
1400 ERR("Unable to add OFFSET to DataObject!\n");
1401 }
1402 }
1403
1404 /* Check if this is a Id */
1405 switch (CmdId)
1406 {
1408 Result = DoPaste(&LocalInvokeInfo, FALSE);
1409 break;
1411 Result = DoPaste(&LocalInvokeInfo, TRUE);
1412 break;
1413 case FCIDM_SHVIEW_OPEN:
1415 Result = DoOpenOrExplore(&LocalInvokeInfo);
1416 break;
1417 case FCIDM_SHVIEW_COPY:
1418 case FCIDM_SHVIEW_CUT:
1419 Result = DoCopyOrCut(&LocalInvokeInfo, CmdId == FCIDM_SHVIEW_COPY);
1420 break;
1422 Result = DoCreateLink(&LocalInvokeInfo);
1423 break;
1425 Result = DoDelete(&LocalInvokeInfo);
1426 break;
1428 Result = DoRename(&LocalInvokeInfo);
1429 break;
1431 Result = DoProperties(&LocalInvokeInfo);
1432 break;
1434 Result = DoCreateNewFolder(&LocalInvokeInfo);
1435 break;
1437 Result = DoCopyToMoveToFolder(&LocalInvokeInfo, TRUE);
1438 break;
1440 Result = DoCopyToMoveToFolder(&LocalInvokeInfo, FALSE);
1441 break;
1442 case FCIDM_SHVIEW_UNDO:
1443 Result = DoUndo(&LocalInvokeInfo);
1444 break;
1445 default:
1447 ERR("Unhandled Verb %xl\n", LOWORD(LocalInvokeInfo.lpVerb));
1448 break;
1449 }
1450
1451 return Result;
1452}
HRESULT InvokeRegVerb(LPCMINVOKECOMMANDINFOEX lpcmi)
HRESULT DoRename(LPCMINVOKECOMMANDINFOEX lpcmi)
BOOL MapVerbToCmdId(PVOID Verb, PUINT idCmd, BOOL IsUnicode)
HRESULT DoCreateLink(LPCMINVOKECOMMANDINFOEX lpcmi)
HRESULT DoUndo(LPCMINVOKECOMMANDINFOEX lpcmi)
HRESULT DoCopyOrCut(LPCMINVOKECOMMANDINFOEX lpcmi, BOOL bCopy)
HRESULT DoDelete(LPCMINVOKECOMMANDINFOEX lpcmi)
HRESULT DoCopyToMoveToFolder(LPCMINVOKECOMMANDINFOEX lpici, BOOL bCopy)
HRESULT DoProperties(LPCMINVOKECOMMANDINFOEX lpcmi)
HRESULT DoCreateNewFolder(LPCMINVOKECOMMANDINFOEX lpici)
HRESULT DoPaste(LPCMINVOKECOMMANDINFOEX lpcmi, BOOL bLink)
HRESULT DoOpenOrExplore(LPCMINVOKECOMMANDINFOEX lpcmi)
HRESULT InvokeShellExt(LPCMINVOKECOMMANDINFOEX lpcmi)
struct IContextMenu::tagCMInvokeCommandInfoEx CMINVOKECOMMANDINFOEX
#define min(a, b)
Definition: monoChain.cc:55
#define FCIDM_SHVIEW_CUT
Definition: shresdef.h:826
#define FCIDM_SHVIEW_OPEN
Definition: shresdef.h:853
#define FCIDM_SHVIEW_UNDO
Definition: shresdef.h:829
#define FCIDM_SHVIEW_COPY
Definition: shresdef.h:827
#define FCIDM_SHVIEW_INSERTLINK
Definition: shresdef.h:830
#define FCIDM_SHVIEW_NEWFOLDER
Definition: shresdef.h:849
#define FCIDM_SHVIEW_EXPLORE
Definition: shresdef.h:852
#define FCIDM_SHVIEW_PROPERTIES
Definition: shresdef.h:825
#define FCIDM_SHVIEW_COPYTO
Definition: shresdef.h:831
#define FCIDM_SHVIEW_MOVETO
Definition: shresdef.h:832
#define FCIDM_SHVIEW_DELETE
Definition: shresdef.h:824
#define FCIDM_SHVIEW_RENAME
Definition: shresdef.h:846
#define FCIDM_SHVIEW_CREATELINK
Definition: shresdef.h:847
#define FCIDM_SHVIEW_INSERT
Definition: shresdef.h:828
#define IS_INTRESOURCE(i)
Definition: winuser.h:580
#define MAKEINTRESOURCEA(i)
Definition: winuser.h:581
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:409

◆ InvokePidl()

HRESULT CDefaultContextMenu::InvokePidl ( LPCMINVOKECOMMANDINFOEX  lpcmi,
LPCITEMIDLIST  pidl,
PStaticShellEntry  pEntry 
)
private

Definition at line 1221 of file CDefaultContextMenu.cpp.

1222{
1223 LPITEMIDLIST pidlFull = ILCombine(m_pidlFolder, pidl);
1224 if (pidlFull == NULL)
1225 {
1226 return E_FAIL;
1227 }
1228
1229 WCHAR wszPath[MAX_PATH];
1230 BOOL bHasPath = SHGetPathFromIDListW(pidlFull, wszPath);
1231
1232 WCHAR wszDir[MAX_PATH];
1233 if (bHasPath)
1234 {
1235 wcscpy(wszDir, wszPath);
1236 PathRemoveFileSpec(wszDir);
1237 }
1238 else
1239 {
1240 if (!SHGetPathFromIDListW(m_pidlFolder, wszDir))
1241 *wszDir = UNICODE_NULL;
1242 }
1243
1245 ZeroMemory(&sei, sizeof(sei));
1246 sei.cbSize = sizeof(sei);
1247 sei.hwnd = lpcmi->hwnd;
1248 sei.nShow = SW_SHOWNORMAL;
1249 sei.lpVerb = pEntry->Verb;
1250 sei.lpDirectory = wszDir;
1251 sei.lpIDList = pidlFull;
1252 sei.hkeyClass = pEntry->hkClass;
1254 if (bHasPath)
1255 {
1256 sei.lpFile = wszPath;
1257 }
1258
1259 ShellExecuteExW(&sei);
1260
1261 ILFree(pidlFull);
1262
1263 return S_OK;
1264}
#define UNICODE_NULL
void WINAPI ILFree(LPITEMIDLIST pidl)
Definition: pidl.c:938
LPITEMIDLIST WINAPI ILCombine(LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2)
Definition: pidl.c:712
_CRTIMP wchar_t *__cdecl wcscpy(_Out_writes_z_(_String_length_(_Source)+1) wchar_t *_Dest, _In_z_ const wchar_t *_Source)
#define SEE_MASK_CLASSKEY
Definition: shellapi.h:26
#define SEE_MASK_IDLIST
Definition: shellapi.h:27
BOOL WINAPI DECLSPEC_HOTPATCH ShellExecuteExW(LPSHELLEXECUTEINFOW sei)
Definition: shlexec.cpp:2391
#define PathRemoveFileSpec
Definition: shlwapi.h:1035
LPCWSTR lpDirectory
Definition: shellapi.h:334
#define ZeroMemory
Definition: winbase.h:1712
#define SW_SHOWNORMAL
Definition: winuser.h:770

Referenced by InvokeRegVerb().

◆ InvokeRegVerb()

HRESULT CDefaultContextMenu::InvokeRegVerb ( LPCMINVOKECOMMANDINFOEX  lpcmi)
private

Definition at line 1267 of file CDefaultContextMenu.cpp.

1269{
1270 INT iCmd = LOWORD(lpcmi->lpVerb);
1271 HRESULT hr;
1272 UINT i;
1273
1274 POSITION it = m_StaticEntries.FindIndex(iCmd);
1275
1276 if (it == NULL)
1277 return E_INVALIDARG;
1278
1280
1281 CRegKey VerbKey;
1282 WCHAR VerbKeyPath[sizeof("shell\\") + MAX_VERB];
1283 hr = StringCbPrintfW(VerbKeyPath, sizeof(VerbKeyPath), L"shell\\%s", pEntry->Verb.GetString());
1284 if (SUCCEEDED(hr) && m_pDataObj &&
1285 VerbKey.Open(pEntry->hkClass, VerbKeyPath, KEY_READ) == ERROR_SUCCESS)
1286 {
1287 CLSID clsid;
1288
1289 DWORD KeyState = 0;
1290 if (lpcmi->fMask & CMIC_MASK_SHIFT_DOWN)
1291 KeyState |= MK_SHIFT;
1292 if (lpcmi->fMask & CMIC_MASK_CONTROL_DOWN)
1293 KeyState |= MK_CONTROL;
1294
1295 POINTL *pPtl = NULL;
1296 C_ASSERT(sizeof(POINT) == sizeof(POINTL));
1297 if (lpcmi->fMask & CMIC_MASK_PTINVOKE)
1298 pPtl = (POINTL*)&lpcmi->ptInvoke;
1299
1300 // TODO: IExecuteCommand
1301
1303 hr = SHELL_GetRegCLSID(VerbKey, L"DropTarget", L"CLSID", clsid);
1304 if (SUCCEEDED(hr))
1305 hr = CoCreateInstance(clsid, NULL, CLSCTX_ALL, IID_PPV_ARG(IDropTarget, &pDT));
1306 if (SUCCEEDED(hr))
1307 {
1308 IUnknown_SetSite(pDT, static_cast<IContextMenu*>(this));
1309 hr = SHSimulateDrop(pDT, m_pDataObj, KeyState, pPtl, NULL);
1310 IUnknown_SetSite(pDT, NULL);
1311 return hr;
1312 }
1313 }
1314
1315 /* Get the browse flags to see if we need to browse */
1317
1318 for (i=0; i < m_cidl; i++)
1319 {
1320 /* Check if we need to browse */
1321 if (wFlags)
1322 {
1323 hr = TryToBrowse(lpcmi, m_apidl[i], wFlags);
1324 if (SUCCEEDED(hr))
1325 {
1326 /* In WinXP if we have browsed, we don't open any more folders.
1327 * In Win7 we browse to the first folder we find and
1328 * open new windows for each of the rest of the folders */
1330 if (ntver >= _WIN32_WINNT_VISTA)
1331 wFlags = 0; // FIXME: = SBSP_NEWBROWSER | (wFlags & ~SBSP_SAMEBROWSER);
1332 else
1333 i = m_cidl;
1334
1335 continue;
1336 }
1337 }
1338
1339 InvokePidl(lpcmi, m_apidl[i], pEntry);
1340 }
1341
1342 return S_OK;
1343}
static HRESULT SHELL_GetRegCLSID(HKEY hKey, LPCWSTR SubKey, LPCWSTR Value, CLSID &clsid)
LONG Open(HKEY hKeyParent, LPCTSTR lpszKeyName, REGSAM samDesired=KEY_READ|KEY_WRITE) noexcept
Definition: atlbase.h:1173
DWORD BrowserFlagsFromVerb(LPCMINVOKECOMMANDINFOEX lpcmi, PStaticShellEntry pEntry)
HRESULT TryToBrowse(LPCMINVOKECOMMANDINFOEX lpcmi, LPCITEMIDLIST pidl, DWORD wFlags)
HRESULT InvokePidl(LPCMINVOKECOMMANDINFOEX lpcmi, LPCITEMIDLIST pidl, PStaticShellEntry pEntry)
HRESULT WINAPI DECLSPEC_HOTPATCH CoCreateInstance(REFCLSID rclsid, LPUNKNOWN pUnkOuter, DWORD dwClsContext, REFIID iid, LPVOID *ppv)
Definition: compobj.c:3325
HRESULT WINAPI IUnknown_SetSite(IUnknown *obj, IUnknown *site)
Definition: ordinal.c:1407
#define C_ASSERT(e)
Definition: intsafe.h:73
int32_t INT
Definition: typedefs.h:58

Referenced by InvokeCommand().

◆ InvokeShellExt()

HRESULT CDefaultContextMenu::InvokeShellExt ( LPCMINVOKECOMMANDINFOEX  lpcmi)
private

Definition at line 1141 of file CDefaultContextMenu.cpp.

1143{
1144 TRACE("verb %p first %x last %x\n", lpcmi->lpVerb, m_iIdSHEFirst, m_iIdSHELast);
1145
1146 UINT idCmd = LOWORD(lpcmi->lpVerb);
1148 if (!pEntry)
1149 return E_FAIL;
1150
1151 /* invoke the dynamic context menu */
1152 lpcmi->lpVerb = MAKEINTRESOURCEA(idCmd - pEntry->iIdCmdFirst);
1153 return pEntry->pCM->InvokeCommand((LPCMINVOKECOMMANDINFO)lpcmi);
1154}

Referenced by InvokeCommand().

◆ IsShellExtensionAlreadyLoaded()

BOOL CDefaultContextMenu::IsShellExtensionAlreadyLoaded ( REFCLSID  clsid)
private

Definition at line 344 of file CDefaultContextMenu.cpp.

345{
346 POSITION it = m_DynamicEntries.GetHeadPosition();
347 while (it != NULL)
348 {
349 const DynamicShellEntry& info = m_DynamicEntries.GetNext(it);
350 if (info.ClassID == clsid)
351 return TRUE;
352 }
353
354 return FALSE;
355}

Referenced by LoadDynamicContextMenuHandler().

◆ LoadDynamicContextMenuHandler()

HRESULT CDefaultContextMenu::LoadDynamicContextMenuHandler ( HKEY  hKey,
REFCLSID  clsid 
)
private

Definition at line 358 of file CDefaultContextMenu.cpp.

359{
360 HRESULT hr;
361 TRACE("LoadDynamicContextMenuHandler entered with This %p hKey %p pclsid %s\n", this, hKey, wine_dbgstr_guid(&clsid));
362
364 return S_OK;
365
368 if (FAILED(hr))
369 {
370 ERR("SHCoCreateInstance(IContextMenu) failed.clsid %s hr 0x%x\n", wine_dbgstr_guid(&clsid), hr);
371 return hr;
372 }
373
374 CComPtr<IShellExtInit> pExtInit;
375 hr = pcm->QueryInterface(IID_PPV_ARG(IShellExtInit, &pExtInit));
376 if (FAILED(hr))
377 {
378 ERR("IContextMenu->QueryInterface(IShellExtInit) failed.clsid %s hr 0x%x\n", wine_dbgstr_guid(&clsid), hr);
379 return hr;
380 }
381
382 hr = pExtInit->Initialize(m_pidlFolder, m_pDataObj, hKey);
383 if (FAILED(hr))
384 {
385 WARN("IShellExtInit::Initialize failed.clsid %s hr 0x%x\n", wine_dbgstr_guid(&clsid), hr);
386 return hr;
387 }
388
389 if (m_site)
391
392 m_DynamicEntries.AddTail({ 0, 0, clsid, pcm });
393
394 return S_OK;
395}
BOOL IsShellExtensionAlreadyLoaded(REFCLSID clsid)
static __inline const char * wine_dbgstr_guid(const GUID *id)
Definition: debug.h:197

Referenced by EnumerateDynamicContextHandlerForKey().

◆ MapVerbToCmdId()

BOOL CDefaultContextMenu::MapVerbToCmdId ( PVOID  Verb,
PUINT  idCmd,
BOOL  IsUnicode 
)
private

Definition at line 1108 of file CDefaultContextMenu.cpp.

1109{
1110 WCHAR UnicodeStr[MAX_VERB];
1111
1112 /* Loop through all the static verbs looking for a match */
1113 for (UINT i = 0; i < _countof(g_StaticInvokeCmdMap); i++)
1114 {
1115 /* We can match both ANSI and unicode strings */
1116 if (IsUnicode)
1117 {
1118 /* The static verbs are ANSI, get a unicode version before doing the compare */
1119 SHAnsiToUnicode(g_StaticInvokeCmdMap[i].szStringVerb, UnicodeStr, MAX_VERB);
1120 if (!wcscmp(UnicodeStr, (LPWSTR)Verb))
1121 {
1122 /* Return the Corresponding Id */
1123 *idCmd = g_StaticInvokeCmdMap[i].IntVerb;
1124 return TRUE;
1125 }
1126 }
1127 else
1128 {
1129 if (!strcmp(g_StaticInvokeCmdMap[i].szStringVerb, (LPSTR)Verb))
1130 {
1131 *idCmd = g_StaticInvokeCmdMap[i].IntVerb;
1132 return TRUE;
1133 }
1134 }
1135 }
1136
1137 return FALSE;
1138}
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
_Check_return_ _CRTIMP int __cdecl wcscmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
char * LPSTR
Definition: xmlstorage.h:182

Referenced by InvokeCommand().

◆ QueryContextMenu()

HRESULT WINAPI CDefaultContextMenu::QueryContextMenu ( HMENU  hMenu,
UINT  indexMenu,
UINT  idCmdFirst,
UINT  idCmdLast,
UINT  uFlags 
)
override

Implements IContextMenu.

Definition at line 739 of file CDefaultContextMenu.cpp.

745{
746 HRESULT hr;
747 UINT idCmdNext = idCmdFirst;
748 UINT cIds = 0;
749
750 TRACE("BuildShellItemContextMenu entered\n");
751
752 /* Load static verbs and shell extensions from registry */
753 for (UINT i = 0; i < m_cKeys && !(uFlags & CMF_NOVERBS); i++)
754 {
757 }
758
759 /* Add static context menu handlers */
760 cIds = AddStaticContextMenusToMenu(hMenu, &IndexMenu, idCmdFirst, idCmdLast, uFlags);
761 m_iIdSCMFirst = 0; // FIXME: This should be = idCmdFirst?
762 m_iIdSCMLast = cIds;
763 idCmdNext = idCmdFirst + cIds;
764
765 /* Add dynamic context menu handlers */
766 cIds += AddShellExtensionsToMenu(hMenu, &IndexMenu, idCmdNext, idCmdLast, uFlags);
768 m_iIdSHELast = cIds;
769 idCmdNext = idCmdFirst + cIds;
770 TRACE("SH_LoadContextMenuHandlers first %x last %x\n", m_iIdSHEFirst, m_iIdSHELast);
771
772 /* Now let the callback add its own items */
773 QCMINFO qcminfo = {hMenu, IndexMenu, idCmdNext, idCmdLast, NULL};
775 {
776 UINT added = qcminfo.idCmdFirst - idCmdNext;
777 cIds += added;
778 IndexMenu += added;
780 m_iIdCBLast = cIds;
781 idCmdNext = idCmdFirst + cIds;
782 }
783
784 //TODO: DFM_MERGECONTEXTMENU_BOTTOM
785
786 UINT idDefaultOffset = 0;
787 BOOL isBackgroundMenu = !m_cidl;
788 if (!(uFlags & CMF_VERBSONLY) && !isBackgroundMenu)
789 {
790 /* Get the attributes of the items */
791 SFGAOF rfg = SFGAO_BROWSABLE | SFGAO_CANCOPY | SFGAO_CANLINK | SFGAO_CANMOVE | SFGAO_CANDELETE | SFGAO_CANRENAME | SFGAO_HASPROPSHEET | SFGAO_FILESYSTEM | SFGAO_FOLDER;
792 hr = m_psf->GetAttributesOf(m_cidl, m_apidl, &rfg);
794 return MAKE_HRESULT(SEVERITY_SUCCESS, 0, cIds);
795
796 /* Add the default part of the menu */
797 HMENU hmenuDefault = LoadMenu(_AtlBaseModule.GetResourceInstance(), L"MENU_SHV_FILE");
798
799 /* Remove uneeded entries */
800 if (!(rfg & SFGAO_CANMOVE))
801 DeleteMenu(hmenuDefault, IDM_CUT, MF_BYCOMMAND);
802 if (!(rfg & SFGAO_CANCOPY))
803 DeleteMenu(hmenuDefault, IDM_COPY, MF_BYCOMMAND);
804 if (!((rfg & SFGAO_FILESYSTEM) && HasClipboardData()))
805 DeleteMenu(hmenuDefault, IDM_INSERT, MF_BYCOMMAND);
806 if (!(rfg & SFGAO_CANLINK))
807 DeleteMenu(hmenuDefault, IDM_CREATELINK, MF_BYCOMMAND);
808 if (!(rfg & SFGAO_CANDELETE))
809 DeleteMenu(hmenuDefault, IDM_DELETE, MF_BYCOMMAND);
810 if (!(rfg & SFGAO_CANRENAME))
811 DeleteMenu(hmenuDefault, IDM_RENAME, MF_BYCOMMAND);
812 if (!(rfg & SFGAO_HASPROPSHEET))
813 DeleteMenu(hmenuDefault, IDM_PROPERTIES, MF_BYCOMMAND);
814
815 idDefaultOffset = idCmdNext;
816 UINT idMax = Shell_MergeMenus(hMenu, GetSubMenu(hmenuDefault, 0), IndexMenu, idCmdNext, idCmdLast, 0);
817 m_iIdDfltFirst = cIds;
818 cIds += idMax - idCmdNext;
819 m_iIdDfltLast = cIds;
820
821 DestroyMenu(hmenuDefault);
822 }
823
824 TryPickDefault(hMenu, idCmdFirst, idDefaultOffset, uFlags);
825
826 // TODO: DFM_MERGECONTEXTMENU_TOP
827
828 return MAKE_HRESULT(SEVERITY_SUCCESS, 0, cIds);
829}
static BOOL HasClipboardData()
#define IDM_PROPERTIES
Definition: resources.h:9
UINT AddShellExtensionsToMenu(HMENU hMenu, UINT *pIndexMenu, UINT idCmdFirst, UINT idCmdLast, UINT uFlags)
UINT AddStaticContextMenusToMenu(HMENU hMenu, UINT *IndexMenu, UINT iIdCmdFirst, UINT iIdCmdLast, UINT uFlags)
BOOL EnumerateDynamicContextHandlerForKey(HKEY hRootKey)
void TryPickDefault(HMENU hMenu, UINT idCmdFirst, UINT DfltOffset, UINT uFlags)
void AddStaticEntriesForKey(HKEY hKey, UINT uFlags)
#define DFM_MERGECONTEXTMENU
Definition: precomp.h:44
#define MAKE_HRESULT(sev, fac, code)
Definition: dmerror.h:30
static IShellFolder IShellItem **static IBindCtx LPITEMIDLIST SFGAOF
Definition: ebrowser.c:83
static const CLSID *static CLSID *static const GUID VARIANT VARIANT *static IServiceProvider DWORD *static HMENU
Definition: ordinal.c:63
UINT WINAPI Shell_MergeMenus(HMENU hmDst, HMENU hmSrc, UINT uInsert, UINT uIDAdjust, UINT uIDAdjustMax, ULONG uFlags)
Definition: shlmenu.c:856
#define IDM_DELETE
Definition: shresdef.h:866
#define IDM_INSERT
Definition: shresdef.h:864
#define IDM_RENAME
Definition: shresdef.h:867
#define IDM_COPY
Definition: shresdef.h:863
#define IDM_CUT
Definition: shresdef.h:862
#define IDM_CREATELINK
Definition: shresdef.h:865
UINT idCmdFirst
Definition: shlobj.h:1383
#define SEVERITY_SUCCESS
Definition: winerror.h:64
#define MF_BYCOMMAND
Definition: winuser.h:202
BOOL WINAPI DeleteMenu(_In_ HMENU, _In_ UINT, _In_ UINT)
HMENU WINAPI GetSubMenu(_In_ HMENU, _In_ int)
#define LoadMenu
Definition: winuser.h:5817
BOOL WINAPI DestroyMenu(_In_ HMENU)

◆ QueryService()

virtual HRESULT STDMETHODCALLTYPE CDefaultContextMenu::QueryService ( REFGUID  svc,
REFIID  riid,
void **  ppv 
)
inlinevirtual

Implements IServiceProvider.

Definition at line 161 of file CDefaultContextMenu.cpp.

162 {
163 return IUnknown_QueryService(m_site, svc, riid, ppv);
164 }
REFIID LPVOID * ppv
Definition: atlbase.h:39

◆ SetSite()

HRESULT WINAPI CDefaultContextMenu::SetSite ( IUnknown pUnkSite)
override

Implements IObjectWithSite.

Definition at line 1635 of file CDefaultContextMenu.cpp.

1636{
1637 m_site = pUnkSite;
1638 return S_OK;
1639}

◆ TryPickDefault()

void CDefaultContextMenu::TryPickDefault ( HMENU  hMenu,
UINT  idCmdFirst,
UINT  DfltOffset,
UINT  uFlags 
)
private

Definition at line 702 of file CDefaultContextMenu.cpp.

703{
704 // Are we allowed to pick a default?
706 if (((uFlags & CMF_NODEFAULT) && ntver >= _WIN32_WINNT_VISTA) ||
707 ((uFlags & CMF_DONOTPICKDEFAULT) && ntver >= _WIN32_WINNT_WIN7))
708 {
709 return;
710 }
711
712 // Do we already have a default?
713 if ((int)GetMenuDefaultItem(hMenu, MF_BYPOSITION, 0) != -1)
714 return;
715
716 // Does the view want to pick one?
717 INT_PTR forceDfm = 0;
718 if (_DoCallback(DFM_GETDEFSTATICID, 0, &forceDfm) == S_OK && forceDfm)
719 {
720 for (UINT i = 0; i < _countof(g_StaticInvokeCmdMap); ++i)
721 {
722 UINT menuItemId = g_StaticInvokeCmdMap[i].IntVerb + DfltOffset - DCM_FCIDM_SHVIEW_OFFSET;
723 if (g_StaticInvokeCmdMap[i].DfmCmd == forceDfm &&
724 SetMenuDefaultItem(hMenu, menuItemId, MF_BYCOMMAND))
725 {
726 return;
727 }
728 }
729 }
730
731 // Don't want to pick something like cut or delete as the default but
732 // a static or dynamic verb is a good default.
734 SetMenuDefaultItem(hMenu, idCmdFirst, MF_BYCOMMAND);
735}
#define DFM_GETDEFSTATICID
Definition: precomp.h:47
int32_t INT_PTR
Definition: typedefs.h:64
UINT WINAPI GetMenuDefaultItem(_In_ HMENU hMenu, _In_ UINT fByPos, _In_ UINT gmdiFlags)
BOOL WINAPI SetMenuDefaultItem(_In_ HMENU, _In_ UINT, _In_ UINT)
#define MF_BYPOSITION
Definition: winuser.h:203

Referenced by QueryContextMenu().

◆ TryToBrowse()

HRESULT CDefaultContextMenu::TryToBrowse ( LPCMINVOKECOMMANDINFOEX  lpcmi,
LPCITEMIDLIST  pidl,
DWORD  wFlags 
)
private

Definition at line 1196 of file CDefaultContextMenu.cpp.

1198{
1200 HRESULT hr;
1201
1202 if (!m_site)
1203 return E_FAIL;
1204
1205 /* Get a pointer to the shell browser */
1207 if (FAILED(hr))
1208 return hr;
1209
1210 PIDLIST_ABSOLUTE pidl;
1211 hr = SHILCombine(m_pidlFolder, pidlChild, &pidl);
1213 return hr;
1214
1215 hr = psb->BrowseObject(pidl, wFlags & ~SBSP_RELATIVE);
1216 ILFree(pidl);
1217 return hr;
1218}

Referenced by InvokeRegVerb().

Member Data Documentation

◆ m_aKeys

HKEY* CDefaultContextMenu::m_aKeys
private

Definition at line 97 of file CDefaultContextMenu.cpp.

Referenced by Initialize(), QueryContextMenu(), and ~CDefaultContextMenu().

◆ m_apidl

PCUITEMID_CHILD_ARRAY CDefaultContextMenu::m_apidl
private

◆ m_bGroupPolicyActive

DWORD CDefaultContextMenu::m_bGroupPolicyActive
private

Definition at line 100 of file CDefaultContextMenu.cpp.

Referenced by EnumerateDynamicContextHandlerForKey().

◆ m_cidl

UINT CDefaultContextMenu::m_cidl
private

◆ m_cKeys

UINT CDefaultContextMenu::m_cKeys
private

Definition at line 98 of file CDefaultContextMenu.cpp.

Referenced by Initialize(), QueryContextMenu(), and ~CDefaultContextMenu().

◆ m_DynamicEntries

◆ m_hwnd

HWND CDefaultContextMenu::m_hwnd
private

Definition at line 111 of file CDefaultContextMenu.cpp.

Referenced by _DoCallback(), and Initialize().

◆ m_iIdCBFirst

UINT CDefaultContextMenu::m_iIdCBFirst
private

Definition at line 107 of file CDefaultContextMenu.cpp.

Referenced by InvokeCommand(), and QueryContextMenu().

◆ m_iIdCBLast

UINT CDefaultContextMenu::m_iIdCBLast
private

Definition at line 108 of file CDefaultContextMenu.cpp.

Referenced by InvokeCommand(), and QueryContextMenu().

◆ m_iIdDfltFirst

UINT CDefaultContextMenu::m_iIdDfltFirst
private

Definition at line 109 of file CDefaultContextMenu.cpp.

Referenced by GetCommandString(), InvokeCommand(), and QueryContextMenu().

◆ m_iIdDfltLast

UINT CDefaultContextMenu::m_iIdDfltLast
private

Definition at line 110 of file CDefaultContextMenu.cpp.

Referenced by GetCommandString(), InvokeCommand(), and QueryContextMenu().

◆ m_iIdSCMFirst

UINT CDefaultContextMenu::m_iIdSCMFirst
private

◆ m_iIdSCMLast

UINT CDefaultContextMenu::m_iIdSCMLast
private

◆ m_iIdSHEFirst

UINT CDefaultContextMenu::m_iIdSHEFirst
private

◆ m_iIdSHELast

UINT CDefaultContextMenu::m_iIdSHELast
private

◆ m_pDataObj

◆ m_pfnmcb

LPFNDFMCALLBACK CDefaultContextMenu::m_pfnmcb
private

Definition at line 93 of file CDefaultContextMenu.cpp.

Referenced by _DoCallback(), and Initialize().

◆ m_pidlFolder

◆ m_pmcb

CComPtr<IContextMenuCB> CDefaultContextMenu::m_pmcb
private

Definition at line 92 of file CDefaultContextMenu.cpp.

Referenced by _DoCallback(), and Initialize().

◆ m_psf

CComPtr<IShellFolder> CDefaultContextMenu::m_psf
private

◆ m_site

◆ m_StaticEntries


The documentation for this class was generated from the following file: