ReactOS 0.4.15-dev-8434-g155a7c7
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
 
WCHAR m_DefVerbs [MAX_PATH]
 

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 128 of file CDefaultContextMenu.cpp.

Constructor & Destructor Documentation

◆ CDefaultContextMenu()

CDefaultContextMenu::CDefaultContextMenu ( )

Definition at line 221 of file CDefaultContextMenu.cpp.

221 :
222 m_psf(NULL),
223 m_pmcb(NULL),
224 m_pfnmcb(NULL),
225 m_cidl(0),
226 m_apidl(NULL),
228 m_aKeys(NULL),
229 m_cKeys(NULL),
232 m_iIdSHEFirst(0),
233 m_iIdSHELast(0),
234 m_iIdSCMFirst(0),
235 m_iIdSCMLast(0),
236 m_iIdCBFirst(0),
237 m_iIdCBLast(0),
239 m_iIdDfltLast(0),
240 m_hwnd(NULL)
241{
243}
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
#define UNICODE_NULL

◆ ~CDefaultContextMenu()

CDefaultContextMenu::~CDefaultContextMenu ( )

Definition at line 245 of file CDefaultContextMenu.cpp.

246{
247 for (POSITION it = m_DynamicEntries.GetHeadPosition(); it != NULL;)
248 {
249 const DynamicShellEntry& info = m_DynamicEntries.GetNext(it);
250 IUnknown_SetSite(info.pCM.p, NULL);
251 }
252 m_DynamicEntries.RemoveAll();
253 m_StaticEntries.RemoveAll();
254
255 for (UINT i = 0; i < m_cKeys; i++)
258
259 if (m_pidlFolder)
261 _ILFreeaPidl(const_cast<PITEMID_CHILD *>(m_apidl), m_cidl);
262}
#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
HRESULT WINAPI IUnknown_SetSite(IUnknown *obj, IUnknown *site)
Definition: ordinal.c:1407
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:2594

Member Function Documentation

◆ _DoCallback()

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

Definition at line 312 of file CDefaultContextMenu.cpp.

313{
314 if (m_pmcb)
315 {
316 return m_pmcb->CallBack(m_psf, m_hwnd, m_pDataObj, uMsg, wParam, (LPARAM)lParam);
317 }
318 else if(m_pfnmcb)
319 {
321 }
322
323 return E_FAIL;
324}
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 520 of file CDefaultContextMenu.cpp.

521{
522 UINT cIds = 0;
523
524 if (m_DynamicEntries.IsEmpty())
525 return cIds;
526
527 POSITION it = m_DynamicEntries.GetHeadPosition();
528 while (it != NULL)
529 {
531
532 HRESULT hr = info.pCM->QueryContextMenu(hMenu, *pIndexMenu, idCmdFirst + cIds, idCmdLast, uFlags);
533 if (SUCCEEDED(hr))
534 {
535 info.iIdCmdFirst = cIds;
536 info.NumIds = HRESULT_CODE(hr);
537 (*pIndexMenu) += info.NumIds;
538
539 cIds += info.NumIds;
540 if (idCmdFirst + cIds >= idCmdLast)
541 break;
542 }
543 TRACE("pEntry hr %x contextmenu %p cmdfirst %x num ids %x\n", hr, info.pCM.p, info.iIdCmdFirst, info.NumIds);
544 }
545 return cIds;
546}
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 549 of file CDefaultContextMenu.cpp.

555{
557 MENUITEMINFOW mii = { sizeof(mii) };
558 UINT idResource;
559 WCHAR wszDispVerb[80]; // The limit on XP. If the friendly string is longer, it falls back to the verb key.
560 UINT fState;
561 UINT cIds = 0, indexFirst = *pIndexMenu, indexDefault;
562 int iDefVerbIndex = -1;
563
565 mii.fType = MFT_STRING;
566
567 POSITION it = m_StaticEntries.GetHeadPosition();
568 bool first = true;
569 while (it != NULL)
570 {
572 BOOL forceFirstPos = FALSE;
573
574 fState = MFS_ENABLED;
575
576 /* set first entry as default */
577 if (first)
578 {
579 fState |= MFS_DEFAULT;
580 first = false;
581 }
582
583 if (info.Verb.CompareNoCase(L"open") == 0)
584 {
585 idResource = IDS_OPEN_VERB;
586 fState |= MFS_DEFAULT; /* override default when open verb is found */
587 forceFirstPos++;
588 }
589 else if (info.Verb.CompareNoCase(L"explore") == 0)
590 {
591 idResource = IDS_EXPLORE_VERB;
592 if (uFlags & CMF_EXPLORE)
593 {
594 fState |= MFS_DEFAULT;
595 forceFirstPos++;
596 }
597 }
598 else if (info.Verb.CompareNoCase(L"runas") == 0)
599 idResource = IDS_RUNAS_VERB;
600 else if (info.Verb.CompareNoCase(L"edit") == 0)
601 idResource = IDS_EDIT_VERB;
602 else if (info.Verb.CompareNoCase(L"find") == 0)
603 idResource = IDS_FIND_VERB;
604 else if (info.Verb.CompareNoCase(L"print") == 0)
605 idResource = IDS_PRINT_VERB;
606 else if (info.Verb.CompareNoCase(L"printto") == 0)
607 continue;
608 else
609 idResource = 0;
610
611 /* By default use verb for menu item name */
612 mii.dwTypeData = (LPWSTR)info.Verb.GetString();
613
614 WCHAR wszKey[sizeof("shell\\") + MAX_VERB];
615 HRESULT hr;
616 hr = StringCbPrintfW(wszKey, sizeof(wszKey), L"shell\\%s", info.Verb.GetString());
618 {
619 continue;
620 }
621
622 UINT cmdFlags = 0;
623 bool hide = false;
624 HKEY hkVerb;
625 if (idResource > 0)
626 {
627 if (!(uFlags & CMF_OPTIMIZEFORINVOKE))
628 {
629 if (LoadStringW(shell32_hInstance, idResource, wszDispVerb, _countof(wszDispVerb)))
630 mii.dwTypeData = wszDispVerb; /* use translated verb */
631 else
632 ERR("Failed to load string\n");
633 }
634
635 if (RegOpenKeyW(info.hkClass, wszKey, &hkVerb) != ERROR_SUCCESS)
636 hkVerb = NULL;
637 }
638 else
639 {
640 if (RegOpenKeyW(info.hkClass, wszKey, &hkVerb) == ERROR_SUCCESS)
641 {
642 if (!(uFlags & CMF_OPTIMIZEFORINVOKE))
643 {
644 DWORD cbVerb = sizeof(wszDispVerb);
645 LONG res = RegLoadMUIStringW(hkVerb, L"MUIVerb", wszDispVerb, cbVerb, NULL, 0, NULL);
646 if (res || !*wszDispVerb)
647 res = RegLoadMUIStringW(hkVerb, NULL, wszDispVerb, cbVerb, NULL, 0, NULL);
648
649 if (res == ERROR_SUCCESS && *wszDispVerb)
650 {
651 /* use description for the menu entry */
652 mii.dwTypeData = wszDispVerb;
653 }
654 }
655 }
656 else
657 {
658 hkVerb = NULL;
659 }
660 }
661
662 if (hkVerb)
663 {
664 if (!(uFlags & CMF_EXTENDEDVERBS))
665 hide = RegValueExists(hkVerb, L"Extended");
666
667 if (!hide)
668 hide = RegValueExists(hkVerb, L"ProgrammaticAccessOnly");
669
670 if (!hide && !(uFlags & CMF_DISABLEDVERBS))
671 hide = RegValueExists(hkVerb, L"LegacyDisable");
672
673 if (RegValueExists(hkVerb, L"NeverDefault"))
674 fState &= ~MFS_DEFAULT;
675
676 if (RegValueExists(hkVerb, L"SeparatorBefore"))
677 cmdFlags |= ECF_SEPARATORBEFORE;
678 if (RegValueExists(hkVerb, L"SeparatorAfter"))
679 cmdFlags |= ECF_SEPARATORAFTER;
680
681 RegCloseKey(hkVerb);
682 }
683
684 if (((uFlags & CMF_NODEFAULT) && ntver >= _WIN32_WINNT_VISTA) ||
685 ((uFlags & CMF_DONOTPICKDEFAULT) && ntver >= _WIN32_WINNT_WIN7))
686 {
687 fState &= ~MFS_DEFAULT;
688 }
689
690 if (!hide)
691 {
692 if (cmdFlags & ECF_SEPARATORBEFORE)
693 {
694 if (InsertMenuItemAt(hMenu, *pIndexMenu, MF_SEPARATOR))
695 (*pIndexMenu)++;
696 }
697
698 UINT pos = *pIndexMenu;
699 int verbIndex = hkVerb ? FindVerbInDefaultVerbList(m_DefVerbs, info.Verb) : -1;
700 if (verbIndex >= 0)
701 {
702 if (verbIndex < iDefVerbIndex || iDefVerbIndex < 0)
703 {
704 iDefVerbIndex = verbIndex;
705 fState |= MFS_DEFAULT;
706 forceFirstPos = TRUE;
707 }
708 else
709 {
710 fState &= ~MFS_DEFAULT; // We have already set a better default
711 pos = indexDefault;
712 }
713 }
714 else if (iDefVerbIndex >= 0)
715 {
716 fState &= ~MFS_DEFAULT; // We have already set the default
717 if (forceFirstPos)
718 pos = indexDefault;
719 forceFirstPos = FALSE;
720 }
721
722 mii.fState = fState;
723 mii.wID = iIdCmdFirst + cIds;
724 if (InsertMenuItemW(hMenu, forceFirstPos ? indexFirst : pos, TRUE, &mii))
725 (*pIndexMenu)++;
726
727 if (cmdFlags & ECF_SEPARATORAFTER)
728 {
729 if (InsertMenuItemAt(hMenu, *pIndexMenu, MF_SEPARATOR))
730 (*pIndexMenu)++;
731 }
732
733 if (fState & MFS_DEFAULT)
734 indexDefault = *pIndexMenu; // This is where we want to insert "high priority" verbs
735 }
736 cIds++; // Always increment the id because it acts as the index into m_StaticEntries
737
738 if (mii.wID >= iIdCmdLast)
739 break;
740 }
741
742 return cIds;
743}
static bool RegValueExists(HKEY hKey, LPCWSTR Name)
static int FindVerbInDefaultVerbList(LPCWSTR List, LPCWSTR Verb)
static BOOL InsertMenuItemAt(HMENU hMenu, UINT Pos, UINT Flags)
#define MAX_VERB
#define shell32_hInstance
#define ERR(fmt,...)
Definition: precomp.h:57
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 352 of file CDefaultContextMenu.cpp.

