Why is the IMarshall interface requested on the IUserNotificationCallback COM object?

Using IUserNotification2 from Microsoft

I use IUserNotification2 to show a notification to a software user.

I am using an existing implementation from microsoft, see here. (Note, I removed the standard headers and simplified it a bit).

#include <Shobjidl.h> //IUserNotification2 interface header

void NotifyUser(const std::wstring &title,
    const std::wstring &text){
if (!SUCCEEDED(CoInitializeEx(nullptr, COINIT_MULTITHREADED)))
    throw std::exception("could not init COM");

IUserNotification2 * handleNotification = nullptr;
auto result = CoCreateInstance(CLSID_UserNotification, 0, CLSCTX_ALL, IID_IUserNotification2, (void**)&handleNotification);
if (!SUCCEEDED(result) || !handleNotification) {
    throw std::exception("could not create CLSID_UserNotification");
}
DWORD notif_flags = NIIF_RESPECT_QUIET_TIME|NIIF_WARNING;
result = handleNotification->SetBalloonInfo(title.c_str(), text.c_str(), notif_flags);
if (!SUCCEEDED(result))
    throw std::exception("could not SetBalloonInfo of notification");
if (!SUCCEEDED(handleNotification->Show(nullptr, 5000,nullptr))
        throw std::exception("failed Show of notification");

When you do this without callbacks (i, e showing a message without any action on click events), I have no problem and my code works.

Add callback on click event

To add such a callback, you need to pass the IUserNotificationCallbackObject ShowMethod of the object IUserNotification2.

See here. I only changed the call to Show.

Callback cbk;
if (!SUCCEEDED(handleNotification->Show(nullptr, 5000,& cbk)))
        throw std::exception("failed Show of notification");

Callback IUserNotificationCallback. . .

class Callback : public IUserNotificationCallback {
public:
    virtual HRESULT STDMETHODCALLTYPE OnBalloonUserClick(POINT * pt) override {return S_OK;}
    virtual HRESULT STDMETHODCALLTYPE OnContextMenu(POINT * pt) override {}
    virtual HRESULT STDMETHODCALLTYPE OnLeftClick(POINT * pt) override {return S_OK;}

    /// Implementing IUnknown Interface
    virtual ULONG STDMETHODCALLTYPE AddRef()override { return 1; }
    virtual ULONG STDMETHODCALLTYPE Release() override { return 0; }
    virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID inRiid, void ** outAddressOfObjectPointer)override {
        if (outAddressOfObjectPointer) {
            if (inRiid == IID_IUnknown || inRiid == IID_IUserNotificationCallback)
            {
                *outAddressOfObjectPointer = this;
                AddRef();
                return NOERROR;
            }
        }
        *outAddressOfObjectPointer = nullptr;
        return E_NOINTERFACE;
    }
};

,

Show, My IUserNotificationCallback QueryInterface IUnknown. COM. IID_IMarshall, ,

else if (inRiid == IID_IMarshal) {
    printf("interface queried is IMarshall\n");

.

, , IID. E_NOINTERFACE void **.

I show.

notifu, , , , .

-, Roman R.. CoInitializeEx if (!SUCCEEDED(CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED))) !

+4
2

, IID

COM , . , COM- , COM- IUnknown .

, *ppvObject NULL E_NOINTERFACE, , S_OK *ppvObject , IUnknown::Release , .

-, ( ) E_NOINTERFACE.

, . , , , . , , , .

,

*outAddressOfObjectPointer = NULL;
if (inRiid == IID_IUnknown)
{
        printf("interface required is IUnknown\n");
        *outAddressOfObjectPointer = this;
        AddRef();
        return NOERROR;
}
// ...

NULL nullptr . , , : COM, Release , , , .

, ? MTA, COM- CLSID_UserNotification . COM API STA , , . COM, , . , . , . COINIT_APARTMENTTHREADED, .

+3

, , COM IMarshal:

COM IMarshal : (.. ), COM IMarshal. , COM IMarshal -. IMarshal, COM .

, .

QueryInterface, , , IUnknown , , . ( ) E_NOINTERFACE.

  • : QueryInterface . , ++, , this , - , AddRef .

, , IMarshal, .

COM (. comClass clrClass), (. ). - , ProxyStubClsid32 ({00020420-0000-0000- C000-000000000046} aka PSDispatch dispinterface s, {00020424-0000-0000-C000-000000000046} aka PSOAInterface [oleautomation] interfaces), , TypeLib , .

0

All Articles