dbraner Posted April 11, 2009 Share Posted April 11, 2009 Ich versuche gerade in C++ die COM-Events des DVBViewers anzuzapfen. Da ich die MFCs mit Visual Studio verwende, ist die Implementierung im Prinzip recht einfach. Leider komme ich an einer Stelle aber nicht weiter. Mein Client greift per ConnectionPoints auf den DVBViewer zu und legt einen EventSink an. Dazu wird folgende Funktion per IUnknown Pointer auf DVBViewer aufgerufen: IUnk->QueryInterface (IID_IConnectionPointContainer, ...) Dieser Aufruf schlägt fehl, da der DVBViewer diese Schnittstelle anscheinend nicht unterstützt. Kann man dies implementieren? Mache ich was falsch? Gibt es eine andere Methode, per C++ an die Events ranzukommen? Vielleicht könnte einer der Entwickler darauf antworten ... Quote Link to comment
Lars_MQ Posted April 11, 2009 Share Posted April 11, 2009 Leider kann ich Dir da nicht wirklich weiterhelfen. Alle notwendigen Interfaces werden angeboten bzw. implementiert vom DVBViewer. Ich nutze ja genau das gleiche vom DVBViewer spy aus. Quote Link to comment
JMS Posted April 11, 2009 Share Posted April 11, 2009 Ich versuche gerade in C++ die COM-Events des DVBViewers anzuzapfen. Da ich die MFCs mit Visual Studio verwende, ist die Implementierung im Prinzip recht einfach. Leider komme ich an einer Stelle aber nicht weiter. Mein Client greift per ConnectionPoints auf den DVBViewer zu und legt einen EventSink an. Dazu wird folgende Funktion per IUnknown Pointer auf DVBViewer aufgerufen: IUnk->QueryInterface (IID_IConnectionPointContainer, ...) Dieser Aufruf schlägt fehl, da der DVBViewer diese Schnittstelle anscheinend nicht unterstützt. Kann man dies implementieren? Mache ich was falsch? Gibt es eine andere Methode, per C++ an die Events ranzukommen? Vielleicht könnte einer der Entwickler darauf antworten ... Kannst Du mal den vollständigen Beispielcode, der nicht geht, irgendwie anhängen. Espl. inkl. Erzeugen des IUnk, aber auch Datentyp et al. Der Teufel steckt vermutlich im Detail und die eine Zeile hilft für eine Analyse nicht wirklich. Jochen Quote Link to comment
dbraner Posted April 12, 2009 Author Share Posted April 12, 2009 Leider kann ich Dir da nicht wirklich weiterhelfen. Alle notwendigen Interfaces werden angeboten bzw. implementiert vom DVBViewer. Ich nutze ja genau das gleiche vom DVBViewer spy aus. Was genau ist denn der Unterschied zwischen den Interfaces IDVBViewerEvent und IDVBViewerEventhelper? In der COM Doku steht, dass die Property Event von IDVBViewer das Interface IDVBViewerEventhelper liefert. Bei der Erklärung von IDVBViewerEvents steht wiederum, dass dieses Interface ebenfalls über die Property Event abgrefragt werden kann. welches nun von den beiden, und was ist der Zweck? Quote Link to comment
dbraner Posted April 13, 2009 Author Share Posted April 13, 2009 (edited) Kannst Du mal den vollständigen Beispielcode, der nicht geht, irgendwie anhängen. Espl. inkl. Erzeugen des IUnk, aber auch Datentyp et al. Der Teufel steckt vermutlich im Detail und die eine Zeile hilft für eine Analyse nicht wirklich. Jochen Also hier mal mein MFC Beispielcode: CLSID clsid; IUnknown *pIUnknown; CLSIDFromProgID (L"DVBViewerServer.DVBViewer", &clsid); hr = GetActiveObject (clsid, NULL, &pIUnknown); // Jetzt kommt das Problem AfxConnectionAdvise (pIUnknown, IID_IDVBVEventSink, pUnkSink, FALSE, &dwCookie); Wenn ich mit dem Debugger in die Funktion AfxConnectionAdvise reingehe, wird dort als erstes folgendes aufgerufen: pIUnknown->QueryInterface (IID_IConnectionPointContainer, &pCPC); Und dieser Aufruf schlägt fehl. pIUnknown ist gültig. Damit bekomme ich nämlich per Queryinterface auf IID_IDispatch einen funktionierenden Handle für DVBViewer, über das ich z.B. per SendCommand Befehle schicken kann. Anzumerken ist noch, dass die Funktion AfxConnectionAdvise eine interne MFC Funktion ist. Habe ich mir also nicht ausgedacht. Mit MS-Word als COM-Server funktioniert das ganze übrigens ... Edited April 13, 2009 by dbraner Quote Link to comment
JMS Posted April 13, 2009 Share Posted April 13, 2009 Wenn ich die Diskussion in Deinem anderen Thread richtig verstanden habe, ist es auch nicht das Primärobject (DVBViewerServer.DVBViewer), das den Connection Point Container anbietet. Vielmehr musst Du von diesem das Events Object abfragen und dessen Interface als ersten Parameter beim Advise verwenden. Jochen Quote Link to comment
Lars_MQ Posted April 13, 2009 Share Posted April 13, 2009 Du machst kein queryinterface auf das hauptobjekt selber, sondern auf das IDVBViewerEventhelper interface, das Du Dir über IDVBViewer.Events holst , darauf kannst Du dann ein queryinterface auf das IConnectionPointContainer interface machen. Ich musste da erstmal sehr tief in den delphi bibliotheken graben, da das hier alles automatisch angelegt wird... Quote Link to comment
dbraner Posted April 14, 2009 Author Share Posted April 14, 2009 Du machst kein queryinterface auf das hauptobjekt selber, sondern auf das IDVBViewerEventhelper interface, das Du Dir über IDVBViewer.Events holst , darauf kannst Du dann ein queryinterface auf das IConnectionPointContainer interface machen. Ich musste da erstmal sehr tief in den delphi bibliotheken graben, da das hier alles automatisch angelegt wird... Vielen Dank an Euch. Damit funktioniert die Abfrage des ConnectionPointContainers. Als nächstes wird nun für den Container die Funktion FindConnectionPoint() aufgerufen. Dabei wird eine IID übergeben. Ich hab nur keine Ahnung welche. In der Doku zur Funktion steht "Ein Verweis auf die IID der Ausgangsschnittstelle, deren Verbindungspunkt angefragt wird". Welche IID ist gemeint? IID_IDVBViewer, IID_IEventHelper, ...? Wenn ich das noch habe, müsste es eigentlich funktionieren. Quote Link to comment
Lars_MQ Posted April 14, 2009 Share Posted April 14, 2009 DIID_IDVBViewerEvents müsste das sein, wenn ich das heir richtig interpretiere... Quote Link to comment
dbraner Posted April 14, 2009 Author Share Posted April 14, 2009 So nach dem letzten Tipp von Lars läuft der Verbindungsaufbau in meinem Programm durch, d.h. die Funktion AfxConnectionAdvise findet zunächst den ConnectionpointContainer und danach auch einen ConnectionPoint. Nach der reinen Microsoft MFC Lehre müsste nun alles funktionieren, siehe auch http://support.microsoft.com/default.aspx?...kb;en-us;181845 Bei MS-Word tut auch alles. Nur meine DVBViewer Eventroutinen werden leider trotzdem nicht aufgerufen Ich werde mal morgen einen etwas größeren Code-Ausschnitt posten. Vielleicht fällt ja jemandem der entscheindende Fehler auf. Ich hab so das Gefühl es passt fast alles und das ganze braucht nur noch einen Tritt ... Quote Link to comment
dbraner Posted April 15, 2009 Author Share Posted April 15, 2009 (edited) Hier nun der etwas auführlichere Code Ausschnitt. Ich bin vorgegangen wie in http://support.microsoft.com/default.aspx?...kb;en-us;181845 beschrieben, d.h. eine neue Klasse CDVBVEventSink abgeleitet von CCmdTarget angelegt, die die Events vom DVBViewer empfangen soll. Die Implementierung der Klasse sieht im wesentlichen so aus: BEGIN_DISPATCH_MAP(CDVBVEventSink, CCmdTarget) DISP_FUNCTION_ID(CDVBVEventSink, "OnChannelChange", 0xc9, OnChannelChange, VT_EMPTY, VTS_I4) DISP_FUNCTION_ID(CDVBVEventSink, "OnAction", 0xd2, OnAction, VT_EMPTY, VTS_I4) END_DISPATCH_MAP() static const IID IID_IDVBVEventSink = { 0x017FD4A8, 0x5E00, 0x4DF8, { 0xA3, 0x88, 0x43, 0x4B, 0x8E, 0x59, 0x2C, 0xC4 } }; BEGIN_INTERFACE_MAP(CDVBVEventSink, CCmdTarget) INTERFACE_PART(CDVBVEventSink, IID_IDVBVEventSink, Dispatch) END_INTERFACE_MAP() void CDVBVEventSink::OnAction (long ActionId) { ::AfxMessageBox ("OnAction"); } void CDVBVEventSink::OnChannelChange (long ChannelNo) { ::AfxMessageBox ("OnChannelChange"); } Hier bin ich am überlegen, ob die IID korrekt ist. In der MS-Doku heißt es, man soll die IID angeben, die vom COM OBject-Spy beim Typelib Eintrag des Servers (DVBViewer) angezeigt wird. Das ist eben die oben angegebene. Im eigentlichen Programm wird dann die Verbindung zum DVBViewerEvent-Interface per Connectionpoints aufgebaut. Die Klasse DVBViewer ist eine Wrapper Klasse für das DVBViewer-Interface, die von Visualstudio automatisch erzeugt wurde und einem das Leben etwas erleichtert. Zusätzlich wird noch ein Object der EventSink-Klasse (s.o.) erzeugt: CDVBViewer m_DVBViewer; CDVBVEventSink m_DVBVEventSink; DWORD m_dwCookie; HRESULT hr; CLSID clsid; IUnknown *pIUnknown; IDispatch *pIDispatch; IID IID_IDVBViewerEvents = { 0xB397FB16, 0xA027, 0x4D5B, { 0x88, 0xEB, 0xFD, 0x9A, 0x2A, 0xA2, 0x8D, 0x92 }}; CLSIDFromProgID (L"DVBViewerServer.DVBViewer", &clsid); hr = GetActiveObject (clsid, NULL, &pIUnknown); if (SUCCEEDED (hr)) { hr = pIUnknown->QueryInterface (IID_IDispatch, (void **) &pIDispatch); pIUnknown->Release (); if (SUCCEEDED (hr)) { m_DVBViewer.AttachDispatch (pIDispatch); if (AfxConnectionAdvise (m_DVBViewer.get_Events (), IID_IDVBViewerEvents, m_DVBVEventSink.GetIDispatch (FALSE), FALSE, &m_dwCookie)) ::AfxMessageBox ("Advise successful"); else ::AfxMessageBox ("Advise failed"); } else ::AfxMessageBox ("Can't get DVBV IDispatch"); } else ::AfxMessageBox ("Can't get DVBV IUnknown"); Dieser Code läuft fehlerfrei durch, d.h. die Verbindung zwischen meinem EventSink und dem DVBViewerEvent-Interface wird per Connectionpoint hergestellt. Der einzige Haken: Meine Eventhandler Funktionen werden niemals aufgerufen. Fällt jemandem dazu was ein? Ist die ganz oben definierte IID korrekt? Edited April 22, 2009 by dbraner Quote Link to comment
dbraner Posted April 24, 2009 Author Share Posted April 24, 2009 (edited) So wie ich die Sache sehe, werden wir bzgl. Dvb script: funktioniert PHP: funktioniert, aber im Browser nicht praktikabel anwendbar Edited April 24, 2009 by dbraner Quote Link to comment
dbraner Posted April 24, 2009 Author Share Posted April 24, 2009 (edited) irgendwie funktioniert das posten hier nicht mehr. Das board zerstört meine posts Edited April 24, 2009 by dbraner Quote Link to comment
erwin Posted May 11, 2009 Share Posted May 11, 2009 Dieser Code läuft fehlerfrei durch, d.h. die Verbindung zwischen meinem EventSink und dem DVBViewerEvent-Interface wird per Connectionpoint hergestellt. Der einzige Haken: Meine Eventhandler Funktionen werden niemals aufgerufen.Fällt jemandem dazu was ein? Ist die ganz oben definierte IID korrekt? Hallo, bin wieder zurück. MFC ist nicht so mein Ding. Aber zum IDispatch-Interface gehört auch GetIDsOfNames. Hast Du dies mal aus-implementiert? Könnte mir vorstellen dass das DVBV/Delphi-Framework sich zuerst eine ID für OnChannelChange über GetIDsOfNames besorgt und mit dieser dann in das Invoke geht. mfg erwin Quote Link to comment
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.