353{
354 WCHAR wszName[VERBKEY_CCHMAX];
355 DWORD cchName, dwIndex = 0;
356 HKEY hShellKey;
357
358 LRESULT lres = RegOpenKeyExW(hKey, L"shell", 0, KEY_READ, &hShellKey);
359 if (lres != STATUS_SUCCESS)
360 return;
361
362 if (!*m_DefVerbs)
363 {
364 DWORD cb = sizeof(m_DefVerbs);
366 }
367
368 while(TRUE)
369 {
370 cchName = _countof(wszName);
371 if (RegEnumKeyExW(hShellKey, dwIndex++, wszName, &cchName, NULL, NULL, NULL, NULL) != ERROR_SUCCESS)
372 break;
373
374 AddStaticEntry(hKey, wszName, uFlags);
375 }
376
377 RegCloseKey(hShellKey);
378}
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
LSTATUS WINAPI RegGetValueW(HKEY hKey, LPCWSTR pszSubKey, LPCWSTR pszValue, DWORD dwFlags, LPDWORD pdwType, PVOID pvData, LPDWORD pcbData)
Definition: reg.c:1931
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
#define RRF_RT_REG_SZ
Definition: driver.c:575
#define VERBKEY_CCHMAX
Definition: precomp.h:130
FxAutoRegKey hKey
static HMODULE MODULEINFO DWORD cb
Definition: module.c:33
#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 326 of file CDefaultContextMenu.cpp.

327{
328 POSITION it = m_StaticEntries.GetHeadPosition();
329 while (it != NULL)
330 {
331 const StaticShellEntry& info = m_StaticEntries.GetNext(it);
332 if (info.Verb.CompareNoCase(szVerb) == 0)
333 {
334 /* entry already exists */
335 return;
336 }
337 }
338
339 TRACE("adding verb %s\n", debugstr_w(szVerb));
340
341 if (!wcsicmp(szVerb, L"open") && !(uFlags & CMF_NODEFAULT))
342 {
343 /* open verb is always inserted in front */
344 m_StaticEntries.AddHead({ szVerb, hkeyClass });
345 }
346 else
347 {
348 m_StaticEntries.AddTail({ szVerb, hkeyClass });
349 }
350}
#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 1239 of file CDefaultContextMenu.cpp.

1240{
1242 HWND hwndTree;
1243 LPCWSTR FlagsName;
1244 WCHAR wszKey[sizeof("shell\\") + MAX_VERB];
1245 HRESULT hr;
1246 DWORD wFlags;
1247 DWORD cbVerb;
1248
1249 if (!m_site)
1250 return 0;
1251
1252 /* Get a pointer to the shell browser */
1254 if (FAILED(hr))
1255 return 0;
1256
1257 /* See if we are in Explore or Browse mode. If the browser's tree is present, we are in Explore mode.*/
1258 if (SUCCEEDED(psb->GetControlWindow(FCW_TREE, &hwndTree)) && hwndTree)
1259 FlagsName = L"ExplorerFlags";
1260 else
1261 FlagsName = L"BrowserFlags";
1262
1263 /* Try to get the flag from the verb */
1264 hr = StringCbPrintfW(wszKey, sizeof(wszKey), L"shell\\%s", pEntry->Verb.GetString());
1266 return 0;
1267
1268 cbVerb = sizeof(wFlags);
1269 if (RegGetValueW(pEntry->hkClass, wszKey, FlagsName, RRF_RT_REG_DWORD, NULL, &wFlags, &cbVerb) == ERROR_SUCCESS)
1270 {
1271 return wFlags;
1272 }
1273
1274 return 0;
1275}
CComPtr< IUnknown > m_site
#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 1003 of file CDefaultContextMenu.cpp.

