ReactOS 0.4.15-dev-8222-g9164419
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 93 of file CDefaultContextMenu.cpp.

Constructor & Destructor Documentation

◆ CDefaultContextMenu()

CDefaultContextMenu::CDefaultContextMenu ( )

Definition at line 185 of file CDefaultContextMenu.cpp.

185 :
186 m_psf(NULL),
187 m_pmcb(NULL),
188 m_pfnmcb(NULL),
189 m_cidl(0),
190 m_apidl(NULL),
192 m_aKeys(NULL),
193 m_cKeys(NULL),
196 m_iIdSHEFirst(0),
197 m_iIdSHELast(0),
198 m_iIdSCMFirst(0),
199 m_iIdSCMLast(0),
200 m_iIdCBFirst(0),
201 m_iIdCBLast(0),
203 m_iIdDfltLast(0),
204 m_hwnd(NULL)
205{
206}
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 208 of file CDefaultContextMenu.cpp.

209{
210 m_DynamicEntries.RemoveAll();
211 m_StaticEntries.RemoveAll();
212
213 for (UINT i = 0; i < m_cKeys; i++)
216
217 if (m_pidlFolder)
219 _ILFreeaPidl(const_cast<PITEMID_CHILD *>(m_apidl), m_cidl);
220}
#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:2687

Member Function Documentation

◆ _DoCallback()

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

Definition at line 270 of file CDefaultContextMenu.cpp.

271{
272 if (m_pmcb)
273 {
274 return m_pmcb->CallBack(m_psf, m_hwnd, m_pDataObj, uMsg, wParam, (LPARAM)lParam);
275 }
276 else if(m_pfnmcb)
277 {
279 }
280
281 return E_FAIL;
282}
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 472 of file CDefaultContextMenu.cpp.

473{
474 UINT cIds = 0;
475
476 if (m_DynamicEntries.IsEmpty())
477 return cIds;
478
479 POSITION it = m_DynamicEntries.GetHeadPosition();
480 while (it != NULL)
481 {
483
484 HRESULT hr = info.pCM->QueryContextMenu(hMenu, *pIndexMenu, idCmdFirst + cIds, idCmdLast, uFlags);
485 if (SUCCEEDED(hr))
486 {
487 info.iIdCmdFirst = cIds;
488 info.NumIds = HRESULT_CODE(hr);
489 (*pIndexMenu) += info.NumIds;
490
491 cIds += info.NumIds;
492 if (idCmdFirst + cIds >= idCmdLast)
493 break;
494 }
495 TRACE("pEntry hr %x contextmenu %p cmdfirst %x num ids %x\n", hr, info.pCM.p, info.iIdCmdFirst, info.NumIds);
496 }
497 return cIds;
498}
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 501 of file CDefaultContextMenu.cpp.

507{
509 MENUITEMINFOW mii = { sizeof(mii) };
510 UINT idResource;
511 WCHAR wszVerb[40];
512 UINT fState;
513 UINT cIds = 0, indexFirst = *pIndexMenu;
514
516 mii.fType = MFT_STRING;
517
518 POSITION it = m_StaticEntries.GetHeadPosition();
519 bool first = true;
520 while (it != NULL)
521 {
523 BOOL forceFirstPos = FALSE;
524
525 fState = MFS_ENABLED;
526
527 /* set first entry as default */
528 if (first)
529 {
530 fState |= MFS_DEFAULT;
531 first = false;
532 }
533
534 if (info.Verb.CompareNoCase(L"open") == 0)
535 {
536 idResource = IDS_OPEN_VERB;
537 fState |= MFS_DEFAULT; /* override default when open verb is found */
538 forceFirstPos++;
539 }
540 else if (info.Verb.CompareNoCase(L"explore") == 0)
541 {
542 idResource = IDS_EXPLORE_VERB;
543 if (uFlags & CMF_EXPLORE)
544 {
545 fState |= MFS_DEFAULT;
546 forceFirstPos++;
547 }
548 }
549 else if (info.Verb.CompareNoCase(L"runas") == 0)
550 idResource = IDS_RUNAS_VERB;
551 else if (info.Verb.CompareNoCase(L"edit") == 0)
552 idResource = IDS_EDIT_VERB;
553 else if (info.Verb.CompareNoCase(L"find") == 0)
554 idResource = IDS_FIND_VERB;
555 else if (info.Verb.CompareNoCase(L"print") == 0)
556 idResource = IDS_PRINT_VERB;
557 else if (info.Verb.CompareNoCase(L"printto") == 0)
558 continue;
559 else
560 idResource = 0;
561
562 /* By default use verb for menu item name */
563 mii.dwTypeData = (LPWSTR)info.Verb.GetString();
564
565 WCHAR wszKey[sizeof("shell\\") + MAX_VERB];
566 HRESULT hr;
567 hr = StringCbPrintfW(wszKey, sizeof(wszKey), L"shell\\%s", info.Verb.GetString());
569 {
570 continue;
571 }
572
573 UINT cmdFlags = 0;
574 bool hide = false;
575 HKEY hkVerb;
576 if (idResource > 0)
577 {
578 if (!(uFlags & CMF_OPTIMIZEFORINVOKE))
579 {
580 if (LoadStringW(shell32_hInstance, idResource, wszVerb, _countof(wszVerb)))
581 mii.dwTypeData = wszVerb; /* use translated verb */
582 else
583 ERR("Failed to load string\n");
584 }
585
586 if (RegOpenKeyW(info.hkClass, wszKey, &hkVerb) != ERROR_SUCCESS)
587 hkVerb = NULL;
588 }
589 else
590 {
591 if (RegOpenKeyW(info.hkClass, wszKey, &hkVerb) == ERROR_SUCCESS)
592 {
593 if (!(uFlags & CMF_OPTIMIZEFORINVOKE))
594 {
595 DWORD cbVerb = sizeof(wszVerb);
596
597 LONG res = RegLoadMUIStringW(hkVerb, L"MUIVerb", wszVerb, cbVerb, NULL, 0, NULL);
598 if (res || !*wszVerb)
599 res = RegLoadMUIStringW(hkVerb, NULL, wszVerb, cbVerb, NULL, 0, NULL);
600
601 if (res == ERROR_SUCCESS && *wszVerb)
602 {
603 /* use description for the menu entry */
604 mii.dwTypeData = wszVerb;
605 }
606 }
607 }
608 else
609 {
610 hkVerb = NULL;
611 }
612 }
613
614 if (hkVerb)
615 {
616 if (!(uFlags & CMF_EXTENDEDVERBS))
617 hide = RegValueExists(hkVerb, L"Extended");
618
619 if (!hide)
620 hide = RegValueExists(hkVerb, L"ProgrammaticAccessOnly");
621
622 if (!hide && !(uFlags & CMF_DISABLEDVERBS))
623 hide = RegValueExists(hkVerb, L"LegacyDisable");
624
625 if (RegValueExists(hkVerb, L"NeverDefault"))
626 fState &= ~MFS_DEFAULT;
627
628 if (RegValueExists(hkVerb, L"SeparatorBefore"))
629 cmdFlags |= ECF_SEPARATORBEFORE;
630 if (RegValueExists(hkVerb, L"SeparatorAfter"))
631 cmdFlags |= ECF_SEPARATORAFTER;
632
633 RegCloseKey(hkVerb);
634 }
635
636 if (((uFlags & CMF_NODEFAULT) && ntver >= _WIN32_WINNT_VISTA) ||
637 ((uFlags & CMF_DONOTPICKDEFAULT) && ntver >= _WIN32_WINNT_WIN7))
638 {
639 fState &= ~MFS_DEFAULT;
640 }
641
642 if (!hide)
643 {
644 if (cmdFlags & ECF_SEPARATORBEFORE)
645 {
646 if (InsertMenuItemAt(hMenu, *pIndexMenu, MF_SEPARATOR))
647 (*pIndexMenu)++;
648 }
649
650 mii.fState = fState;
651 mii.wID = iIdCmdFirst + cIds;
652 if (InsertMenuItemW(hMenu, forceFirstPos ? indexFirst : *pIndexMenu, TRUE, &mii))
653 (*pIndexMenu)++;
654
655 if (cmdFlags & ECF_SEPARATORAFTER)
656 {
657 if (InsertMenuItemAt(hMenu, *pIndexMenu, MF_SEPARATOR))
658 (*pIndexMenu)++;
659 }
660 }
661 cIds++; // Always increment the id because it acts as the index into m_StaticEntries
662
663 if (mii.wID >= iIdCmdLast)
664 break;
665 }
666
667 return cIds;
668}
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:113
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:215
#define IDS_FIND_VERB
Definition: shresdef.h:219
#define IDS_EXPLORE_VERB
Definition: shresdef.h:216
#define IDS_PRINT_VERB
Definition: shresdef.h:220
#define IDS_RUNAS_VERB
Definition: shresdef.h:217
#define IDS_EDIT_VERB
Definition: shresdef.h:218
#define _countof(array)
Definition: sndvol32.h:70
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 MFT_STRING
Definition: winuser.h:746
#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 310 of file CDefaultContextMenu.cpp.

