سؤال

لقد كتبت خادم COM DLL INPROC بسيط مع كائن COM واحد بسيط. كائن COM ينفذ نقطة اتصال.

أعرف كيفية إنشاء عميل ATL الذي يستمد منه IDispEventImpl, ، ويستخدم خريطة بالوعة لتبسيط هذه العملية.

ولكن ، لأغراض العرض التوضيحي ، أود إنشاء تطبيق وحدة تحكم Win32 يستخدم فئة تستدعي كائن COM البسيط الخاص بي ، ثم يعمل بمثابة حوض نقطة اتصال.

ليس لدي أي فكرة عن كيفية تقديم تنفيذ IDispatch - هل يمكن لشخص ما أن يوصي به وثائق حول هذا ، حيث لا يمكنني العثور على أي (لدي ATL Internals ، لكن هذا لا يبدو أنه يغطي ما أحتاجه).

هذا هو الفصل الذي حصلت عليه بالفعل:

#pragma once
#include <iostream>
using namespace std;

// Because we're implementing a connection points sink (_IPogFarmEvents) 
// in a non-ATL class, we must provide implementations for IUnknown and IDispatch.

class KidWithAPogFarm : public _IPogFarmEvents
{
    private:
        DWORD   m_dwRefCount;
        LONG    m_lNumPogs;

    public:
        KidWithAPogFarm() :
        m_dwRefCount    (0),
        m_lNumPogs  (0)
        {
        }

        ~KidWithAPogFarm()
        {
        }


        // -- IUnknown 
        HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void **ppvObject)
        {
            if (iid == DIID__IPogFarmEvents)
            {
                m_dwRefCount++;
                *ppvObject = (void *)this;
                return S_OK;
            }
            if (iid == IID_IUnknown)
            {
                m_dwRefCount++;
                *ppvObject = (void *)this;
                return S_OK;
            }
            return E_NOINTERFACE;
        }

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

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

            if ( 0 == m_dwRefCount)
                delete this;

            return l;
        }


        // -- IDispatch
        STDMETHODIMP GetTypeInfoCount(UINT *pctinfo)
        {       
            return E_NOTIMPL;
        }

        STDMETHODIMP GetTypeInfo( UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo )
        {
            return E_NOTIMPL;
        }

        STDMETHODIMP GetIDsOfNames(const IID &riid, LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId )
        {
            return E_NOTIMPL;
        }
        STDMETHODIMP Invoke(DISPID dispIdMember, const IID &riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr )
        {
            return E_NOT_IMPL;
        }   

        // -- IAntFarmEvents
        STDMETHODIMP OnFarmCreated(LONG lInitialPopulation)
        {
            m_lNumPogs = lInitialPopulation;

            cout << "The kid has a pog farm with " << m_lNumPogs << " pogs " << endl;
            return S_OK;
        }
};
هل كانت مفيدة؟

المحلول

منذ أن لديك بالفعل ATL يمكنك فحص مصادرها ومعرفة كيف IDispatchImpl يفعل كل هذه الأشياء. IDispatch يتم تنفيذ الأساليب ، هناك قراءة بيانات من مكتبة النوع في نفس الوحدة لأنها الطريقة الأسهل والأكثر موثوقية عند وجود مكتبة من النوع بالفعل.

تجدر الإشارة أيضًا إلى أنه موضوع صعب إلى حد ما لإجراء عرض مظاهرة عليه - ستحتاج إلى كتابة الكثير من التعليمات البرمجية التي لا تجلب أي رؤية. IMO ستكون أفضل حالًا إذا قمت بتطبيق واجهة أحداث لا ترث منها IDispatch بل ترث مباشرة من IUnknown - سيوضح هذا كيف تعمل الأحداث دون سحب الكثير من الاهتمام IDispatch الأعمال الداخلية.

نصائح أخرى

أعتقد أن أسهل طريقة للقيام بذلك createstddispatch

يمكنك استخدام هذه تنفيذ idispatch.

إنه ليس بالضبط ما تبحث عنه ، ولكن نفس ناري يستخدم Idispatchex ونقاط الاتصال لتوفير عنصر تحكم ActiveX يعمل في IE. نظرًا لأن Firebreath عبارة عن تجريد للسماح لكتابة المكونات الإضافية مرة واحدة واستخدامها في جميع المتصفحات الرئيسية ، يجب كتابة واجهة Idispatch باليد - بما في ذلك نقاط الاتصال.

قد يكون الرمز مربكًا بعض الشيء ، نظرًا لوجود فئة Mixin templated المستخدمة لتوفير نقاط Idispatch و Connection لفئتين مختلفتين كائنات COM ، ولكن قد يساعد ذلك.

لقد قبلت بالفعل إجابة ، لكن ربما لا يزال من المفيد. آسف لم أر السؤال عاجلاً.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top