1004{
1005 if (!m_cidl || !m_pDataObj)
1006 return E_FAIL;
1007
1008 FORMATETC formatetc;
1010 STGMEDIUM medium = {0};
1011 medium.tymed = TYMED_HGLOBAL;
1012 medium.hGlobal = GlobalAlloc(GHND, sizeof(DWORD));
1013 DWORD* pdwFlag = (DWORD*)GlobalLock(medium.hGlobal);
1014 if (pdwFlag)
1015 *pdwFlag = bCopy ? DROPEFFECT_COPY : DROPEFFECT_MOVE;
1016 GlobalUnlock(medium.hGlobal);
1017 m_pDataObj->SetData(&formatetc, &medium, TRUE);
1018
1021 return hr;
1022
1023 return S_OK;
1024}
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 1075 of file CDefaultContextMenu.cpp.

1076{
1077 HRESULT hr = E_FAIL;
1078 if (!m_pDataObj)
1079 {
1080 ERR("m_pDataObj is NULL\n");
1081 return hr;
1082 }
1083
1084 CComPtr<IContextMenu> pContextMenu;
1085 if (bCopy)
1086 hr = SHCoCreateInstance(NULL, &CLSID_CopyToMenu, NULL,
1087 IID_PPV_ARG(IContextMenu, &pContextMenu));
1088 else
1089 hr = SHCoCreateInstance(NULL, &CLSID_MoveToMenu, NULL,
1090 IID_PPV_ARG(IContextMenu, &pContextMenu));
1092 return hr;
1093
1095 hr = pContextMenu->QueryInterface(IID_PPV_ARG(IShellExtInit, &pInit));
1097 return hr;
1098
1099 hr = pInit->Initialize(m_pidlFolder, m_pDataObj, NULL);
1101 return hr;
1102
1103 if (bCopy)
1104 lpici->lpVerb = "copyto";
1105 else
1106 lpici->lpVerb = "moveto";
1107
1108 return pContextMenu->InvokeCommand((LPCMINVOKECOMMANDINFO)lpici);
1109}
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 972 of file CDefaultContextMenu.cpp.

973{
974 if (!m_cidl || !m_pDataObj)
975 return E_FAIL;
976
978 HRESULT hr = m_psf->CreateViewObject(NULL, IID_PPV_ARG(IDropTarget, &pDT));
980 return hr;
981
983
984 return S_OK;
985}
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 1113 of file CDefaultContextMenu.cpp.

1115{
1116 WCHAR wszPath[MAX_PATH];
1117 WCHAR wszName[MAX_PATH];
1118 WCHAR wszNewFolder[25];
1119 HRESULT hr;
1120
1121 /* Get folder path */
1124 return hr;
1125
1126 if (!LoadStringW(shell32_hInstance, IDS_NEWFOLDER, wszNewFolder, _countof(wszNewFolder)))
1127 return E_FAIL;
1128
1129 /* Create the name of the new directory */
1130 if (!PathYetAnotherMakeUniqueName(wszName, wszPath, NULL, wszNewFolder))
1131 return E_FAIL;
1132
1133 /* Create the new directory and show the appropriate dialog in case of error */
1134 if (SHCreateDirectory(lpici->hwnd, wszName) != ERROR_SUCCESS)
1135 return E_FAIL;
1136
1137 /* Show and select the new item in the def view */
1138 LPITEMIDLIST pidl;
1139 PITEMID_CHILD pidlNewItem;
1141
1142 /* Notify the view object about the new item */
1144
1145 if (!m_site)
1146 return S_OK;
1147
1148 /* Get a pointer to the shell view */
1151 return S_OK;
1152
1153 /* Attempt to get the pidl of the new item */
1154 hr = SHILCreateFromPathW(wszName, &pidl, NULL);
1156 return hr;
1157
1158 pidlNewItem = ILFindLastID(pidl);
1159
1160 hr = psv->SelectItem(pidlNewItem, SVSI_DESELECTOTHERS | SVSI_EDIT | SVSI_ENSUREVISIBLE |
1161 SVSI_FOCUSED | SVSI_SELECT);
1163 return hr;
1164
1165 SHFree(pidl);
1166
1167 return S_OK;
1168}
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:1892
#define SHCNF_FLUSH
Definition: shlobj.h:1927
#define SHCNF_PATHW
Definition: shlobj.h:1924
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 987 of file CDefaultContextMenu.cpp.

988{
989 if (!m_cidl || !m_pDataObj)
990 return E_FAIL;
991
995 return hr;
996
997 DWORD grfKeyState = (lpcmi->fMask & CMIC_MASK_SHIFT_DOWN) ? MK_SHIFT : 0;
998 SHSimulateDrop(pDT, m_pDataObj, grfKeyState, NULL, NULL);
999
1000 return S_OK;
1001}
HRESULT CRecyclerDropTarget_CreateInstance(REFIID riid, LPVOID *ppvOut)

Referenced by InvokeCommand().

◆ DoOpenOrExplore()

HRESULT CDefaultContextMenu::DoOpenOrExplore ( LPCMINVOKECOMMANDINFOEX  lpcmi)
private

Definition at line 966 of file CDefaultContextMenu.cpp.

967{
969 return E_FAIL;
970}
#define UNIMPLEMENTED
Definition: debug.h:118

Referenced by InvokeCommand().

◆ DoPaste()

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

Definition at line 913 of file CDefaultContextMenu.cpp.

914{
915 HRESULT hr;
916
918 hr = OleGetClipboard(&pda);
920 return hr;
921
922 FORMATETC formatetc2;
923 STGMEDIUM medium2;
925
926 DWORD dwKey= 0;
927
928 if (SUCCEEDED(pda->GetData(&formatetc2, &medium2)))
929 {
930 DWORD * pdwFlag = (DWORD*)GlobalLock(medium2.hGlobal);
931 if (pdwFlag)
932 {
933 if (*pdwFlag == DROPEFFECT_COPY)
934 dwKey = MK_CONTROL;
935 else
936 dwKey = MK_SHIFT;
937 }
938 else
939 {
940 ERR("No drop effect obtained\n");
941 }
942 GlobalUnlock(medium2.hGlobal);
943 }
944
945 if (bLink)
946 {
947 dwKey = MK_CONTROL|MK_SHIFT;
948 }
949
951 if (m_cidl)
952 hr = m_psf->GetUIObjectOf(NULL, 1, &m_apidl[0], IID_NULL_PPV_ARG(IDropTarget, &pdrop));
953 else
954 hr = m_psf->CreateViewObject(NULL, IID_PPV_ARG(IDropTarget, &pdrop));
955
957 return hr;
958
959 SHSimulateDrop(pdrop, pda, dwKey, NULL, NULL);
960
961 TRACE("CP result %x\n", hr);
962 return S_OK;
963}
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 1053 of file CDefaultContextMenu.cpp.

1055{
1057
1058 // We are asked to run the default property sheet
1059 if (hr == S_FALSE)
1060 {
1062 }
1063
1064 return hr;
1065}
HRESULT _DoCallback(UINT uMsg, WPARAM wParam, LPVOID lParam)
#define DFM_INVOKECOMMAND
Definition: precomp.h:45
HRESULT SHELL32_ShowPropertiesDialog(IDataObject *pdtobj)
Definition: shlfolder.cpp:504
#define DFM_CMD_PROPERTIES
Definition: shlobj.h:2611
#define S_FALSE
Definition: winerror.h:2357