311{
312 WCHAR wszName[40];
313 DWORD cchName, dwIndex = 0;
314 HKEY hShellKey;
315
316 LRESULT lres = RegOpenKeyExW(hKey, L"shell", 0, KEY_READ, &hShellKey);
317 if (lres != STATUS_SUCCESS)
318 return;
319
320 while(TRUE)
321 {
322 cchName = _countof(wszName);
323 if (RegEnumKeyExW(hShellKey, dwIndex++, wszName, &cchName, NULL, NULL, NULL, NULL) != ERROR_SUCCESS)
324 break;
325
326 AddStaticEntry(hKey, wszName, uFlags);
327 }
328
329 RegCloseKey(hShellKey);
330}
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 284 of file CDefaultContextMenu.cpp.

285{
286 POSITION it = m_StaticEntries.GetHeadPosition();
287 while (it != NULL)
288 {
289 const StaticShellEntry& info = m_StaticEntries.GetNext(it);
290 if (info.Verb.CompareNoCase(szVerb) == 0)
291 {
292 /* entry already exists */
293 return;
294 }
295 }
296
297 TRACE("adding verb %s\n", debugstr_w(szVerb));
298
299 if (!wcsicmp(szVerb, L"open") && !(uFlags & CMF_NODEFAULT))
300 {
301 /* open verb is always inserted in front */
302 m_StaticEntries.AddHead({ szVerb, hkeyClass });
303 }
304 else
305 {
306 m_StaticEntries.AddTail({ szVerb, hkeyClass });
307 }
308}
#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 1164 of file CDefaultContextMenu.cpp.

1165{
1167 HWND hwndTree;
1168 LPCWSTR FlagsName;
1169 WCHAR wszKey[sizeof("shell\\") + MAX_VERB];
1170 HRESULT hr;
1171 DWORD wFlags;
1172 DWORD cbVerb;
1173
1174 if (!m_site)
1175 return 0;
1176
1177 /* Get a pointer to the shell browser */
1179 if (FAILED(hr))
1180 return 0;
1181
1182 /* See if we are in Explore or Browse mode. If the browser's tree is present, we are in Explore mode.*/
1183 if (SUCCEEDED(psb->GetControlWindow(FCW_TREE, &hwndTree)) && hwndTree)
1184 FlagsName = L"ExplorerFlags";
1185 else
1186 FlagsName = L"BrowserFlags";
1187
1188 /* Try to get the flag from the verb */
1189 hr = StringCbPrintfW(wszKey, sizeof(wszKey), L"shell\\%s", pEntry->Verb.GetString());
1191 return 0;
1192
1193 cbVerb = sizeof(wFlags);
1194 if (RegGetValueW(pEntry->hkClass, wszKey, FlagsName, RRF_RT_REG_DWORD, NULL, &wFlags, &cbVerb) == ERROR_SUCCESS)
1195 {
1196 return wFlags;
1197 }
1198
1199 return 0;
1200}
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 928 of file CDefaultContextMenu.cpp.

929{
930 if (!m_cidl || !m_pDataObj)
931 return E_FAIL;
932
933 FORMATETC formatetc;
935 STGMEDIUM medium = {0};
936 medium.tymed = TYMED_HGLOBAL;
937 medium.hGlobal = GlobalAlloc(GHND, sizeof(DWORD));
938 DWORD* pdwFlag = (DWORD*)GlobalLock(medium.hGlobal);
939 if (pdwFlag)
940 *pdwFlag = bCopy ? DROPEFFECT_COPY : DROPEFFECT_MOVE;
941 GlobalUnlock(medium.hGlobal);
942 m_pDataObj->SetData(&formatetc, &medium, TRUE);
943
946 return hr;
947
948 return S_OK;
949}
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:560
#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 1000 of file CDefaultContextMenu.cpp.

1001{
1002 HRESULT hr = E_FAIL;
1003 if (!m_pDataObj)
1004 {
1005 ERR("m_pDataObj is NULL\n");
1006 return hr;
1007 }
1008
1009 CComPtr<IContextMenu> pContextMenu;
1010 if (bCopy)
1011 hr = SHCoCreateInstance(NULL, &CLSID_CopyToMenu, NULL,
1012 IID_PPV_ARG(IContextMenu, &pContextMenu));
1013 else
1014 hr = SHCoCreateInstance(NULL, &CLSID_MoveToMenu, NULL,
1015 IID_PPV_ARG(IContextMenu, &pContextMenu));
1017 return hr;
1018
1020 hr = pContextMenu->QueryInterface(IID_PPV_ARG(IShellExtInit, &pInit));
1022 return hr;
1023
1024 hr = pInit->Initialize(m_pidlFolder, m_pDataObj, NULL);
1026 return hr;
1027
1028 if (bCopy)
1029 lpici->lpVerb = "copyto";
1030 else
1031 lpici->lpVerb = "moveto";
1032
1033 return pContextMenu->InvokeCommand((LPCMINVOKECOMMANDINFO)lpici);
1034}
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 897 of file CDefaultContextMenu.cpp.

898{
899 if (!m_cidl || !m_pDataObj)
900 return E_FAIL;
901
903 HRESULT hr = m_psf->CreateViewObject(NULL, IID_PPV_ARG(IDropTarget, &pDT));
905 return hr;
906
908
909 return S_OK;
910}
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 1038 of file CDefaultContextMenu.cpp.

