ReactOS 0.4.15-dev-8064-gdaf8068
CDefaultContextMenu Class Reference
Inheritance diagram for CDefaultContextMenu:
Collaboration diagram for CDefaultContextMenu:

Public Member Functions

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

Private Member Functions

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

Private Attributes

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

Additional Inherited Members

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

Detailed Description

Definition at line 83 of file CDefaultContextMenu.cpp.

Constructor & Destructor Documentation

◆ CDefaultContextMenu()

CDefaultContextMenu::CDefaultContextMenu ( )

Definition at line 175 of file CDefaultContextMenu.cpp.

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

◆ ~CDefaultContextMenu()

CDefaultContextMenu::~CDefaultContextMenu ( )

Definition at line 198 of file CDefaultContextMenu.cpp.

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

Member Function Documentation

◆ _DoCallback()

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

Definition at line 260 of file CDefaultContextMenu.cpp.

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

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

◆ AddShellExtensionsToMenu()

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

Definition at line 462 of file CDefaultContextMenu.cpp.

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

Referenced by QueryContextMenu().

◆ AddStaticContextMenusToMenu()

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

Definition at line 491 of file CDefaultContextMenu.cpp.

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

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

Referenced by QueryContextMenu().

◆ AddStaticEntry()

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

Definition at line 274 of file CDefaultContextMenu.cpp.

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

Referenced by AddStaticEntriesForKey().

◆ BrowserFlagsFromVerb()

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

Definition at line 1154 of file CDefaultContextMenu.cpp.

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

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

Referenced by InvokeCommand().

◆ DoCopyToMoveToFolder()

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

Definition at line 990 of file CDefaultContextMenu.cpp.

991{
992 HRESULT hr = E_FAIL;
993 if (!m_pDataObj)
994 {
995 ERR("m_pDataObj is NULL\n");
996 return hr;
997 }
998
999 CComPtr<IContextMenu> pContextMenu;
1000 if (bCopy)
1001 hr = SHCoCreateInstance(NULL, &CLSID_CopyToMenu, NULL,
1002 IID_PPV_ARG(IContextMenu, &pContextMenu));
1003 else
1004 hr = SHCoCreateInstance(NULL, &CLSID_MoveToMenu, NULL,
1005 IID_PPV_ARG(IContextMenu, &pContextMenu));
1007 return hr;
1008
1010 hr = pContextMenu->QueryInterface(IID_PPV_ARG(IShellExtInit, &pInit));
1012 return hr;
1013
1014 hr = pInit->Initialize(m_pidlFolder, m_pDataObj, NULL);
1016 return hr;
1017
1018 if (bCopy)
1019 lpici->lpVerb = "copyto";
1020 else
1021 lpici->lpVerb = "moveto";
1022
1023 return pContextMenu->InvokeCommand((LPCMINVOKECOMMANDINFO)lpici);
1024}
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 887 of file CDefaultContextMenu.cpp.

888{
889 if (!m_cidl || !m_pDataObj)
890 return E_FAIL;
891
893 HRESULT hr = m_psf->CreateViewObject(NULL, IID_PPV_ARG(IDropTarget, &pDT));
895 return hr;
896
898
899 return S_OK;
900}
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 1028 of file CDefaultContextMenu.cpp.

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

Referenced by InvokeCommand().

◆ DoDelete()

HRESULT CDefaultContextMenu::DoDelete ( LPCMINVOKECOMMANDINFOEX  lpcmi)
private

Definition at line 902 of file CDefaultContextMenu.cpp.

903{
904 if (!m_cidl || !m_pDataObj)
905 return E_FAIL;
906
910 return hr;
911
912 DWORD grfKeyState = (lpcmi->fMask & CMIC_MASK_SHIFT_DOWN) ? MK_SHIFT : 0;
913 SHSimulateDrop(pDT, m_pDataObj, grfKeyState, NULL, NULL);
914
915 return S_OK;
916}
HRESULT CRecyclerDropTarget_CreateInstance(REFIID riid, LPVOID *ppvOut)