Referenced by InvokeCommand().

◆ DoRename()

HRESULT CDefaultContextMenu::DoRename ( LPCMINVOKECOMMANDINFOEX  lpcmi)
private

Definition at line 1026 of file CDefaultContextMenu.cpp.

1027{
1029 HRESULT hr;
1030
1031 if (!m_site || !m_cidl)
1032 return E_FAIL;
1033
1034 /* Get a pointer to the shell browser */
1037 return hr;
1038
1040 hr = psb->QueryActiveShellView(&lpSV);
1042 return hr;
1043
1044 SVSIF selFlags = SVSI_DESELECTOTHERS | SVSI_EDIT | SVSI_ENSUREVISIBLE | SVSI_FOCUSED | SVSI_SELECT;
1045 hr = lpSV->SelectItem(m_apidl[0], selFlags);
1047 return hr;
1048
1049 return S_OK;
1050}

Referenced by InvokeCommand().

◆ DoUndo()

HRESULT CDefaultContextMenu::DoUndo ( LPCMINVOKECOMMANDINFOEX  lpcmi)
private

Definition at line 1068 of file CDefaultContextMenu.cpp.

1069{
1070 ERR("TODO: Undo\n");
1071 return E_NOTIMPL;
1072}
#define E_NOTIMPL
Definition: ddrawi.h:99

Referenced by InvokeCommand().

◆ EnumerateDynamicContextHandlerForKey()

BOOL CDefaultContextMenu::EnumerateDynamicContextHandlerForKey ( HKEY  hRootKey)
private

Definition at line 456 of file CDefaultContextMenu.cpp.

457{
458 WCHAR wszName[MAX_PATH], wszBuf[MAX_PATH], *pwszClsid;
460 HRESULT hr;
461 HKEY hKey;
462
463 if (RegOpenKeyExW(hRootKey, L"shellex\\ContextMenuHandlers", 0, KEY_READ, &hKey) != ERROR_SUCCESS)
464 {
465 TRACE("RegOpenKeyExW failed\n");
466 return FALSE;
467 }
468
469 DWORD dwIndex = 0;
470 while (TRUE)
471 {
472 cchName = _countof(wszName);
473 if (RegEnumKeyExW(hKey, dwIndex++, wszName, &cchName, NULL, NULL, NULL, NULL) != ERROR_SUCCESS)
474 break;
475
476 /* Key name or key value is CLSID */
477 CLSID clsid;
478 hr = CLSIDFromString(wszName, &clsid);
479 if (hr == S_OK)
480 pwszClsid = wszName;
481 else
482 {
483 DWORD cchBuf = _countof(wszBuf);
484 if (RegGetValueW(hKey, wszName, NULL, RRF_RT_REG_SZ, NULL, wszBuf, &cchBuf) == ERROR_SUCCESS)
485 hr = CLSIDFromString(wszBuf, &clsid);
486 pwszClsid = wszBuf;
487 }
488
489 if (FAILED(hr))
490 {
491 ERR("CLSIDFromString failed for clsid %S hr 0x%x\n", pwszClsid, hr);
492 continue;
493 }
494
496 {
498 L"Software\\Microsoft\\Windows\\CurrentVersion\\Shell Extensions\\Approved",
499 pwszClsid,
501 NULL,
502 NULL,
504 {
505 ERR("Shell extension %s not approved!\n", pwszClsid);
506 continue;
507 }
508 }
509
511 if (FAILED(hr))
512 WARN("Failed to get context menu entires from shell extension! clsid: %S\n", pwszClsid);
513 }
514
516 return TRUE;
517}
#define WARN(fmt,...)
Definition: precomp.h:61
HRESULT LoadDynamicContextMenuHandler(HKEY hKey, REFCLSID clsid)
HRESULT WINAPI CLSIDFromString(LPCOLESTR idstr, LPCLSID id)
Definition: compobj.c:2338
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 1556 of file CDefaultContextMenu.cpp.

1562{
1563 /* We don't handle the help text yet */
1564 if (uFlags == GCS_HELPTEXTA ||
1565 uFlags == GCS_HELPTEXTW ||
1566 HIWORD(idCommand) != 0)
1567 {
1568 return E_NOTIMPL;
1569 }
1570
1571 UINT CmdId = LOWORD(idCommand);
1572
1573 if (!m_DynamicEntries.IsEmpty() && CmdId >= m_iIdSHEFirst && CmdId < m_iIdSHELast)
1574 {
1575 idCommand -= m_iIdSHEFirst;
1577 if (!pEntry)
1578 return E_FAIL;
1579
1580 idCommand -= pEntry->iIdCmdFirst;
1581 return pEntry->pCM->GetCommandString(idCommand,
1582 uFlags,
1583 lpReserved,
1584 lpszName,
1585 uMaxNameLen);
1586 }
1587
1588 if (!m_StaticEntries.IsEmpty() && CmdId >= m_iIdSCMFirst && CmdId < m_iIdSCMLast)
1589 {
1590 /* Validation just returns S_OK on a match. The id exists. */
1591 if (uFlags == GCS_VALIDATEA || uFlags == GCS_VALIDATEW)
1592 return S_OK;
1593
1594 CmdId -= m_iIdSCMFirst;
1595
1596 POSITION it = m_StaticEntries.FindIndex(CmdId);
1597
1598 if (it == NULL)
1599 return E_INVALIDARG;
1600
1602
1603 if (uFlags == GCS_VERBW)
1604 return StringCchCopyW((LPWSTR)lpszName, uMaxNameLen, pEntry->Verb);
1605
1606 if (uFlags == GCS_VERBA)
1607 {
1608 if (SHUnicodeToAnsi(pEntry->Verb, lpszName, uMaxNameLen))
1609 return S_OK;
1610 }
1611
1612 return E_INVALIDARG;
1613 }
1614
1615 //FIXME: Should we handle callbacks here?
1616 if (m_iIdDfltFirst != m_iIdDfltLast && CmdId >= m_iIdDfltFirst && CmdId < m_iIdDfltLast)
1617 {
1618 CmdId -= m_iIdDfltFirst;
1619 /* See the definitions of IDM_CUT and co to see how this works */
1620 CmdId += DCM_FCIDM_SHVIEW_OFFSET;
1621 }
1622
1623 /* Loop looking for a matching Id */
1624 for (UINT i = 0; i < _countof(g_StaticInvokeCmdMap); i++)
1625 {
1626 if (g_StaticInvokeCmdMap[i].IntVerb == CmdId)
1627 {
1628 /* Validation just returns S_OK on a match */
1629 if (uFlags == GCS_VALIDATEA || uFlags == GCS_VALIDATEW)
1630 return S_OK;
1631
1632 /* Return a copy of the ANSI verb */
1633 if (uFlags == GCS_VERBA)
1634 return StringCchCopyA(lpszName, uMaxNameLen, g_StaticInvokeCmdMap[i].szStringVerb);
1635
1636 /* Convert the ANSI verb to unicode and return that */
1637 if (uFlags == GCS_VERBW)
1638 {
1639 if (SHAnsiToUnicode(g_StaticInvokeCmdMap[i].szStringVerb, (LPWSTR)lpszName, uMaxNameLen))
1640 return S_OK;
1641 }
1642 }
1643 }
1644
1645 return E_INVALIDARG;
1646}
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 1170 of file CDefaultContextMenu.cpp.