1040{
1041 WCHAR wszPath[MAX_PATH];
1042 WCHAR wszName[MAX_PATH];
1043 WCHAR wszNewFolder[25];
1044 HRESULT hr;
1045
1046 /* Get folder path */
1049 return hr;
1050
1051 if (!LoadStringW(shell32_hInstance, IDS_NEWFOLDER, wszNewFolder, _countof(wszNewFolder)))
1052 return E_FAIL;
1053
1054 /* Create the name of the new directory */
1055 if (!PathYetAnotherMakeUniqueName(wszName, wszPath, NULL, wszNewFolder))
1056 return E_FAIL;
1057
1058 /* Create the new directory and show the appropriate dialog in case of error */
1059 if (SHCreateDirectory(lpici->hwnd, wszName) != ERROR_SUCCESS)
1060 return E_FAIL;
1061
1062 /* Show and select the new item in the def view */
1063 LPITEMIDLIST pidl;
1064 PITEMID_CHILD pidlNewItem;
1066
1067 /* Notify the view object about the new item */
1069
1070 if (!m_site)
1071 return S_OK;
1072
1073 /* Get a pointer to the shell view */
1076 return S_OK;
1077
1078 /* Attempt to get the pidl of the new item */
1079 hr = SHILCreateFromPathW(wszName, &pidl, NULL);
1081 return hr;
1082
1083 pidlNewItem = ILFindLastID(pidl);
1084
1085 hr = psv->SelectItem(pidlNewItem, SVSI_DESELECTOTHERS | SVSI_EDIT | SVSI_ENSUREVISIBLE |
1086 SVSI_FOCUSED | SVSI_SELECT);
1088 return hr;
1089
1090 SHFree(pidl);
1091
1092 return S_OK;
1093}
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:1342
int WINAPI SHCreateDirectory(HWND hWnd, LPCWSTR path)
Definition: shlfileop.cpp:847
#define SID_IFolderView
#define SHCNE_MKDIR
Definition: shlobj.h:1886
#define SHCNF_FLUSH
Definition: shlobj.h:1921
#define SHCNF_PATHW
Definition: shlobj.h:1918
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 912 of file CDefaultContextMenu.cpp.

913{
914 if (!m_cidl || !m_pDataObj)
915 return E_FAIL;
916
920 return hr;
921
922 DWORD grfKeyState = (lpcmi->fMask & CMIC_MASK_SHIFT_DOWN) ? MK_SHIFT : 0;
923 SHSimulateDrop(pDT, m_pDataObj, grfKeyState, NULL, NULL);
924
925 return S_OK;
926}
HRESULT CRecyclerDropTarget_CreateInstance(REFIID riid, LPVOID *ppvOut)

Referenced by InvokeCommand().

◆ DoOpenOrExplore()

HRESULT CDefaultContextMenu::DoOpenOrExplore ( LPCMINVOKECOMMANDINFOEX  lpcmi)
private

Definition at line 891 of file CDefaultContextMenu.cpp.

892{
894 return E_FAIL;
895}
#define UNIMPLEMENTED
Definition: debug.h:118

Referenced by InvokeCommand().

◆ DoPaste()

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

Definition at line 838 of file CDefaultContextMenu.cpp.

839{
840 HRESULT hr;
841
843 hr = OleGetClipboard(&pda);
845 return hr;
846
847 FORMATETC formatetc2;
848 STGMEDIUM medium2;
850
851 DWORD dwKey= 0;
852
853 if (SUCCEEDED(pda->GetData(&formatetc2, &medium2)))
854 {
855 DWORD * pdwFlag = (DWORD*)GlobalLock(medium2.hGlobal);
856 if (pdwFlag)
857 {
858 if (*pdwFlag == DROPEFFECT_COPY)
859 dwKey = MK_CONTROL;
860 else
861 dwKey = MK_SHIFT;
862 }
863 else
864 {
865 ERR("No drop effect obtained\n");
866 }
867 GlobalUnlock(medium2.hGlobal);
868 }
869
870 if (bLink)
871 {
872 dwKey = MK_CONTROL|MK_SHIFT;
873 }
874
876 if (m_cidl)
877 hr = m_psf->GetUIObjectOf(NULL, 1, &m_apidl[0], IID_NULL_PPV_ARG(IDropTarget, &pdrop));
878 else
879 hr = m_psf->CreateViewObject(NULL, IID_PPV_ARG(IDropTarget, &pdrop));
880
882 return hr;
883
884 SHSimulateDrop(pdrop, pda, dwKey, NULL, NULL);
885
886 TRACE("CP result %x\n", hr);
887 return S_OK;
888}
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 978 of file CDefaultContextMenu.cpp.

980{
982
983 // We are asked to run the default property sheet
984 if (hr == S_FALSE)
985 {
987 }
988
989 return hr;
990}
HRESULT _DoCallback(UINT uMsg, WPARAM wParam, LPVOID lParam)
#define DFM_INVOKECOMMAND
Definition: precomp.h:45
HRESULT SHELL32_ShowPropertiesDialog(IDataObject *pdtobj)
Definition: shlfolder.cpp:497
#define DFM_CMD_PROPERTIES
Definition: shlobj.h:2605
#define S_FALSE
Definition: winerror.h:2357

Referenced by InvokeCommand().

◆ DoRename()

HRESULT CDefaultContextMenu::DoRename ( LPCMINVOKECOMMANDINFOEX  lpcmi)
private

Definition at line 951 of file CDefaultContextMenu.cpp.

952{
954 HRESULT hr;
955
956 if (!m_site || !m_cidl)
957 return E_FAIL;
958
959 /* Get a pointer to the shell browser */
962 return hr;
963
965 hr = psb->QueryActiveShellView(&lpSV);
967 return hr;
968
969 SVSIF selFlags = SVSI_DESELECTOTHERS | SVSI_EDIT | SVSI_ENSUREVISIBLE | SVSI_FOCUSED | SVSI_SELECT;
970 hr = lpSV->SelectItem(m_apidl[0], selFlags);
972 return hr;
973
974 return S_OK;
975}

Referenced by InvokeCommand().

◆ DoUndo()

HRESULT CDefaultContextMenu::DoUndo ( LPCMINVOKECOMMANDINFOEX  lpcmi)
private

Definition at line 993 of file CDefaultContextMenu.cpp.

994{
995 ERR("TODO: Undo\n");
996 return E_NOTIMPL;
997}
#define E_NOTIMPL
Definition: ddrawi.h:99

Referenced by InvokeCommand().

◆ EnumerateDynamicContextHandlerForKey()

BOOL CDefaultContextMenu::EnumerateDynamicContextHandlerForKey ( HKEY  hRootKey)
private

Definition at line 408 of file CDefaultContextMenu.cpp.