Referenced by InvokeCommand().

◆ DoOpenOrExplore()

HRESULT CDefaultContextMenu::DoOpenOrExplore ( LPCMINVOKECOMMANDINFOEX  lpcmi)
private

Definition at line 881 of file CDefaultContextMenu.cpp.

882{
884 return E_FAIL;
885}
#define UNIMPLEMENTED
Definition: debug.h:118

Referenced by InvokeCommand().

◆ DoPaste()

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

Definition at line 828 of file CDefaultContextMenu.cpp.

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

970{
972
973 // We are asked to run the default property sheet
974 if (hr == S_FALSE)
975 {
977 }
978
979 return hr;
980}
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:2597
#define S_FALSE
Definition: winerror.h:2357

Referenced by InvokeCommand().

◆ DoRename()

HRESULT CDefaultContextMenu::DoRename ( LPCMINVOKECOMMANDINFOEX  lpcmi)
private

Definition at line 941 of file CDefaultContextMenu.cpp.

942{
944 HRESULT hr;
945
946 if (!m_site || !m_cidl)
947 return E_FAIL;
948
949 /* Get a pointer to the shell browser */
952 return hr;
953
955 hr = psb->QueryActiveShellView(&lpSV);
957 return hr;
958
959 SVSIF selFlags = SVSI_DESELECTOTHERS | SVSI_EDIT | SVSI_ENSUREVISIBLE | SVSI_FOCUSED | SVSI_SELECT;
960 hr = lpSV->SelectItem(m_apidl[0], selFlags);
962 return hr;
963
964 return S_OK;
965}

Referenced by InvokeCommand().

◆ DoUndo()

HRESULT CDefaultContextMenu::DoUndo ( LPCMINVOKECOMMANDINFOEX  lpcmi)
private

Definition at line 983 of file CDefaultContextMenu.cpp.

984{
985 ERR("TODO: Undo\n");
986 return E_NOTIMPL;
987}
#define E_NOTIMPL
Definition: ddrawi.h:99

Referenced by InvokeCommand().

◆ EnumerateDynamicContextHandlerForKey()

BOOL CDefaultContextMenu::EnumerateDynamicContextHandlerForKey ( HKEY  hRootKey)
private

Definition at line 398 of file CDefaultContextMenu.cpp.

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