1171{
1172 POSITION it = m_DynamicEntries.GetHeadPosition();
1173 while (it != NULL)
1174 {
1176
1177 if (idCmd >= info.iIdCmdFirst + info.NumIds)
1178 continue;
1179
1180 if (idCmd < info.iIdCmdFirst || idCmd > info.iIdCmdFirst + info.NumIds)
1181 return NULL;
1182
1183 return &info;
1184 }
1185
1186 return NULL;
1187}

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

◆ GetSite()

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

Definition at line 1743 of file CDefaultContextMenu.cpp.

1744{
1745 if (!m_site)
1746 return E_FAIL;
1747
1748 return m_site->QueryInterface(riid, ppvSite);
1749}
REFIID riid
Definition: atlbase.h:39

◆ HandleMenuMsg()

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

Implements IContextMenu2.

Definition at line 1650 of file CDefaultContextMenu.cpp.

1654{
1655 /* FIXME: Should we implement this as well? */
1656 return S_OK;
1657}

◆ HandleMenuMsg2()

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

Implements IContextMenu3.

Definition at line 1697 of file CDefaultContextMenu.cpp.

1702{
1703 if (uMsg == WM_INITMENUPOPUP)
1704 {
1705 POSITION it = m_DynamicEntries.GetHeadPosition();
1706 while (it != NULL)
1707 {
1709 SHForwardContextMenuMsg(info.pCM, uMsg, wParam, lParam, plResult, TRUE);
1710 }
1711 return S_OK;
1712 }
1713
1714 UINT CmdId;
1715 HRESULT hr = SHGetMenuIdFromMenuMsg(uMsg, lParam, &CmdId);
1716 if (FAILED(hr))
1717 return S_FALSE;
1718
1719 if (CmdId < m_iIdSHEFirst || CmdId >= m_iIdSHELast)
1720 return S_FALSE;
1721
1722 CmdId -= m_iIdSHEFirst;
1724 if (pEntry)
1725 {
1726 SHSetMenuIdInMenuMsg(uMsg, lParam, CmdId - pEntry->iIdCmdFirst);
1727 SHForwardContextMenuMsg(pEntry->pCM, uMsg, wParam, lParam, plResult, TRUE);
1728 }
1729
1730 return S_OK;
1731}
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 264 of file CDefaultContextMenu.cpp.

265{
266 TRACE("cidl %u\n", pdcm->cidl);
267
268 if (!pdcm->pcmcb && !lpfn)
269 {
270 ERR("CDefaultContextMenu needs a callback!\n");
271 return E_INVALIDARG;
272 }
273
274 m_cidl = pdcm->cidl;
276 if (m_cidl && !m_apidl)
277 return E_OUTOFMEMORY;
278 m_psf = pdcm->psf;
279 m_pmcb = pdcm->pcmcb;
280 m_pfnmcb = lpfn;
281 m_hwnd = pdcm->hwnd;
282
283 m_cKeys = pdcm->cKeys;
284 if (pdcm->cKeys)
285 {
286 m_aKeys = (HKEY*)HeapAlloc(GetProcessHeap(), 0, sizeof(HKEY) * pdcm->cKeys);
287 if (!m_aKeys)
288 return E_OUTOFMEMORY;
289 memcpy(m_aKeys, pdcm->aKeys, sizeof(HKEY) * pdcm->cKeys);
290 }
291
292 m_psf->GetUIObjectOf(pdcm->hwnd, m_cidl, m_apidl, IID_NULL_PPV_ARG(IDataObject, &m_pDataObj));
293
294 if (pdcm->pidlFolder)
295 {
297 }
298 else
299 {
301 if (SUCCEEDED(m_psf->QueryInterface(IID_PPV_ARG(IPersistFolder2, &pf))))
302 {
303 if (FAILED(pf->GetCurFolder(&m_pidlFolder)))
304 ERR("GetCurFolder failed\n");
305 }
306 TRACE("pidlFolder %p\n", m_pidlFolder);
307 }
308
309 return S_OK;
310}
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:2611
LPITEMIDLIST WINAPI ILClone(LPCITEMIDLIST pidl)
Definition: pidl.c:237
const PCUITEMID_CHILD * PCUITEMID_CHILD_ARRAY
Definition: shtypes.idl:71
IContextMenuCB * pcmcb
Definition: shlobj.h:2549
IShellFolder * psf
Definition: shlobj.h:2551
PCUITEMID_CHILD_ARRAY apidl
Definition: shlobj.h:2553
const HKEY * aKeys
Definition: shlobj.h:2556
PCIDLIST_ABSOLUTE pidlFolder
Definition: shlobj.h:2550

◆ InvokeCommand()

HRESULT WINAPI CDefaultContextMenu::InvokeCommand ( LPCMINVOKECOMMANDINFO  lpcmi)
override

Implements IContextMenu.

Definition at line 1447 of file CDefaultContextMenu.cpp.