409{
410 WCHAR wszName[MAX_PATH], wszBuf[MAX_PATH], *pwszClsid;
412 HRESULT hr;
413 HKEY hKey;
414
415 if (RegOpenKeyExW(hRootKey, L"shellex\\ContextMenuHandlers", 0, KEY_READ, &hKey) != ERROR_SUCCESS)
416 {
417 TRACE("RegOpenKeyExW failed\n");
418 return FALSE;
419 }
420
421 DWORD dwIndex = 0;
422 while (TRUE)
423 {
424 cchName = _countof(wszName);
425 if (RegEnumKeyExW(hKey, dwIndex++, wszName, &cchName, NULL, NULL, NULL, NULL) != ERROR_SUCCESS)
426 break;
427
428 /* Key name or key value is CLSID */
429 CLSID clsid;
430 hr = CLSIDFromString(wszName, &clsid);
431 if (hr == S_OK)
432 pwszClsid = wszName;
433 else
434 {
435 DWORD cchBuf = _countof(wszBuf);
436 if (RegGetValueW(hKey, wszName, NULL, RRF_RT_REG_SZ, NULL, wszBuf, &cchBuf) == ERROR_SUCCESS)
437 hr = CLSIDFromString(wszBuf, &clsid);
438 pwszClsid = wszBuf;
439 }
440
441 if (FAILED(hr))
442 {
443 ERR("CLSIDFromString failed for clsid %S hr 0x%x\n", pwszClsid, hr);
444 continue;
445 }
446
448 {
450 L"Software\\Microsoft\\Windows\\CurrentVersion\\Shell Extensions\\Approved",
451 pwszClsid,
453 NULL,
454 NULL,
456 {
457 ERR("Shell extension %s not approved!\n", pwszClsid);
458 continue;
459 }
460 }
461
463 if (FAILED(hr))
464 WARN("Failed to get context menu entires from shell extension! clsid: %S\n", pwszClsid);
465 }
466
468 return TRUE;
469}
#define WARN(fmt,...)
Definition: debug.h:115
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 1476 of file CDefaultContextMenu.cpp.

1482{
1483 /* We don't handle the help text yet */
1484 if (uFlags == GCS_HELPTEXTA ||
1485 uFlags == GCS_HELPTEXTW ||
1486 HIWORD(idCommand) != 0)
1487 {
1488 return E_NOTIMPL;
1489 }
1490
1491 UINT CmdId = LOWORD(idCommand);
1492
1493 if (!m_DynamicEntries.IsEmpty() && CmdId >= m_iIdSHEFirst && CmdId < m_iIdSHELast)
1494 {
1495 idCommand -= m_iIdSHEFirst;
1497 if (!pEntry)
1498 return E_FAIL;
1499
1500 idCommand -= pEntry->iIdCmdFirst;
1501 return pEntry->pCM->GetCommandString(idCommand,
1502 uFlags,
1503 lpReserved,
1504 lpszName,
1505 uMaxNameLen);
1506 }
1507
1508 if (!m_StaticEntries.IsEmpty() && CmdId >= m_iIdSCMFirst && CmdId < m_iIdSCMLast)
1509 {
1510 /* Validation just returns S_OK on a match. The id exists. */
1511 if (uFlags == GCS_VALIDATEA || uFlags == GCS_VALIDATEW)
1512 return S_OK;
1513
1514 CmdId -= m_iIdSCMFirst;
1515
1516 POSITION it = m_StaticEntries.FindIndex(CmdId);
1517
1518 if (it == NULL)
1519 return E_INVALIDARG;
1520
1522
1523 if (uFlags == GCS_VERBW)
1524 return StringCchCopyW((LPWSTR)lpszName, uMaxNameLen, pEntry->Verb);
1525
1526 if (uFlags == GCS_VERBA)
1527 {
1528 if (SHUnicodeToAnsi(pEntry->Verb, lpszName, uMaxNameLen))
1529 return S_OK;
1530 }
1531
1532 return E_INVALIDARG;
1533 }
1534
1535 //FIXME: Should we handle callbacks here?
1536 if (m_iIdDfltFirst != m_iIdDfltLast && CmdId >= m_iIdDfltFirst && CmdId < m_iIdDfltLast)
1537 {
1538 CmdId -= m_iIdDfltFirst;
1539 /* See the definitions of IDM_CUT and co to see how this works */
1540 CmdId += DCM_FCIDM_SHVIEW_OFFSET;
1541 }
1542
1543 /* Loop looking for a matching Id */
1544 for (UINT i = 0; i < _countof(g_StaticInvokeCmdMap); i++)
1545 {
1546 if (g_StaticInvokeCmdMap[i].IntVerb == CmdId)
1547 {
1548 /* Validation just returns S_OK on a match */
1549 if (uFlags == GCS_VALIDATEA || uFlags == GCS_VALIDATEW)
1550 return S_OK;
1551
1552 /* Return a copy of the ANSI verb */
1553 if (uFlags == GCS_VERBA)
1554 return StringCchCopyA(lpszName, uMaxNameLen, g_StaticInvokeCmdMap[i].szStringVerb);
1555
1556 /* Convert the ANSI verb to unicode and return that */
1557 if (uFlags == GCS_VERBW)
1558 {
1559 if (SHAnsiToUnicode(g_StaticInvokeCmdMap[i].szStringVerb, (LPWSTR)lpszName, uMaxNameLen))
1560 return S_OK;
1561 }
1562 }
1563 }
1564
1565 return E_INVALIDARG;
1566}
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 1095 of file CDefaultContextMenu.cpp.

1096{
1097 POSITION it = m_DynamicEntries.GetHeadPosition();
1098 while (it != NULL)
1099 {
1101
1102 if (idCmd >= info.iIdCmdFirst + info.NumIds)
1103 continue;
1104
1105 if (idCmd < info.iIdCmdFirst || idCmd > info.iIdCmdFirst + info.NumIds)
1106 return NULL;
1107
1108 return &info;
1109 }
1110
1111 return NULL;
1112}

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

◆ GetSite()

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

Definition at line 1663 of file CDefaultContextMenu.cpp.

1664{
1665 if (!m_site)
1666 return E_FAIL;
1667
1668 return m_site->QueryInterface(riid, ppvSite);
1669}
REFIID riid
Definition: atlbase.h:39

◆ HandleMenuMsg()

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

Implements IContextMenu2.

Definition at line 1570 of file CDefaultContextMenu.cpp.

1574{
1575 /* FIXME: Should we implement this as well? */
1576 return S_OK;
1577}

◆ HandleMenuMsg2()

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

Implements IContextMenu3.

Definition at line 1617 of file CDefaultContextMenu.cpp.

1622{
1623 if (uMsg == WM_INITMENUPOPUP)
1624 {
1625 POSITION it = m_DynamicEntries.GetHeadPosition();
1626 while (it != NULL)
1627 {
1629 SHForwardContextMenuMsg(info.pCM, uMsg, wParam, lParam, plResult, TRUE);
1630 }
1631 return S_OK;
1632 }
1633
1634 UINT CmdId;
1635 HRESULT hr = SHGetMenuIdFromMenuMsg(uMsg, lParam, &CmdId);
1636 if (FAILED(hr))
1637 return S_FALSE;
1638
1639 if (CmdId < m_iIdSHEFirst || CmdId >= m_iIdSHELast)
1640 return S_FALSE;
1641
1642 CmdId -= m_iIdSHEFirst;
1644 if (pEntry)
1645 {
1646 SHSetMenuIdInMenuMsg(uMsg, lParam, CmdId - pEntry->iIdCmdFirst);
1647 SHForwardContextMenuMsg(pEntry->pCM, uMsg, wParam, lParam, plResult, TRUE);
1648 }
1649
1650 return S_OK;
1651}
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 222 of file CDefaultContextMenu.cpp.

