I have a class called ValidatorContextMenuHandler
that implements the IShellExtInit
and IContextMenu
interfaces.
My DLL is being referenced in the Registry, and gets loaded into Windows Explorer correctly. I check this by creating MessageBoxes whenever a method is being called. When I right click on a file, I also get notified of my ContextMenuHandler
being instantiated. So, IShellExtInit::Initialize()
is indeed being called (twice, actually). My implementation of IShellExtInit::Initialize()
looks like the following:
IFACEMETHODIMP ValidatorContextMenuHandler::Initialize(PCIDLIST_ABSOLUTE pidlFolder, IDataObject* pdtobj, HKEY hKeyProgID)
{
MessageBox(NULL, L"ContextMenuHandler Initialized!", L"Notice", MB_OK);
return S_OK;
}
However, after that nothing happens. IContextMenu::QueryContextMenu()
is never being called, and I cannot find the cause. The first line of QueryContextMenu()
should bring up a MessageBox, but it never gets to that point in the first place.
My implementation of the method looks like the following:
STDMETHODIMP ValidatorContextMenuHandler::QueryContextMenu(HMENU hMenu, UINT indexMenu, UINT idCmdFirst, UINT idCmdLast, UINT uFlags)
{
MessageBox(NULL, L"QUERYING CONTEXT MENU", L"ValidatorContextMenuHandler::QueryContextMenu()", MB_OK);
//...Removed the unnecessary code after this, so that the post doesn't get too long
}
There are no compiling errors, and the DLL I tested on is the newest version (unloaded DLL with regsvr32 /u
, restarted Windows Explorer, loaded DLL with regsvr32
).
For those wanting to see my header file:
#pragma once
#include<Windows.h>
#include<ShlObj.h>
extern UINT g_cObjCount;
class ValidatorContextMenuHandler : public IShellExtInit, IContextMenu
{
protected:
DWORD m_ObjRefCount;
~ValidatorContextMenuHandler();
public:
ValidatorContextMenuHandler();
//IUnknown Methods
ULONG __stdcall AddRef();
ULONG __stdcall Release();
HRESULT __stdcall QueryInterface(REFIID riid, void** ppvObject);
//IShellExtInit Methods
IFACEMETHODIMP Initialize(PCIDLIST_ABSOLUTE pidlFolder, IDataObject* pdtobj, HKEY hKeyProgID);
//IContextMenu Methods
IFACEMETHODIMP GetCommandString(UINT_PTR idCmd, UINT uFlags, UINT* pwReserved, LPSTR pszName, UINT cchMax);
STDMETHODIMP InvokeCommand(LPCMINVOKECOMMANDINFO pici);
STDMETHODIMP QueryContextMenu(HMENU hMenu, UINT indexMenu, UINT idCmdFirst, UINT idCmdLast, UINT uFlags);
};
I found out why it wasn't working. A lot of frustration for nothing.
In my ValidatorContextMenuHandler.cpp
file, I did a simple mistake. When queried for the IContextMenu
interface, I accidentally cast this
to IClassFactory
when I should cast it to IContextMenu
. Mistyped it.
Before:
else if (IsEqualIID(riid, IID_IContextMenu))
{
*ppvObject = (IClassFactory*)this;
this->AddRef();
return S_OK;
}
After:
else if (IsEqualIID(riid, IID_IContextMenu))
{
*ppvObject = (IContextMenu*)this;
this->AddRef();
return S_OK;
}