1459{
1460 /* We don't handle the help text yet */
1461 if (uFlags == GCS_HELPTEXTA ||
1462 uFlags == GCS_HELPTEXTW ||
1463 HIWORD(idCommand) != 0)
1464 {
1465 return E_NOTIMPL;
1466 }
1467
1468 UINT CmdId = LOWORD(idCommand);
1469
1470 if (!m_DynamicEntries.IsEmpty() && CmdId >= m_iIdSHEFirst && CmdId < m_iIdSHELast)
1471 {
1472 idCommand -= m_iIdSHEFirst;
1474 if (!pEntry)
1475 return E_FAIL;
1476
1477 idCommand -= pEntry->iIdCmdFirst;
1478 return pEntry->pCM->GetCommandString(idCommand,
1479 uFlags,
1480 lpReserved,
1481 lpszName,
1482 uMaxNameLen);
1483 }
1484
1485 if (!m_StaticEntries.IsEmpty() && CmdId >= m_iIdSCMFirst && CmdId < m_iIdSCMLast)
1486 {
1487 /* Validation just returns S_OK on a match. The id exists. */
1488 if (uFlags == GCS_VALIDATEA || uFlags == GCS_VALIDATEW)
1489 return S_OK;
1490
1491 CmdId -= m_iIdSCMFirst;
1492
1493 POSITION it = m_StaticEntries.FindIndex(CmdId);
1494
1495 if (it == NULL)
1496 return E_INVALIDARG;
1497
1499
1500 if (uFlags == GCS_VERBW)
1501 return StringCchCopyW((LPWSTR)lpszName, uMaxNameLen, pEntry->Verb);
1502
1503 if (uFlags == GCS_VERBA)
1504 {
1505 if (SHUnicodeToAnsi(pEntry->Verb, lpszName, uMaxNameLen))
1506 return S_OK;
1507 }
1508
1509 return E_INVALIDARG;
1510 }
1511
1512 //FIXME: Should we handle callbacks here?
1513 if (m_iIdDfltFirst != m_iIdDfltLast && CmdId >= m_iIdDfltFirst && CmdId < m_iIdDfltLast)
1514 {
1515 CmdId -= m_iIdDfltFirst;
1516 /* See the definitions of IDM_CUT and co to see how this works */
1517 CmdId += DCM_FCIDM_SHVIEW_OFFSET;
1518 }
1519
1520 /* Loop looking for a matching Id */
1521 for (UINT i = 0; i < _countof(g_StaticInvokeCmdMap); i++)
1522 {
1523 if (g_StaticInvokeCmdMap[i].IntVerb == CmdId)
1524 {
1525 /* Validation just returns S_OK on a match */
1526 if (uFlags == GCS_VALIDATEA || uFlags == GCS_VALIDATEW)
1527 return S_OK;
1528
1529 /* Return a copy of the ANSI verb */
1530 if (uFlags == GCS_VERBA)
1531 return StringCchCopyA(lpszName, uMaxNameLen, g_StaticInvokeCmdMap[i].szStringVerb);
1532
1533 /* Convert the ANSI verb to unicode and return that */
1534 if (uFlags == GCS_VERBW)
1535 {
1536 if (SHAnsiToUnicode(g_StaticInvokeCmdMap[i].szStringVerb, (LPWSTR)lpszName, uMaxNameLen))
1537 return S_OK;
1538 }
1539 }
1540 }
1541
1542 return E_INVALIDARG;
1543}
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 1085 of file CDefaultContextMenu.cpp.

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

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

◆ GetSite()

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

Definition at line 1640 of file CDefaultContextMenu.cpp.

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

◆ HandleMenuMsg()

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

Implements IContextMenu2.

Definition at line 1547 of file CDefaultContextMenu.cpp.

1551{
1552 /* FIXME: Should we implement this as well? */
1553 return S_OK;
1554}

◆ HandleMenuMsg2()

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

Implements IContextMenu3.

Definition at line 1594 of file CDefaultContextMenu.cpp.

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

◆ Initialize()

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

Definition at line 212 of file CDefaultContextMenu.cpp.

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

◆ InvokeCommand()

HRESULT WINAPI CDefaultContextMenu::InvokeCommand ( LPCMINVOKECOMMANDINFO  lpcmi)
override

Implements IContextMenu.

Definition at line 1344 of file CDefaultContextMenu.cpp.

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

◆ InvokePidl()

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

Definition at line 1218 of file CDefaultContextMenu.cpp.

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

Referenced by InvokeRegVerb().

◆ InvokeRegVerb()

HRESULT CDefaultContextMenu::InvokeRegVerb ( LPCMINVOKECOMMANDINFOEX  lpcmi)
private

Definition at line 1264 of file CDefaultContextMenu.cpp.

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

Referenced by InvokeCommand().

◆ InvokeShellExt()

HRESULT CDefaultContextMenu::InvokeShellExt ( LPCMINVOKECOMMANDINFOEX  lpcmi)
private

Definition at line 1138 of file CDefaultContextMenu.cpp.

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

Referenced by InvokeCommand().

◆ IsShellExtensionAlreadyLoaded()

BOOL CDefaultContextMenu::IsShellExtensionAlreadyLoaded ( REFCLSID  clsid)
private

Definition at line 344 of file CDefaultContextMenu.cpp.

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