223{
224 TRACE("cidl %u\n", pdcm->cidl);
225
226 if (!pdcm->pcmcb && !lpfn)
227 {
228 ERR("CDefaultContextMenu needs a callback!\n");
229 return E_INVALIDARG;
230 }
231
232 m_cidl = pdcm->cidl;
234 if (m_cidl && !m_apidl)
235 return E_OUTOFMEMORY;
236 m_psf = pdcm->psf;
237 m_pmcb = pdcm->pcmcb;
238 m_pfnmcb = lpfn;
239 m_hwnd = pdcm->hwnd;
240
241 m_cKeys = pdcm->cKeys;
242 if (pdcm->cKeys)
243 {
244 m_aKeys = (HKEY*)HeapAlloc(GetProcessHeap(), 0, sizeof(HKEY) * pdcm->cKeys);
245 if (!m_aKeys)
246 return E_OUTOFMEMORY;
247 memcpy(m_aKeys, pdcm->aKeys, sizeof(HKEY) * pdcm->cKeys);
248 }
249
250 m_psf->GetUIObjectOf(pdcm->hwnd, m_cidl, m_apidl, IID_NULL_PPV_ARG(IDataObject, &m_pDataObj));
251
252 if (pdcm->pidlFolder)
253 {
255 }
256 else
257 {
259 if (SUCCEEDED(m_psf->QueryInterface(IID_PPV_ARG(IPersistFolder2, &pf))))
260 {
261 if (FAILED(pf->GetCurFolder(&m_pidlFolder)))
262 ERR("GetCurFolder failed\n");
263 }
264 TRACE("pidlFolder %p\n", m_pidlFolder);
265 }
266
267 return S_OK;
268}
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:2704
LPITEMIDLIST WINAPI ILClone(LPCITEMIDLIST pidl)
Definition: pidl.c:237
const PCUITEMID_CHILD * PCUITEMID_CHILD_ARRAY
Definition: shtypes.idl:71
IContextMenuCB * pcmcb
Definition: shlobj.h:2543
IShellFolder * psf
Definition: shlobj.h:2545
PCUITEMID_CHILD_ARRAY apidl
Definition: shlobj.h:2547
const HKEY * aKeys
Definition: shlobj.h:2550
PCIDLIST_ABSOLUTE pidlFolder
Definition: shlobj.h:2544

◆ InvokeCommand()

HRESULT WINAPI CDefaultContextMenu::InvokeCommand ( LPCMINVOKECOMMANDINFO  lpcmi)
override

Implements IContextMenu.

Definition at line 1367 of file CDefaultContextMenu.cpp.

1369{
1370 CMINVOKECOMMANDINFOEX LocalInvokeInfo = {};
1372 UINT CmdId;
1373
1374 /* Take a local copy of the fixed members of the
1375 struct as we might need to modify the verb */
1376 memcpy(&LocalInvokeInfo, lpcmi, min(sizeof(LocalInvokeInfo), lpcmi->cbSize));
1377
1378 /* Check if this is a string verb */
1379 if (!IS_INTRESOURCE(LocalInvokeInfo.lpVerb))
1380 {
1381 /* Get the ID which corresponds to this verb, and update our local copy */
1382 if (MapVerbToCmdId((LPVOID)LocalInvokeInfo.lpVerb, &CmdId, FALSE))
1383 LocalInvokeInfo.lpVerb = MAKEINTRESOURCEA(CmdId);
1384 }
1385
1386 CmdId = LOWORD(LocalInvokeInfo.lpVerb);
1387
1388 if (!m_DynamicEntries.IsEmpty() && CmdId >= m_iIdSHEFirst && CmdId < m_iIdSHELast)
1389 {
1390 LocalInvokeInfo.lpVerb -= m_iIdSHEFirst;
1391 Result = InvokeShellExt(&LocalInvokeInfo);
1392 return Result;
1393 }
1394
1395 if (!m_StaticEntries.IsEmpty() && CmdId >= m_iIdSCMFirst && CmdId < m_iIdSCMLast)
1396 {
1397 LocalInvokeInfo.lpVerb -= m_iIdSCMFirst;
1398 Result = InvokeRegVerb(&LocalInvokeInfo);
1399 // TODO: if (FAILED(Result) && !(lpcmi->fMask & CMIC_MASK_FLAG_NO_UI)) SHELL_ErrorBox(m_pSite, Result);
1400 return Result;
1401 }
1402
1403 if (m_iIdCBFirst != m_iIdCBLast && CmdId >= m_iIdCBFirst && CmdId < m_iIdCBLast)
1404 {
1406 return Result;
1407 }
1408
1409 if (m_iIdDfltFirst != m_iIdDfltLast && CmdId >= m_iIdDfltFirst && CmdId < m_iIdDfltLast)
1410 {
1411 CmdId -= m_iIdDfltFirst;
1412 /* See the definitions of IDM_CUT and co to see how this works */
1413 CmdId += DCM_FCIDM_SHVIEW_OFFSET;
1414 }
1415
1416 if (LocalInvokeInfo.cbSize >= sizeof(CMINVOKECOMMANDINFOEX) && (LocalInvokeInfo.fMask & CMIC_MASK_PTINVOKE))
1417 {
1418 if (m_pDataObj && FAILED_UNEXPECTEDLY(DataObject_SetOffset(m_pDataObj, &LocalInvokeInfo.ptInvoke)))
1419 {
1420 ERR("Unable to add OFFSET to DataObject!\n");
1421 }
1422 }
1423
1424 /* Check if this is a Id */
1425 switch (CmdId)
1426 {
1428 Result = DoPaste(&LocalInvokeInfo, FALSE);
1429 break;
1431 Result = DoPaste(&LocalInvokeInfo, TRUE);
1432 break;
1433 case FCIDM_SHVIEW_OPEN:
1435 Result = DoOpenOrExplore(&LocalInvokeInfo);
1436 break;
1437 case FCIDM_SHVIEW_COPY:
1438 case FCIDM_SHVIEW_CUT:
1439 Result = DoCopyOrCut(&LocalInvokeInfo, CmdId == FCIDM_SHVIEW_COPY);
1440 break;
1442 Result = DoCreateLink(&LocalInvokeInfo);
1443 break;
1445 Result = DoDelete(&LocalInvokeInfo);
1446 break;
1448 Result = DoRename(&LocalInvokeInfo);
1449 break;
1451 Result = DoProperties(&LocalInvokeInfo);
1452 break;
1454 Result = DoCreateNewFolder(&LocalInvokeInfo);
1455 break;
1457 Result = DoCopyToMoveToFolder(&LocalInvokeInfo, TRUE);
1458 break;
1460 Result = DoCopyToMoveToFolder(&LocalInvokeInfo, FALSE);
1461 break;
1462 case FCIDM_SHVIEW_UNDO:
1463 Result = DoUndo(&LocalInvokeInfo);
1464 break;
1465 default:
1467 ERR("Unhandled Verb %xl\n", LOWORD(LocalInvokeInfo.lpVerb));
1468 break;
1469 }
1470
1471 return Result;
1472}
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:831
#define FCIDM_SHVIEW_OPEN
Definition: shresdef.h:858
#define FCIDM_SHVIEW_UNDO
Definition: shresdef.h:834
#define FCIDM_SHVIEW_COPY
Definition: shresdef.h:832
#define FCIDM_SHVIEW_INSERTLINK
Definition: shresdef.h:835
#define FCIDM_SHVIEW_NEWFOLDER
Definition: shresdef.h:854
#define FCIDM_SHVIEW_EXPLORE
Definition: shresdef.h:857
#define FCIDM_SHVIEW_PROPERTIES
Definition: shresdef.h:830
#define FCIDM_SHVIEW_COPYTO
Definition: shresdef.h:836
#define FCIDM_SHVIEW_MOVETO
Definition: shresdef.h:837
#define FCIDM_SHVIEW_DELETE
Definition: shresdef.h:829
#define FCIDM_SHVIEW_RENAME
Definition: shresdef.h:851
#define FCIDM_SHVIEW_CREATELINK
Definition: shresdef.h:852
#define FCIDM_SHVIEW_INSERT
Definition: shresdef.h:833
#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 1228 of file CDefaultContextMenu.cpp.

