Bir kap farklı bağlantıları destekler olmadığını kontrol etme?

oy
1
  • Uygulanan Lavabo Sınıf - COM Server Etkinlik bildirimleri almak için
  • Olay Arayüz kaynaklanmaktadır ıdispatch

Bir sayede bir sorun vardır IConnectionPoint :: Tavsiye çağrısı döndürür E_NOTIMPL . Bunun nedeni olabilir bağlantı noktası - tek bağlantı sağlayan MSDN .

Not:

  • COM Sunucusu dışı süreci
  • Saf C ++ uygulama

DÜZENLE:

S8.tlh : Win32 tipi kütüphanesi S8.tlb C ++ kaynak eşdeğeri:

struct __declspec(uuid(090910c3-28c3-45fe-861d-edcf11aa9788))
IS8SimulationEvents : IDispatch
{

    // Methods:
    HRESULT S8SimulationReset ( );
    HRESULT S8SimulationEndRun ( );
    HRESULT S8SimulationCustomEvent (
        BSTR * TextInfo );
    HRESULT S8SimulationOpened ( );
    HRESULT S8SimulationEndTrial ( );
    HRESULT S8SimulationOEMEvent (
        BSTR * TextInfo );
    HRESULT S8SimulationReadyToClose ( );
    HRESULT S8SimulationUserMessage (
        long * Answer,
        BSTR * TextMsg,
        long ValidAnswers );
};

Uygulanması Sınıf Sink - etkinlik bildirimlerini işlemek için:

class Sink : public IS8SimulationEvents
{
public:
Sink(){
    m_dwRefCount = 0;
};
~Sink(){};
/*
* IS8SimulationEvent interface functions
*/
HRESULT S8SimulationEndTrial()
{
    cout << Simulation complete. << endl;
    return S_OK;;
};

HRESULT S8SimulationOpened()
{
    cout << Simulation open. << endl;
    return S_OK;
};

HRESULT S8SimulationReadyToClose()
{
    cout << Simulation ready to close << endl;
    return S_OK;
};

ULONG STDMETHODCALLTYPE AddRef()
{
    m_dwRefCount++;
    return m_dwRefCount;
};

ULONG STDMETHODCALLTYPE Release()
{
    ULONG l;
    l = m_dwRefCount--;

    if (0 == m_dwRefCount)
    {
        delete this;
    }

    return m_dwRefCount;
};

HRESULT STDMETHODCALLTYPE QueryInterface(
                                        REFIID iid ,
                                        void **ppvObject)
{
    m_dwRefCount++;
    *ppvObject = (void *)this;
    return S_OK;
};

HRESULT STDMETHODCALLTYPE GetTypeInfoCount(UINT *pctinfo)
{
    return E_NOTIMPL;
};

HRESULT STDMETHODCALLTYPE GetIDsOfNames( 
                                        REFIID riid,
                                        LPOLESTR *rgszNames,
                                        UINT cNames,
                                        LCID lcid,
                                        DISPID *rgDispId)
{
    return E_NOTIMPL;
};

HRESULT STDMETHODCALLTYPE GetTypeInfo(
                                    unsigned int iTInfo,
                                    LCID lcid,
                                    ITypeInfo FAR* FAR* ppTInfo)
{
    return E_NOTIMPL;
};

HRESULT STDMETHODCALLTYPE Invoke(
                                DISPID dispIdMember,
                                REFIID riid,
                                LCID lcid,
                                WORD wFlags,
                                DISPPARAMS FAR* pDispParams,
                                VARIANT FAR* pVarResult,
                                EXCEPINFO FAR* pExcepInfo,
                                unsigned int FAR* puArgErr)
{
    HRESULT hresult = S_OK;
    if (pDispParams)
    {
        switch (dispIdMember) {
        case 1:
            return S8SimulationEndTrial();
        case 2:
            return S8SimulationOpened();
        case 3:
            return S8SimulationReadyToClose();
        default:
            return E_NOTIMPL;
        }

    }
    return E_NOTIMPL;
}
private:
    DWORD m_dwRefCount;
public:
void SetupConnectionPoint (IS8Simulation *pis8)
{

    HRESULT hresult;
    IConnectionPointContainer *pContainer = NULL;
    IConnectionPoint *pConnection = NULL;
    IUnknown *pSinkUnk = NULL;
    Sink *pSink = NULL;
    DWORD dwAdvise;

    dwAdvise = 0;

    hresult = pis8->QueryInterface(
                        __uuidof(IConnectionPointContainer),
                        (void **) &pContainer);

    if (SUCCEEDED(hresult))
    {
        cout << IConnectionPointContainer inteface supported. << endl;
    } else {
        cerr << Error: No such interface supported. << endl;
        exit (hresult);
    }

                                    __uuidof(IS8SimulationEvents),
                                    &pConnection); 

    switch (HRESULT_CODE(hresult)) {
        case NOERROR:
            cout << Obtained valid interface pointer. << endl;
            break;
        case E_POINTER:
            cerr << Invalid pointer: the address is not valid. << endl;
            exit (hresult);
            break;
        case CONNECT_E_NOCONNECTION:
            cerr << This connectable object not support the 
                    outgoing interface specified. << endl;
            exit (hresult);
            break;
        case E_UNEXPECTED:
        default:
            cerr << Catastrophic failure. << endl;
            exit (hresult);
            break;
    }