1449{
1450 CMINVOKECOMMANDINFOEX LocalInvokeInfo = {};
1452 UINT CmdId;
1453
1454 /* Take a local copy of the fixed members of the
1455 struct as we might need to modify the verb */
1456 memcpy(&LocalInvokeInfo, lpcmi, min(sizeof(LocalInvokeInfo), lpcmi->cbSize));
1457
1458 /* Check if this is a string verb */
1459 if (!IS_INTRESOURCE(LocalInvokeInfo.lpVerb))
1460 {
1461 /* Get the ID which corresponds to this verb, and update our local copy */
1462 if (MapVerbToCmdId((LPVOID)LocalInvokeInfo.lpVerb, &CmdId, FALSE))
1463 LocalInvokeInfo.lpVerb = MAKEINTRESOURCEA(CmdId);
1464 }
1465
1466 CmdId = LOWORD(LocalInvokeInfo.lpVerb);
1467
1468 if (!m_DynamicEntries.IsEmpty() && CmdId >= m_iIdSHEFirst && CmdId < m_iIdSHELast)
1469 {
1470 LocalInvokeInfo.lpVerb -= m_iIdSHEFirst;
1471 Result = InvokeShellExt(&LocalInvokeInfo);
1472 return Result;
1473 }
1474
1475 if (!m_StaticEntries.IsEmpty() && CmdId >= m_iIdSCMFirst && CmdId < m_iIdSCMLast)
1476 {
1477 LocalInvokeInfo.lpVerb -= m_iIdSCMFirst;
1478 Result = InvokeRegVerb(&LocalInvokeInfo);
1479 // TODO: if (FAILED(Result) && !(lpcmi->fMask & CMIC_MASK_FLAG_NO_UI)) SHELL_ErrorBox(m_pSite, Result);
1480 return Result;
1481 }
1482
1483 if (m_iIdCBFirst != m_iIdCBLast && CmdId >= m_iIdCBFirst && CmdId < m_iIdCBLast)
1484 {
1486 return Result;
1487 }
1488
1489 if (m_iIdDfltFirst != m_iIdDfltLast && CmdId >= m_iIdDfltFirst && CmdId < m_iIdDfltLast)
1490 {
1491 CmdId -= m_iIdDfltFirst;
1492 /* See the definitions of IDM_CUT and co to see how this works */
1493 CmdId += DCM_FCIDM_SHVIEW_OFFSET;
1494 }
1495
1496 if (LocalInvokeInfo.cbSize >= sizeof(CMINVOKECOMMANDINFOEX) && (LocalInvokeInfo.fMask & CMIC_MASK_PTINVOKE))
1497 {
1498 if (m_pDataObj && FAILED_UNEXPECTEDLY(DataObject_SetOffset(m_pDataObj, &LocalInvokeInfo.ptInvoke)))
1499 {
1500 ERR("Unable to add OFFSET to DataObject!\n");
1501 }
1502 }
1503
1504 /* Check if this is a Id */
1505 switch (CmdId)
1506 {
1508 Result = DoPaste(&LocalInvokeInfo, FALSE);
1509 break;
1511 Result = DoPaste(&LocalInvokeInfo, TRUE);
1512 break;
1513 case FCIDM_SHVIEW_OPEN:
1515 Result = DoOpenOrExplore(&LocalInvokeInfo);
1516 break;
1517 case FCIDM_SHVIEW_COPY:
1518 case FCIDM_SHVIEW_CUT:
1519 Result = DoCopyOrCut(&LocalInvokeInfo, CmdId == FCIDM_SHVIEW_COPY);
1520 break;
1522 Result = DoCreateLink(&LocalInvokeInfo);
1523 break;
1525 Result = DoDelete(&LocalInvokeInfo);
1526 break;
1528 Result = DoRename(&LocalInvokeInfo);
1529 break;
1531 Result = DoProperties(&LocalInvokeInfo);
1532 break;
1534 Result = DoCreateNewFolder(&LocalInvokeInfo);
1535 break;
1537 Result = DoCopyToMoveToFolder(&LocalInvokeInfo, TRUE);
1538 break;
1540 Result = DoCopyToMoveToFolder(&LocalInvokeInfo, FALSE);
1541 break;
1542 case FCIDM_SHVIEW_UNDO:
1543 Result = DoUndo(&LocalInvokeInfo);
1544 break;
1545 default:
1547 ERR("Unhandled Verb %xl\n", LOWORD(LocalInvokeInfo.lpVerb));
1548 break;
1549 }
1550
1551 return Result;
1552}
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 1303 of file CDefaultContextMenu.cpp.

1304{
1305 BOOL unicode = lpcmi->cbSize >= FIELD_OFFSET(CMINVOKECOMMANDINFOEX, ptInvoke) &&
1306 (lpcmi->fMask & CMIC_MASK_UNICODE);
1307
1308 LPITEMIDLIST pidlFull = ILCombine(m_pidlFolder, pidl);
1309 if (pidlFull == NULL)
1310 {
1311 return E_FAIL;
1312 }
1313
1314 WCHAR wszPath[MAX_PATH];
1315 BOOL bHasPath = SHGetPathFromIDListW(pidlFull, wszPath);
1316
1317 WCHAR wszDir[MAX_PATH];
1318 if (bHasPath)
1319 {
1320 wcscpy(wszDir, wszPath);
1321 PathRemoveFileSpec(wszDir);
1322 }
1323 else
1324 {
1325 if (!SHGetPathFromIDListW(m_pidlFolder, wszDir))
1326 *wszDir = UNICODE_NULL;
1327 }
1328
1329 CComHeapPtr<WCHAR> pszParamsW;
1330 SHELLEXECUTEINFOW sei = { sizeof(sei) };
1331 sei.hwnd = lpcmi->hwnd;
1332 sei.nShow = SW_SHOWNORMAL;
1333 sei.lpVerb = pEntry->Verb;
1334 sei.lpDirectory = wszDir;
1335 sei.lpIDList = pidlFull;
1336 sei.hkeyClass = pEntry->hkClass;
1338 if (bHasPath)
1339 sei.lpFile = wszPath;
1340
1341 if (unicode && !StrIsNullOrEmpty(lpcmi->lpParametersW))
1342 sei.lpParameters = lpcmi->lpParametersW;
1343 else if (!StrIsNullOrEmpty(lpcmi->lpParameters) && __SHCloneStrAtoW(&pszParamsW, lpcmi->lpParameters))
1344 sei.lpParameters = pszParamsW;
1345
1346 ShellExecuteExW(&sei);
1347
1348 ILFree(pidlFull);
1349
1350 return S_OK;
1351}
if(dx< 0)
Definition: linetemp.h:194
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)
static __inline LPWSTR __SHCloneStrAtoW(WCHAR **target, const char *source)
Definition: shell32_main.h:170
#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:2455
#define PathRemoveFileSpec
Definition: shlwapi.h:1035
LPCWSTR lpDirectory
Definition: shellapi.h:334
LPCWSTR lpParameters
Definition: shellapi.h:333
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
#define SW_SHOWNORMAL
Definition: winuser.h:770

Referenced by InvokeRegVerb().

◆ InvokeRegVerb()

HRESULT CDefaultContextMenu::InvokeRegVerb ( LPCMINVOKECOMMANDINFOEX  lpcmi)
private

Definition at line 1354 of file CDefaultContextMenu.cpp.

1356{
1357 INT iCmd = LOWORD(lpcmi->lpVerb);
1358 HRESULT hr;
1359 UINT i;
1360
1361 POSITION it = m_StaticEntries.FindIndex(iCmd);
1362
1363 if (it == NULL)
1364 return E_INVALIDARG;
1365
1367
1368 CRegKey VerbKey;
1369 WCHAR VerbKeyPath[sizeof("shell\\") + MAX_VERB];
1370 hr = StringCbPrintfW(VerbKeyPath, sizeof(VerbKeyPath), L"shell\\%s", pEntry->Verb.GetString());
1371 if (SUCCEEDED(hr) && m_pDataObj &&
1372 VerbKey.Open(pEntry->hkClass, VerbKeyPath, KEY_READ) == ERROR_SUCCESS)
1373 {
1374 CLSID clsid;
1375
1376 DWORD KeyState = 0;
1377 if (lpcmi->fMask & CMIC_MASK_SHIFT_DOWN)
1378 KeyState |= MK_SHIFT;
1379 if (lpcmi->fMask & CMIC_MASK_CONTROL_DOWN)
1380 KeyState |= MK_CONTROL;
1381
1382 POINTL *pPtl = NULL;
1383 C_ASSERT(sizeof(POINT) == sizeof(POINTL));
1384 if (lpcmi->fMask & CMIC_MASK_PTINVOKE)
1385 pPtl = (POINTL*)&lpcmi->ptInvoke;
1386
1388 hr = SHELL_GetRegCLSID(VerbKey, L"command", L"DelegateExecute", clsid);
1389 if (SUCCEEDED(hr))
1390 hr = CoCreateInstance(clsid, NULL, CLSCTX_ALL, IID_PPV_ARG(IExecuteCommand, &pEC));
1391 if (SUCCEEDED(hr))
1392 {
1395 return InvokeIExecuteCommandWithDataObject(pEC, pEntry->Verb.GetString(), pPB, m_pDataObj,
1396 lpcmi, static_cast<IContextMenu*>(this));
1397 }
1398
1400 hr = SHELL_GetRegCLSID(VerbKey, L"DropTarget", L"CLSID", clsid);
1401 if (SUCCEEDED(hr))
1402 hr = CoCreateInstance(clsid, NULL, CLSCTX_ALL, IID_PPV_ARG(IDropTarget, &pDT));
1403 if (SUCCEEDED(hr))
1404 {
1407 IUnknown_SetSite(pDT, static_cast<IContextMenu*>(this));
1408 IUnknown_InitializeCommand(pDT, pEntry->Verb.GetString(), pPB);
1409 hr = SHSimulateDrop(pDT, m_pDataObj, KeyState, pPtl, NULL);
1410 IUnknown_SetSite(pDT, NULL);
1411 return hr;
1412 }
1413 }
1414
1415 /* Get the browse flags to see if we need to browse */
1417
1418 for (i=0; i < m_cidl; i++)
1419 {
1420 /* Check if we need to browse */
1421 if (wFlags)
1422 {
1423 hr = TryToBrowse(lpcmi, m_apidl[i], wFlags);
1424 if (SUCCEEDED(hr))
1425 {
1426 /* In WinXP if we have browsed, we don't open any more folders.
1427 * In Win7 we browse to the first folder we find and
1428 * open new windows for each of the rest of the folders */
1430 if (ntver >= _WIN32_WINNT_VISTA)
1431 wFlags = 0; // FIXME: = SBSP_NEWBROWSER | (wFlags & ~SBSP_SAMEBROWSER);
1432 else
1433 i = m_cidl;
1434
1435 continue;
1436 }
1437 }
1438
1439 InvokePidl(lpcmi, m_apidl[i], pEntry);
1440 }
1441
1442 return S_OK;
1443}
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
#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 1223 of file CDefaultContextMenu.cpp.