1229{
1230 LPITEMIDLIST pidlFull = ILCombine(m_pidlFolder, pidl);
1231 if (pidlFull == NULL)
1232 {
1233 return E_FAIL;
1234 }
1235
1236 WCHAR wszPath[MAX_PATH];
1237 BOOL bHasPath = SHGetPathFromIDListW(pidlFull, wszPath);
1238
1239 WCHAR wszDir[MAX_PATH];
1240 if (bHasPath)
1241 {
1242 wcscpy(wszDir, wszPath);
1243 PathRemoveFileSpec(wszDir);
1244 }
1245 else
1246 {
1247 if (!SHGetPathFromIDListW(m_pidlFolder, wszDir))
1248 *wszDir = UNICODE_NULL;
1249 }
1250
1252 ZeroMemory(&sei, sizeof(sei));
1253 sei.cbSize = sizeof(sei);
1254 sei.hwnd = lpcmi->hwnd;
1255 sei.nShow = SW_SHOWNORMAL;
1256 sei.lpVerb = pEntry->Verb;
1257 sei.lpDirectory = wszDir;
1258 sei.lpIDList = pidlFull;
1259 sei.hkeyClass = pEntry->hkClass;
1261 if (bHasPath)
1262 {
1263 sei.lpFile = wszPath;
1264 }
1265
1266 ShellExecuteExW(&sei);
1267
1268 ILFree(pidlFull);
1269
1270 return S_OK;
1271}
#define UNICODE_NULL
void WINAPI ILFree(LPITEMIDLIST pidl)
Definition: pidl.c:940
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:2428
#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 1274 of file CDefaultContextMenu.cpp.

1276{
1277 INT iCmd = LOWORD(lpcmi->lpVerb);
1278 HRESULT hr;
1279 UINT i;
1280
1281 POSITION it = m_StaticEntries.FindIndex(iCmd);
1282
1283 if (it == NULL)
1284 return E_INVALIDARG;
1285
1287
1288 CRegKey VerbKey;
1289 WCHAR VerbKeyPath[sizeof("shell\\") + MAX_VERB];
1290 hr = StringCbPrintfW(VerbKeyPath, sizeof(VerbKeyPath), L"shell\\%s", pEntry->Verb.GetString());
1291 if (SUCCEEDED(hr) && m_pDataObj &&
1292 VerbKey.Open(pEntry->hkClass, VerbKeyPath, KEY_READ) == ERROR_SUCCESS)
1293 {
1294 CLSID clsid;
1295
1296 DWORD KeyState = 0;
1297 if (lpcmi->fMask & CMIC_MASK_SHIFT_DOWN)
1298 KeyState |= MK_SHIFT;
1299 if (lpcmi->fMask & CMIC_MASK_CONTROL_DOWN)
1300 KeyState |= MK_CONTROL;
1301
1302 POINTL *pPtl = NULL;
1303 C_ASSERT(sizeof(POINT) == sizeof(POINTL));
1304 if (lpcmi->fMask & CMIC_MASK_PTINVOKE)
1305 pPtl = (POINTL*)&lpcmi->ptInvoke;
1306
1308 hr = SHELL_GetRegCLSID(VerbKey, L"command", L"DelegateExecute", clsid);
1309 if (SUCCEEDED(hr))
1310 hr = CoCreateInstance(clsid, NULL, CLSCTX_ALL, IID_PPV_ARG(IExecuteCommand, &pEC));
1311 if (SUCCEEDED(hr))
1312 {
1315 return InvokeIExecuteCommandWithDataObject(pEC, pEntry->Verb.GetString(), pPB, m_pDataObj,
1316 lpcmi, static_cast<IContextMenu*>(this));
1317 }
1318
1320 hr = SHELL_GetRegCLSID(VerbKey, L"DropTarget", L"CLSID", clsid);
1321 if (SUCCEEDED(hr))
1322 hr = CoCreateInstance(clsid, NULL, CLSCTX_ALL, IID_PPV_ARG(IDropTarget, &pDT));
1323 if (SUCCEEDED(hr))
1324 {
1327 IUnknown_SetSite(pDT, static_cast<IContextMenu*>(this));
1328 IUnknown_InitializeCommand(pDT, pEntry->Verb.GetString(), pPB);
1329 hr = SHSimulateDrop(pDT, m_pDataObj, KeyState, pPtl, NULL);
1330 IUnknown_SetSite(pDT, NULL);
1331 return hr;
1332 }
1333 }
1334
1335 /* Get the browse flags to see if we need to browse */
1337
1338 for (i=0; i < m_cidl; i++)
1339 {
1340 /* Check if we need to browse */
1341 if (wFlags)
1342 {
1343 hr = TryToBrowse(lpcmi, m_apidl[i], wFlags);
1344 if (SUCCEEDED(hr))
1345 {
1346 /* In WinXP if we have browsed, we don't open any more folders.
1347 * In Win7 we browse to the first folder we find and
1348 * open new windows for each of the rest of the folders */
1350 if (ntver >= _WIN32_WINNT_VISTA)
1351 wFlags = 0; // FIXME: = SBSP_NEWBROWSER | (wFlags & ~SBSP_SAMEBROWSER);
1352 else
1353 i = m_cidl;
1354
1355 continue;
1356 }
1357 }
1358
1359 InvokePidl(lpcmi, m_apidl[i], pEntry);
1360 }
1361
1362 return S_OK;
1363}
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
EXTERN_C HRESULT IUnknown_InitializeCommand(_In_ IUnknown *pUnk, _In_ PCWSTR pszCommandName, _In_opt_ IPropertyBag *pPB)
Definition: utils.cpp:1294
EXTERN_C HRESULT InvokeIExecuteCommandWithDataObject(_In_ IExecuteCommand *pEC, _In_ PCWSTR pszCommandName, _In_opt_ IPropertyBag *pPB, _In_ IDataObject *pDO, _In_opt_ LPCMINVOKECOMMANDINFOEX pICI, _In_opt_ IUnknown *pSite)
Definition: utils.cpp:1348
HRESULT WINAPI SHCreatePropertyBagOnRegKey(HKEY hKey, LPCWSTR subkey, DWORD grfMode, REFIID riid, void **ppv)
Definition: ordinal.c:5177
HRESULT WINAPI IUnknown_SetSite(IUnknown *obj, IUnknown *site)
Definition: ordinal.c:1407
#define C_ASSERT(e)
Definition: intsafe.h:73
#define STGM_READ
Definition: objbase.h:917
int32_t INT
Definition: typedefs.h:58

