COM: DDiscFormat2DataEvents mit IDiscFormat2Data verknüpfen



  • Hallo zusammen,

    Ich habe ein Problem mit Microsoft's COM. Ich habe leider noch nicht viel damit gemacht, außer vielleicht mal DirectX angeschnitten.
    Momentan versuch ich mit der IMAPI2 eine CD / DVD zu brennen und will von dem Interface gerne auch Rückmeldungen haben.
    Rückmeldungen erfolgen über das DDiscFormat2DataEvents-Interface (erbt von IDispatch und IUnknown) und ich verwende das IDiscFormat2Data-Interface um Daten auf das Medium zu schreiben.

    Die Verknüpfung der beiden Interfaces erledige ich so:
    Ich habe mal die Fehlerbehandlung rausgenommen...

    // pConnectTo = IDiscFormat2Data-Interface
    // riid = IID_DDiscFormat2DataEvents
    // pUnknown = Mein Event Receiver (siehe Unten):
    void connect(IUnknown* pConnectTo, REFIID riid, IUnknown* pUnknown)
    {
    // Container abfragen:
    HRESULT hr = pConnectTo->QueryInterface(IID_IConnectionPointContainer, (void**)&m_connContainer);
    
    // Die Verbindung suchen und das Interface ebenfalls abfragen:
    hr = m_connContainer->FindConnectionPoint(riid, &m_connPoint);
    
    // Verbindung zwischen den beiden Objekten herstellen:
    DWORD cookie;
    hr = m_connPoint->Advise(pUnknown, &cookie);
    
    // Cookie kopieren:
    m_dwCookie = cookie;
    }
    
    // Der Event-Receiver:
    class EventReceiver : public DDiscFormat2DataEvents
    {
    public:
    virtual HRESULT __stdcall Update(IDispatch* object, IDispatch* progress);
    };
    

    Die Verbindung läuft korrekt... 🙂
    Folgendes Problem tritt aber auf bei der kompilierung:

    1>d:\programmierung\c++\projekte\picturemanager\picturemanager\discformatdata.cpp(78) : error C2259: 'DiscFormatData::EventReceiver': Instanz von abstrakter Klasse kann nicht erstellt werden
    1>        aufgrund folgender Member:
    1>        "HRESULT IDispatch::GetTypeInfoCount(UINT *)": ist abstrakt
    1>        c:\program files\microsoft sdks\windows\v6.0a\include\oaidl.h(2081): Siehe Deklaration von 'IDispatch::GetTypeInfoCount'
    1>        "HRESULT IDispatch::GetTypeInfo(UINT,LCID,ITypeInfo **)": ist abstrakt
    1>        c:\program files\microsoft sdks\windows\v6.0a\include\oaidl.h(2084): Siehe Deklaration von 'IDispatch::GetTypeInfo'
    1>        "HRESULT IDispatch::GetIDsOfNames(const IID &,LPOLESTR *,UINT,LCID,DISPID *)": ist abstrakt
    1>        c:\program files\microsoft sdks\windows\v6.0a\include\oaidl.h(2089): Siehe Deklaration von 'IDispatch::GetIDsOfNames'
    1>        "HRESULT IDispatch::Invoke(DISPID,const IID &,LCID,WORD,DISPPARAMS *,VARIANT *,EXCEPINFO *,UINT *)": ist abstrakt
    1>        c:\program files\microsoft sdks\windows\v6.0a\include\oaidl.h(2096): Siehe Deklaration von 'IDispatch::Invoke'
    

    Wie man sieht erstelle ich ja einen Event-Receiver. Diesen kann ich aber nicht instanzieren, weil ich von IDispatch erbe und dieses Interface abstrakte Funktionen hat, die nicht implementiert sind.

    Ist das überhaupt die richtige Lösung mit einem IDispatch-Interface zu verknüpfen? Was müsste ich tun, um das Problem zu lösen?
    Wäre schön, wenn jemand dazu eine Lösung wüsste 🙂

    Liebe Grüße,
    SALOMON



  • Hallo,

    dein Thread ist zwar schon ein paar Monate alt, mich würde trotzdem interessieren ob Du zu einer Lösung gekommen bist. Ich suche auch gerade nach der Möglichkeit IDiskFormat2Data mit DDiscFormat2DataEvents zu verknüpfen (und zwar komplett ohne MFC oder ATL). Diesbezüglich ist sind die Hilfen im Netz recht rar.

    Viele Grüße
    humpalumpa



  • Leider kann ich dir da nich weiterhelfen. Habe das damals abgebrochen, weil ich meine eigentliche brennsoftware wieder in Gang gesetzt hatte - da gabs nen Konflikt mit Windows 7, ist eine etwas längere Geschichte.

    Im Prinzip müsste man sich für das Problem insgesamt mal mehr mit COM beschäftigen, wozu ich allerdings weder Zeit noch Lust habe. Wäre nur mal interessant gewesen, wie man da einen Event-Receiver einsetzt, wenn nicht durch eine Ableitung der Basisklasse.

    Vielleicht hilft dir aber der Beispiel-Code im Windows-SDK. Da gabs auf jeden Fall was... kann mich nur leider nicht mehr genau dran erinnern, weil ich es (wie gesagt) nicht mehr gebraucht habe.

    Wenn du noch was finden solltest, dann würde mich das allerdings auch interessieren! 🙂

    SALOMON



  • Hallo,

    ich hatte genau das gleiche Problem und habe eine Lösung gefunden.

    Der Code von Salomon ist schon richtig und hat mir auch sehr weitergeholfen. Also schonmal vielen Dank dafür! 🙂

    Die Methoden von IUnknown habt ihr ja offenbar schon implementiert. Die fehlenden Methoden von IDispatch müssen allerdings auch selbst implementiert werden. Hier sind meine Implementierungen:

    STDMETHODIMP EventData::GetTypeInfoCount(UINT FAR *pctinfo)
    {
    	*pctinfo = 1;
    
    	return NOERROR;
    }
    
    STDMETHODIMP EventData::GetTypeInfo(UINT itinfo, LCID lcid, ITypeInfo FAR * FAR *pptinfo)
    {
    	*pptinfo = NULL;
    
    	if (itinfo != 0) return ResultFromScode(DISP_E_BADINDEX);
    
    	m_ptinfo->AddRef();
    
    	*pptinfo = m_ptinfo;
    
    	return NOERROR;
    }
    
    STDMETHODIMP EventData::GetIDsOfNames(REFIID riid, OLECHAR FAR * FAR *rgszNames, UINT cNames, LCID lcid, DISPID FAR *rgdispid)
    {
    	return DispGetIDsOfNames(m_ptinfo, rgszNames, cNames, rgdispid);
    }
    
    STDMETHODIMP EventData::Invoke(DISPID dispidMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS FAR *pdispparams, VARIANT FAR *pvarResult, EXCEPINFO FAR *pexcepinfo, UINT FAR *puArgErr)
    {
    	return DispInvoke(this, m_ptinfo, dispidMember, wFlags, pdispparams, pvarResult, pexcepinfo, puArgErr);
    }
    

    Zusätzlich müssen noch die Type-Infos erzeugt werden, was bei mir im Konstruktor der Klasse passiert:

    m_ptinfo   = NULL;
    
    HRESULT		 hr	= 0;
    LPTYPELIB	 ptlib	= NULL;
    
    hr = LoadRegTypeLib(LIBID_IMAPILib2, IMAPILib2_MajorVersion, IMAPILib2_MinorVersion, LOCALE_SYSTEM_DEFAULT, &ptlib);
    
    if (!FAILED(hr))
    {
    	hr = ptlib->GetTypeInfoOfGuid(IID_DDiscFormat2DataEvents, &m_ptinfo);
    
    	ptlib->Release();
    }
    

    Denke das sollte euch weiterhelfen.

    Viele Grüße,
    enzo1982



  • Wow, ich habe ja nicht damit gerechnet, dass noch mal jemand auf das Thema antwortet, gut dass ich das Thema abboniert habe, sodass ich ne Mail bekomme, wenn jemand hier schreibt 😃 Ich hatte das eigentlich schon verworfen und habe die Option "Auf CD brennen" einfach weggelassen.

    Ich habe leider momentan keine Zeit den Code auszuprobieren, aber habe mir die Seite gleich mal abgespeichert - das sieht alles ja sehr vielversprechend aus!

    Vielen Dank dafür! 🙂

    Viele Grüße,
    SALOMON


Anmelden zum Antworten