    pContainer->Release();


    hresult = pSink->QueryInterface(
                            __uuidof(IUnknown),
                            (void **)&pSinkUnk);

    if (FAILED(hresult))
    {
        exit (EXIT_FAILURE);
    }

    hresult = pConnection->Advise(
                            pSinkUnk,
                            &dwAdvise);

    switch (HRESULT_CODE(hresult)) {
        case NOERROR:
            cout << The connection has been established and 
                    *dwAdvise has the connection token. << endl;
            break;
        case E_POINTER:
            cerr << Invalid pointer: 
                    the value pSinkUnk or dwAdvise is not valid. << endl;
            exit (hresult);
            break;
        case CONNECT_E_ADVISELIMIT:
            cerr << The connection point has already reached 
                    its limit of connections and cannot accept 
                    any more. << endl;
            exit (hresult);
            break;
        case CONNECT_E_CANNOTCONNECT:
            cerr << The sink does not support the interface 
                    required by this connection point. << endl;
            exit (hresult);
            break;
        case E_NOTIMPL:
            break;
            case E_UNEXPECTED:
            default:
        cerr << Catastrophic failure. << endl;
        exit (hresult);
        break;
    }
    return;
}
};

DÜZENLE:

Uygulanması Iunknown içinde Arayüz Lavabo Sınıf

ULONG STDMETHODCALLTYPE AddRef()
{
    m_dwRefCount++;
    return m_dwRefCount;
};

ULONG STDMETHODCALLTYPE Release()
{
    ULONG l;
    l = m_dwRefCount--;

    if (0 == m_dwRefCount)
    {
        delete this;
    }

    return m_dwRefCount;
};

HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void **ppvObject)
{
    m_dwRefCount++;
    *ppvObject = (void *)this;
    return S_OK;
};

Soru:

  • Bir kap farklı bağlantıları destekler olmadığını kontrol etme?
  • Daha fazla bilgi gerekiyorsa, buna göre yorum lütfen.
Oluştur 26/01/2009 saat 23:28
kaynak kullanıcı
Diğer dillerde...                            


4 cevaplar

oy
1

Tekrar MSDN makalesine okuyunuz.

 Sadece bir arayüz sağlayan bir bağlantı noktası
 E_NOTIMPL dönebilirsiniz DAN IConnectionPoint :: EnumConnections yöntemle
EnumConnections: E_NOTIMPL 
Bağlantı noktası numaralandırma desteklemez.

IConnectionPoint :: Tavsiye cevap için gereklidir

CONNECT_E_ADVISELIMIT

o bağlantı noktası olduğunda zaten bağlantı sınırına ulaştı ve bir daha kabul edemez.

-

Michael

Cevap 27/01/2009 saat 00:39
kaynak kullanıcı

oy
0

AtlAdvise connectionpoint olay lavabonun üzerinde QI aramaya sebep olmalıdır. Bunu QI kaç kere diyebilirsiniz NE veya emin olamaz.

Öneri: Doğru olay arayüzü sorgulanır belirlemek için eventsink böyle bir şeye bakın.

void GuidToString(PTCHAR s, LPGUID piid )
{
_stprintf(s, _T("{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}"),
    piid->Data1, piid->Data2,
    piid->Data3,
    piid->Data4[0], piid->Data4[1],
    piid->Data4[2], piid->Data4[3],
    piid->Data4[4], piid->Data4[5],
    piid->Data4[6], piid->Data4[7]);
    // Outputdebugstr (s)
}

AYRICA olay havuzu QueryInterfacegibi bir şey yapmalıyım

if (iid == IID_IUnknown || iid == IID_AppEvents)
     *ppObj = (AppEvents*)this;

Yani sadece döner doğru bir arayüz.

Cevap 29/01/2009 saat 19:40
kaynak kullanıcı

oy
0

Tavsiye çağrı çağrıldığında COM Kütüphane ıunknown, IMarshall vb gibi pek çok arabirimler için QI çağırır.

Michael MSDN makale hakkında belirttiği gibi, bunun sadece EnumConnections API için değil, Advise için E_NOTIMPL döndüren söylüyor. Ben E_NOTIMPL döndürmek için QI şüpheli. Yani Tavsiye API izlemek için deneyin. Ve QI başarısızlığı hakkında bilmek gelecek.

Cevap 30/01/2009 saat 00:33
kaynak kullanıcı

oy
0

çözüldü:

  • Kullanılması saf C ++
  • yok ATL

Aşağıdaki ile uygulanması arasında QI :

HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void **ppvObject)
{
    if (iid == __uuidof(IUnknown) || iid == __uuidof(IS8SimulationEvents))
    {
        *ppvObject = (IS8SimulationEvents*)this;
    } else {
        *ppvObject = NULL;
        return E_NOINTERFACE;
    }
    m_dwRefCount++;
    return S_OK;
};
Cevap 01/02/2009 saat 12:57
kaynak kullanıcı

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more