Referenced by InvokeCommand().

◆ InvokeShellExt()

HRESULT CDefaultContextMenu::InvokeShellExt ( LPCMINVOKECOMMANDINFOEX  lpcmi)
private

Definition at line 1148 of file CDefaultContextMenu.cpp.

1150{
1151 TRACE("verb %p first %x last %x\n", lpcmi->lpVerb, m_iIdSHEFirst, m_iIdSHELast);
1152
1153 UINT idCmd = LOWORD(lpcmi->lpVerb);
1155 if (!pEntry)
1156 return E_FAIL;
1157
1158 /* invoke the dynamic context menu */
1159 lpcmi->lpVerb = MAKEINTRESOURCEA(idCmd - pEntry->iIdCmdFirst);
1160 return pEntry->pCM->InvokeCommand((LPCMINVOKECOMMANDINFO)lpcmi);
1161}

Referenced by InvokeCommand().

◆ IsShellExtensionAlreadyLoaded()

BOOL CDefaultContextMenu::IsShellExtensionAlreadyLoaded ( REFCLSID  clsid)
private

Definition at line 354 of file CDefaultContextMenu.cpp.

355{
356 POSITION it = m_DynamicEntries.GetHeadPosition();
357 while (it != NULL)
358 {
359 const DynamicShellEntry& info = m_DynamicEntries.GetNext(it);
360 if (info.ClassID == clsid)
361 return TRUE;
362 }
363
364 return FALSE;
365}

Referenced by LoadDynamicContextMenuHandler().

◆ LoadDynamicContextMenuHandler()

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

Definition at line 368 of file CDefaultContextMenu.cpp.

369{
370 HRESULT hr;
371 TRACE("LoadDynamicContextMenuHandler entered with This %p hKey %p pclsid %s\n", this, hKey, wine_dbgstr_guid(&clsid));
372
374 return S_OK;
375
378 if (FAILED(hr))
379 {
380 ERR("SHCoCreateInstance(IContextMenu) failed.clsid %s hr 0x%x\n", wine_dbgstr_guid(&clsid), hr);
381 return hr;
382 }
383
384 CComPtr<IShellExtInit> pExtInit;
385 hr = pcm->QueryInterface(IID_PPV_ARG(IShellExtInit, &pExtInit));
386 if (FAILED(hr))
387 {
388 ERR("IContextMenu->QueryInterface(IShellExtInit) failed.clsid %s hr 0x%x\n", wine_dbgstr_guid(&clsid), hr);
389 return hr;
390 }
391
392 hr = pExtInit->Initialize(m_pidlFolder, m_pDataObj, hKey);
393 if (FAILED(hr))
394 {
395 WARN("IShellExtInit::Initialize failed.clsid %s hr 0x%x\n", wine_dbgstr_guid(&clsid), hr);
396 return hr;
397 }
398
399 if (m_site)
401
402 m_DynamicEntries.AddTail({ 0, 0, clsid, pcm });
403
404 return S_OK;
405}
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 1115 of file CDefaultContextMenu.cpp.

1116{
1117 WCHAR UnicodeStr[MAX_VERB];
1118
1119 /* Loop through all the static verbs looking for a match */
1120 for (UINT i = 0; i < _countof(g_StaticInvokeCmdMap); i++)
1121 {
1122 /* We can match both ANSI and unicode strings */
1123 if (IsUnicode)
1124 {
1125 /* The static verbs are ANSI, get a unicode version before doing the compare */
1126 SHAnsiToUnicode(g_StaticInvokeCmdMap[i].szStringVerb, UnicodeStr, MAX_VERB);
1127 if (!wcscmp(UnicodeStr, (LPWSTR)Verb))
1128 {
1129 /* Return the Corresponding Id */
1130 *idCmd = g_StaticInvokeCmdMap[i].IntVerb;
1131 return TRUE;
1132 }
1133 }
1134 else
1135 {
1136 if (!strcmp(g_StaticInvokeCmdMap[i].szStringVerb, (LPSTR)Verb))
1137 {
1138 *idCmd = g_StaticInvokeCmdMap[i].IntVerb;
1139 return TRUE;
1140 }
1141 }
1142 }
1143
1144 return FALSE;
1145}
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 746 of file CDefaultContextMenu.cpp.