Referenced by LoadDynamicContextMenuHandler().

◆ LoadDynamicContextMenuHandler()

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

Definition at line 358 of file CDefaultContextMenu.cpp.

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

Referenced by EnumerateDynamicContextHandlerForKey().

◆ MapVerbToCmdId()

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

Definition at line 1105 of file CDefaultContextMenu.cpp.

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

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

◆ QueryService()

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

Implements IServiceProvider.

Definition at line 161 of file CDefaultContextMenu.cpp.

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

◆ SetSite()

HRESULT WINAPI CDefaultContextMenu::SetSite ( IUnknown pUnkSite)
override

Implements IObjectWithSite.

Definition at line 1632 of file CDefaultContextMenu.cpp.

1633{
1634 m_site = pUnkSite;
1635 return S_OK;
1636}

◆ TryPickDefault()

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

Definition at line 700 of file CDefaultContextMenu.cpp.

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

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

Referenced by InvokeRegVerb().

Member Data Documentation

◆ m_aKeys

HKEY* CDefaultContextMenu::m_aKeys
private

Definition at line 97 of file CDefaultContextMenu.cpp.

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

◆ m_apidl

PCUITEMID_CHILD_ARRAY CDefaultContextMenu::m_apidl
private

◆ m_bGroupPolicyActive

DWORD CDefaultContextMenu::m_bGroupPolicyActive
private

Definition at line 100 of file CDefaultContextMenu.cpp.

Referenced by EnumerateDynamicContextHandlerForKey().

◆ m_cidl

UINT CDefaultContextMenu::m_cidl
private

◆ m_cKeys

UINT CDefaultContextMenu::m_cKeys
private

Definition at line 98 of file CDefaultContextMenu.cpp.

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

◆ m_DynamicEntries

◆ m_hwnd

HWND CDefaultContextMenu::m_hwnd
private

Definition at line 111 of file CDefaultContextMenu.cpp.

Referenced by _DoCallback(), and Initialize().

◆ m_iIdCBFirst

UINT CDefaultContextMenu::m_iIdCBFirst
private

Definition at line 107 of file CDefaultContextMenu.cpp.

Referenced by InvokeCommand(), and QueryContextMenu().

◆ m_iIdCBLast

UINT CDefaultContextMenu::m_iIdCBLast
private

Definition at line 108 of file CDefaultContextMenu.cpp.

Referenced by InvokeCommand(), and QueryContextMenu().

◆ m_iIdDfltFirst

UINT CDefaultContextMenu::m_iIdDfltFirst
private

Definition at line 109 of file CDefaultContextMenu.cpp.

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

◆ m_iIdDfltLast

UINT CDefaultContextMenu::m_iIdDfltLast
private

Definition at line 110 of file CDefaultContextMenu.cpp.

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

◆ m_iIdSCMFirst

UINT CDefaultContextMenu::m_iIdSCMFirst
private

◆ m_iIdSCMLast

UINT CDefaultContextMenu::m_iIdSCMLast
private

◆ m_iIdSHEFirst

UINT CDefaultContextMenu::m_iIdSHEFirst
private

◆ m_iIdSHELast

UINT CDefaultContextMenu::m_iIdSHELast
private

◆ m_pDataObj

◆ m_pfnmcb

LPFNDFMCALLBACK CDefaultContextMenu::m_pfnmcb
private

Definition at line 93 of file CDefaultContextMenu.cpp.

Referenced by _DoCallback(), and Initialize().

◆ m_pidlFolder

◆ m_pmcb

CComPtr<IContextMenuCB> CDefaultContextMenu::m_pmcb
private

Definition at line 92 of file CDefaultContextMenu.cpp.

Referenced by _DoCallback(), and Initialize().

◆ m_psf

CComPtr<IShellFolder> CDefaultContextMenu::m_psf
private

◆ m_site

◆ m_StaticEntries


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