1225{
1226 TRACE("verb %p first %x last %x\n", lpcmi->lpVerb, m_iIdSHEFirst, m_iIdSHELast);
1227
1228 UINT idCmd = LOWORD(lpcmi->lpVerb);
1230 if (!pEntry)
1231 return E_FAIL;
1232
1233 /* invoke the dynamic context menu */
1234 lpcmi->lpVerb = MAKEINTRESOURCEA(idCmd - pEntry->iIdCmdFirst);
1235 return pEntry->pCM->InvokeCommand((LPCMINVOKECOMMANDINFO)lpcmi);
1236}

Referenced by InvokeCommand().

◆ IsShellExtensionAlreadyLoaded()

BOOL CDefaultContextMenu::IsShellExtensionAlreadyLoaded ( REFCLSID  clsid)
private

Definition at line 402 of file CDefaultContextMenu.cpp.

403{
404 POSITION it = m_DynamicEntries.GetHeadPosition();
405 while (it != NULL)
406 {
407 const DynamicShellEntry& info = m_DynamicEntries.GetNext(it);
408 if (info.ClassID == clsid)
409 return TRUE;
410 }
411
412 return FALSE;
413}

Referenced by LoadDynamicContextMenuHandler().

◆ LoadDynamicContextMenuHandler()

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

Definition at line 416 of file CDefaultContextMenu.cpp.

417{
418 HRESULT hr;
419 TRACE("LoadDynamicContextMenuHandler entered with This %p hKey %p pclsid %s\n", this, hKey, wine_dbgstr_guid(&clsid));
420
422 return S_OK;
423
426 if (FAILED(hr))
427 {
428 ERR("SHCoCreateInstance(IContextMenu) failed.clsid %s hr 0x%x\n", wine_dbgstr_guid(&clsid), hr);
429 return hr;
430 }
431
432 CComPtr<IShellExtInit> pExtInit;
433 hr = pcm->QueryInterface(IID_PPV_ARG(IShellExtInit, &pExtInit));
434 if (FAILED(hr))
435 {
436 ERR("IContextMenu->QueryInterface(IShellExtInit) failed.clsid %s hr 0x%x\n", wine_dbgstr_guid(&clsid), hr);
437 return hr;
438 }
439
440 hr = pExtInit->Initialize(m_pDataObj ? NULL : m_pidlFolder, m_pDataObj, hKey);
441 if (FAILED(hr))
442 {
443 WARN("IShellExtInit::Initialize failed.clsid %s hr 0x%x\n", wine_dbgstr_guid(&clsid), hr);
444 return hr;
445 }
446
447 if (m_site)
449
450 m_DynamicEntries.AddTail({ 0, 0, clsid, pcm });
451
452 return S_OK;
453}
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 1190 of file CDefaultContextMenu.cpp.

1191{
1192 WCHAR UnicodeStr[MAX_VERB];
1193
1194 /* Loop through all the static verbs looking for a match */
1195 for (UINT i = 0; i < _countof(g_StaticInvokeCmdMap); i++)
1196 {
1197 /* We can match both ANSI and unicode strings */
1198 if (IsUnicode)
1199 {
1200 /* The static verbs are ANSI, get a unicode version before doing the compare */
1201 SHAnsiToUnicode(g_StaticInvokeCmdMap[i].szStringVerb, UnicodeStr, MAX_VERB);
1202 if (!wcscmp(UnicodeStr, (LPWSTR)Verb))
1203 {
1204 /* Return the Corresponding Id */
1205 *idCmd = g_StaticInvokeCmdMap[i].IntVerb;
1206 return TRUE;
1207 }
1208 }
1209 else
1210 {
1211 if (!strcmp(g_StaticInvokeCmdMap[i].szStringVerb, (LPSTR)Verb))
1212 {
1213 *idCmd = g_StaticInvokeCmdMap[i].IntVerb;
1214 return TRUE;
1215 }
1216 }
1217 }
1218
1219 return FALSE;
1220}
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 821 of file CDefaultContextMenu.cpp.