752{
753 HRESULT hr;
754 UINT idCmdNext = idCmdFirst;
755 UINT cIds = 0;
756
757 TRACE("BuildShellItemContextMenu entered\n");
758
759 /* Load static verbs and shell extensions from registry */
760 for (UINT i = 0; i < m_cKeys && !(uFlags & CMF_NOVERBS); i++)
761 {
764 }
765
766 /* Add static context menu handlers */
767 cIds = AddStaticContextMenusToMenu(hMenu, &IndexMenu, idCmdFirst, idCmdLast, uFlags);
768 m_iIdSCMFirst = 0; // FIXME: This should be = idCmdFirst?
769 m_iIdSCMLast = cIds;
770 idCmdNext = idCmdFirst + cIds;
771
772 /* Add dynamic context menu handlers */
773 cIds += AddShellExtensionsToMenu(hMenu, &IndexMenu, idCmdNext, idCmdLast, uFlags);
775 m_iIdSHELast = cIds;
776 idCmdNext = idCmdFirst + cIds;
777 TRACE("SH_LoadContextMenuHandlers first %x last %x\n", m_iIdSHEFirst, m_iIdSHELast);
778
779 /* Now let the callback add its own items */
780 QCMINFO qcminfo = {hMenu, IndexMenu, idCmdNext, idCmdLast, NULL};
782 {
783 UINT added = qcminfo.idCmdFirst - idCmdNext;
784 cIds += added;
785 IndexMenu += added;
787 m_iIdCBLast = cIds;
788 idCmdNext = idCmdFirst + cIds;
789 }
790
791 //TODO: DFM_MERGECONTEXTMENU_BOTTOM
792
793 UINT idDefaultOffset = 0;
794 BOOL isBackgroundMenu = !m_cidl;
795 if (!(uFlags & CMF_VERBSONLY) && !isBackgroundMenu)
796 {
797 /* Get the attributes of the items */
798 SFGAOF rfg = SFGAO_BROWSABLE | SFGAO_CANCOPY | SFGAO_CANLINK | SFGAO_CANMOVE | SFGAO_CANDELETE | SFGAO_CANRENAME | SFGAO_HASPROPSHEET | SFGAO_FILESYSTEM | SFGAO_FOLDER;
799 hr = m_psf->GetAttributesOf(m_cidl, m_apidl, &rfg);
801 return MAKE_HRESULT(SEVERITY_SUCCESS, 0, cIds);
802
803 /* Add the default part of the menu */
804 HMENU hmenuDefault = LoadMenu(_AtlBaseModule.GetResourceInstance(), L"MENU_SHV_FILE");
805
806 /* Remove uneeded entries */
807 if (!(rfg & SFGAO_CANMOVE))
808 DeleteMenu(hmenuDefault, IDM_CUT, MF_BYCOMMAND);
809 if (!(rfg & SFGAO_CANCOPY))
810 DeleteMenu(hmenuDefault, IDM_COPY, MF_BYCOMMAND);
811 if (!((rfg & SFGAO_FILESYSTEM) && HasClipboardData()))
812 DeleteMenu(hmenuDefault, IDM_INSERT, MF_BYCOMMAND);
813 if (!(rfg & SFGAO_CANLINK))
814 DeleteMenu(hmenuDefault, IDM_CREATELINK, MF_BYCOMMAND);
815 if (!(rfg & SFGAO_CANDELETE))
816 DeleteMenu(hmenuDefault, IDM_DELETE, MF_BYCOMMAND);
817 if (!(rfg & SFGAO_CANRENAME) || !(uFlags & CMF_CANRENAME))
818 DeleteMenu(hmenuDefault, IDM_RENAME, MF_BYCOMMAND);
819 if (!(rfg & SFGAO_HASPROPSHEET))
820 DeleteMenu(hmenuDefault, IDM_PROPERTIES, MF_BYCOMMAND);
821
822 idDefaultOffset = idCmdNext;
823 UINT idMax = Shell_MergeMenus(hMenu, GetSubMenu(hmenuDefault, 0), IndexMenu, idCmdNext, idCmdLast, 0);
824 m_iIdDfltFirst = cIds;
825 cIds += idMax - idCmdNext;
826 m_iIdDfltLast = cIds;
827
828 DestroyMenu(hmenuDefault);
829 }
830
831 TryPickDefault(hMenu, idCmdFirst, idDefaultOffset, uFlags);
832
833 // TODO: DFM_MERGECONTEXTMENU_TOP
834
835 return MAKE_HRESULT(SEVERITY_SUCCESS, 0, cIds);
836}
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:871
#define IDM_INSERT
Definition: shresdef.h:869
#define IDM_RENAME
Definition: shresdef.h:872
#define IDM_COPY
Definition: shresdef.h:868
#define IDM_CUT
Definition: shresdef.h:867
#define IDM_CREATELINK
Definition: shresdef.h:870
UINT idCmdFirst
Definition: shlobj.h:1391
#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:5826
BOOL WINAPI DestroyMenu(_In_ HMENU)

◆ QueryService()

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

Implements IServiceProvider.

Definition at line 171 of file CDefaultContextMenu.cpp.

172 {
173 return IUnknown_QueryService(m_site, svc, riid, ppv);
174 }
REFIID LPVOID * ppv
Definition: atlbase.h:39

◆ SetSite()

HRESULT WINAPI CDefaultContextMenu::SetSite ( IUnknown pUnkSite)
override

Implements IObjectWithSite.

Definition at line 1655 of file CDefaultContextMenu.cpp.

1656{
1657 m_site = pUnkSite;
1658 return S_OK;
1659}

◆ TryPickDefault()

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

Definition at line 710 of file CDefaultContextMenu.cpp.

711{
712 // Are we allowed to pick a default?
713 if ((uFlags & CMF_NODEFAULT) ||
714 ((uFlags & CMF_DONOTPICKDEFAULT) && RosGetProcessEffectiveVersion() >= _WIN32_WINNT_WIN7))
715 {
716 return;
717 }
718
719 // Do we already have a default?
720 if ((int)GetMenuDefaultItem(hMenu, MF_BYPOSITION, 0) != -1)
721 return;
722
723 // Does the view want to pick one?
724 INT_PTR forceDfm = 0;
725 if (SUCCEEDED(_DoCallback(DFM_GETDEFSTATICID, 0, &forceDfm)) && forceDfm)
726 {
727 for (UINT i = 0; i < _countof(g_StaticInvokeCmdMap); ++i)
728 {
729 UINT menuItemId = g_StaticInvokeCmdMap[i].IntVerb + DfltOffset - DCM_FCIDM_SHVIEW_OFFSET;
730 if (g_StaticInvokeCmdMap[i].DfmCmd == forceDfm &&
731 SetMenuDefaultItem(hMenu, menuItemId, MF_BYCOMMAND))
732 {
733 return;
734 }
735 }
736 }
737
738 // Don't want to pick something like cut or delete as the default but
739 // a static or dynamic verb is a good default.
741 SetMenuDefaultItem(hMenu, idCmdFirst, MF_BYCOMMAND);
742}
#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 1203 of file CDefaultContextMenu.cpp.

1205{
1207 HRESULT hr;
1208
1209 if (!m_site)
1210 return E_FAIL;
1211
1212 /* Get a pointer to the shell browser */
1214 if (FAILED(hr))
1215 return hr;
1216
1217 PIDLIST_ABSOLUTE pidl;
1218 hr = SHILCombine(m_pidlFolder, pidlChild, &pidl);
1220 return hr;
1221
1222 hr = psb->BrowseObject(pidl, wFlags & ~SBSP_RELATIVE);
1223 ILFree(pidl);
1224 return hr;
1225}

Referenced by InvokeRegVerb().

Member Data Documentation

◆ m_aKeys

HKEY* CDefaultContextMenu::m_aKeys
private

Definition at line 107 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 110 of file CDefaultContextMenu.cpp.

Referenced by EnumerateDynamicContextHandlerForKey().

◆ m_cidl

UINT CDefaultContextMenu::m_cidl
private

◆ m_cKeys

UINT CDefaultContextMenu::m_cKeys
private

Definition at line 108 of file CDefaultContextMenu.cpp.

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

◆ m_DynamicEntries

◆ m_hwnd

HWND CDefaultContextMenu::m_hwnd
private

Definition at line 121 of file CDefaultContextMenu.cpp.

Referenced by _DoCallback(), and Initialize().

◆ m_iIdCBFirst

UINT CDefaultContextMenu::m_iIdCBFirst
private

Definition at line 117 of file CDefaultContextMenu.cpp.

Referenced by InvokeCommand(), and QueryContextMenu().

◆ m_iIdCBLast

UINT CDefaultContextMenu::m_iIdCBLast
private

Definition at line 118 of file CDefaultContextMenu.cpp.

Referenced by InvokeCommand(), and QueryContextMenu().

◆ m_iIdDfltFirst

UINT CDefaultContextMenu::m_iIdDfltFirst
private

Definition at line 119 of file CDefaultContextMenu.cpp.

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

◆ m_iIdDfltLast

UINT CDefaultContextMenu::m_iIdDfltLast
private

Definition at line 120 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 103 of file CDefaultContextMenu.cpp.

Referenced by _DoCallback(), and Initialize().

◆ m_pidlFolder

◆ m_pmcb

CComPtr<IContextMenuCB> CDefaultContextMenu::m_pmcb
private

Definition at line 102 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: