Joe J
Joe J

Reputation: 359

Calling IContextMenu directly from shell extension dll

I'm trying to call IContextMenu directly from a shell extension DLL but having some trouble.

In general, I do:

  1. Load DLL using LoadLibrary()
  2. Call GetProcAddress() to get address of DllGetClassObject()
  3. Call DllGetClassObject() to get IClassFactory
  4. Call CreateInstance() to get IContextMenu

The first three steps are successful, but the fourth step fails with an E_NOINTERFACE error. The same thing happens if I request IContextMenu2 and IContextMenu3.

Eventually, I want to access IContextMenu and call IContextMenu::QueryContextMenu(). How can I achieve this?

#include <iostream>
#include <combaseapi.h>
#include <shobjidl_core.h>

typedef HRESULT(WINAPI* DllGetClassObjectType)(REFCLSID rclsid, REFIID riid, void** ppv);

int main()
{
    CoInitialize(NULL);

    HMODULE hModule = LoadLibrary(L"C:\\Users\\UserName\\Desktop\\NppShell.dll");
    if (!hModule) {
        std::cout << "LoadLibrary ERR " << GetLastError();
        return 0;
    }

    DllGetClassObjectType DllGetClassObject = (DllGetClassObjectType)GetProcAddress(hModule, "DllGetClassObject");
    if (!DllGetClassObject) {
        std::cout << "DllGetClassObject ERR " << GetLastError();
        return 0;
    }

    CLSID clsid;
    CLSIDFromString(L"{B298D29A-A6ED-11DE-BA8C-A68E55D89593}", &clsid);

    IClassFactory* iFactory;
    HRESULT hr = DllGetClassObject(clsid, IID_IClassFactory, (void**)&iFactory);
    if (!SUCCEEDED(hr)) {
        std::cout << "DllGetClassObject ERR " << GetLastError();
        return 0;
    }

    IContextMenu* cm;
    hr = iFactory->CreateInstance(NULL, IID_IContextMenu, (void**)&cm);
    if (!SUCCEEDED(hr)) {

        std::cout << "CreateInstance ERR " << (hr == E_NOINTERFACE);
        return 0;
    }
}

Upvotes: 0

Views: 127

Answers (0)

Related Questions