827{
828 HRESULT hr;
829 UINT idCmdNext = idCmdFirst;
830 UINT cIds = 0;
831
832 TRACE("BuildShellItemContextMenu entered\n");
833
834 /* Load static verbs and shell extensions from registry */
835 for (UINT i = 0; i < m_cKeys && !(uFlags & CMF_NOVERBS); i++)
836 {
839 }
840
841 /* Add static context menu handlers */
842 cIds = AddStaticContextMenusToMenu(hMenu, &IndexMenu, idCmdFirst, idCmdLast, uFlags);
843 m_iIdSCMFirst = 0; // FIXME: This should be = idCmdFirst?
844 m_iIdSCMLast = cIds;
845 idCmdNext = idCmdFirst + cIds;
846
847 /* Add dynamic context menu handlers */
848 cIds += AddShellExtensionsToMenu(hMenu, &IndexMenu, idCmdNext, idCmdLast, uFlags);
850 m_iIdSHELast = cIds;
851 idCmdNext = idCmdFirst + cIds;
852 TRACE("SH_LoadContextMenuHandlers first %x last %x\n", m_iIdSHEFirst, m_iIdSHELast);
853
854 /* Now let the callback add its own items */
855 QCMINFO qcminfo = {hMenu, IndexMenu, idCmdNext, idCmdLast, NULL};
857 {
858 UINT added = qcminfo.idCmdFirst - idCmdNext;
859 cIds += added;
860 IndexMenu += added;
862 m_iIdCBLast = cIds;
863 idCmdNext = idCmdFirst + cIds;
864 }
865
866 //TODO: DFM_MERGECONTEXTMENU_BOTTOM
867
868 UINT idDefaultOffset = 0;
869 BOOL isBackgroundMenu = !m_cidl;
870 if (!(uFlags & CMF_VERBSONLY) && !isBackgroundMenu)
871 {
872 /* Get the attributes of the items */
873 SFGAOF rfg = SFGAO_BROWSABLE | SFGAO_CANCOPY | SFGAO_CANLINK | SFGAO_CANMOVE | SFGAO_CANDELETE | SFGAO_CANRENAME | SFGAO_HASPROPSHEET | SFGAO_FILESYSTEM | SFGAO_FOLDER;
874 hr = m_psf->GetAttributesOf(m_cidl, m_apidl, &rfg);
876 return MAKE_HRESULT(SEVERITY_SUCCESS, 0, cIds);
877
878 /* Add the default part of the menu */
879 HMENU hmenuDefault = LoadMenu(_AtlBaseModule.GetResourceInstance(), L"MENU_SHV_FILE");
880
881 /* Remove uneeded entries */
882 if (!(rfg & SFGAO_CANMOVE))
883 DeleteMenu(hmenuDefault, IDM_CUT, MF_BYCOMMAND);
884 if (!(rfg & SFGAO_CANCOPY))
885 DeleteMenu(hmenuDefault, IDM_COPY, MF_BYCOMMAND);
886 if (!((rfg & SFGAO_FILESYSTEM) && HasClipboardData()))
887 DeleteMenu(hmenuDefault, IDM_INSERT, MF_BYCOMMAND);
888 if (!(rfg & SFGAO_CANLINK))
889 DeleteMenu(hmenuDefault, IDM_CREATELINK, MF_BYCOMMAND);
890 if (!(rfg & SFGAO_CANDELETE))
891 DeleteMenu(hmenuDefault, IDM_DELETE, MF_BYCOMMAND);
892 if (!(rfg & SFGAO_CANRENAME) || !(uFlags & CMF_CANRENAME))
893 DeleteMenu(hmenuDefault, IDM_RENAME, MF_BYCOMMAND);
894 if (!(rfg & SFGAO_HASPROPSHEET))
895 DeleteMenu(hmenuDefault, IDM_PROPERTIES, MF_BYCOMMAND);
896
897 idDefaultOffset = idCmdNext;
898 UINT idMax = Shell_MergeMenus(hMenu, GetSubMenu(hmenuDefault, 0), IndexMenu, idCmdNext, idCmdLast, 0);
899 m_iIdDfltFirst = cIds;
900 cIds += idMax - idCmdNext;
901 m_iIdDfltLast = cIds;
902
903 DestroyMenu(hmenuDefault);
904 }
905
906 TryPickDefault(hMenu, idCmdFirst, idDefaultOffset, uFlags);
907
908 // TODO: DFM_MERGECONTEXTMENU_TOP
909
910 return MAKE_HRESULT(SEVERITY_SUCCESS, 0, cIds);
911}
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 207 of file CDefaultContextMenu.cpp.

208 {
209 return IUnknown_QueryService(m_site, svc, riid, ppv);
210 }
REFIID LPVOID * ppv
Definition: atlbase.h:39

◆ SetSite()

HRESULT WINAPI CDefaultContextMenu::SetSite ( IUnknown pUnkSite)
override

Implements IObjectWithSite.

Definition at line 1735 of file CDefaultContextMenu.cpp.

1736{
1737 m_site = pUnkSite;
1738 return S_OK;
1739}

◆ TryPickDefault()

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

Definition at line 785 of file CDefaultContextMenu.cpp.

786{
787 // Are we allowed to pick a default?
788 if ((uFlags & CMF_NODEFAULT) ||
789 ((uFlags & CMF_DONOTPICKDEFAULT) && RosGetProcessEffectiveVersion() >= _WIN32_WINNT_WIN7))
790 {
791 return;
792 }
793
794 // Do we already have a default?
795 if ((int)GetMenuDefaultItem(hMenu, MF_BYPOSITION, 0) != -1)
796 return;
797
798 // Does the view want to pick one?
799 INT_PTR forceDfm = 0;
800 if (SUCCEEDED(_DoCallback(DFM_GETDEFSTATICID, 0, &forceDfm)) && forceDfm)
801 {
802 for (UINT i = 0; i < _countof(g_StaticInvokeCmdMap); ++i)
803 {
804 UINT menuItemId = g_StaticInvokeCmdMap[i].IntVerb + DfltOffset - DCM_FCIDM_SHVIEW_OFFSET;
805 if (g_StaticInvokeCmdMap[i].DfmCmd == forceDfm &&
806 SetMenuDefaultItem(hMenu, menuItemId, MF_BYCOMMAND))
807 {
808 return;
809 }
810 }
811 }
812
813 // Don't want to pick something like cut or delete as the default but
814 // a static or dynamic verb is a good default.
816 SetMenuDefaultItem(hMenu, idCmdFirst, MF_BYCOMMAND);
817}
#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 1278 of file CDefaultContextMenu.cpp.

1280{
1282 HRESULT hr;
1283
1284 if (!m_site)
1285 return E_FAIL;
1286
1287 /* Get a pointer to the shell browser */
1289 if (FAILED(hr))
1290 return hr;
1291
1292 PIDLIST_ABSOLUTE pidl;
1293 hr = SHILCombine(m_pidlFolder, pidlChild, &pidl);
1295 return hr;
1296
1297 hr = psb->BrowseObject(pidl, wFlags & ~SBSP_RELATIVE);
1298 ILFree(pidl);
1299 return hr;
1300}

Referenced by InvokeRegVerb().

Member Data Documentation

◆ m_aKeys

HKEY* CDefaultContextMenu::m_aKeys
private

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

Referenced by EnumerateDynamicContextHandlerForKey().

◆ m_cidl

UINT CDefaultContextMenu::m_cidl
private

◆ m_cKeys

UINT CDefaultContextMenu::m_cKeys
private

Definition at line 143 of file CDefaultContextMenu.cpp.

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

◆ m_DefVerbs

WCHAR CDefaultContextMenu::m_DefVerbs[MAX_PATH]
private

◆ m_DynamicEntries

◆ m_hwnd

HWND CDefaultContextMenu::m_hwnd
private

Definition at line 156 of file CDefaultContextMenu.cpp.

Referenced by _DoCallback(), and Initialize().

◆ m_iIdCBFirst

UINT CDefaultContextMenu::m_iIdCBFirst
private

Definition at line 152 of file CDefaultContextMenu.cpp.

Referenced by InvokeCommand(), and QueryContextMenu().

◆ m_iIdCBLast

UINT CDefaultContextMenu::m_iIdCBLast
private

Definition at line 153 of file CDefaultContextMenu.cpp.

Referenced by InvokeCommand(), and QueryContextMenu().

◆ m_iIdDfltFirst

UINT CDefaultContextMenu::m_iIdDfltFirst
private

Definition at line 154 of file CDefaultContextMenu.cpp.

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

◆ m_iIdDfltLast

UINT CDefaultContextMenu::m_iIdDfltLast
private

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

Referenced by _DoCallback(), and Initialize().

◆ m_pidlFolder

◆ m_pmcb

CComPtr<IContextMenuCB> CDefaultContextMenu::m_pmcb
private

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