Jump to content

c++ anfang


c-o-m-m-a-n-d-e-r

Recommended Posts

konnte das problem noch immer nicht in den griff bekommen :biggrin:

Link to comment

Mhhh die Edit Funktion ist zu schnell weg.... :biggrin: sorry für das Multiposting!!

 

Wollte nur mal Zeigen wie weit ich bin!

Wenn jetzt wie gesagt das OnChangeHandle klappt könnte ich mein Plugin finalisieren!

 

 

92e8e174a64648c9e7a9a093a2fdf283.jpg

Link to comment
ich probier gerade

 

events->OnChannelChange += gcnew DVBViewerServer::IDVBViewerEvents_OnChannelChangeEventHandler(&CdvbtestDlg::ChChange);

 

bekomme aber nen Compilererror

 

Error 1 error C3364: 'DVBViewerServer::IDVBViewerEvents_OnChannelChangeEventHandler' : invalid argument for delegate constructor; delegate target needs to be a pointer to a member function

 

Was mache ich falsch ?

 

Mach mal den Adressoperator & vor der Funktion CdvbtestDlg::ChChange weg. Es wird ein Funktionszeiger erwartet. Die Funktion sollte trotzdem static sein. Bei mir geht das. Deine Funktion sollte so deklariert sein:

 

class CdvbtestDlg
{
...
public:
  static void ChChange (int ChannelNo);
...
};

 

Nochmal meinen Dank an erwin. Sensationell :bye:

 

Dafür gibts ein Krönchen :tongue:

Edited by dbraner
Link to comment

sensationell und schon gehts...ich werd bekloppt :tongue:

 

Vielen Dank!

 

 

Dann hab ich jetzt noch eine abschliessende Frage. Wenn ich das ganze jetzt als DLL schreiben möchte, steigt der DVBViewer automatisch in die main der DLL ein oder wie ist das? Da bin ich noch nicht ganz hinter gestiegen!

 

Kann mir das noch einer erklären? :bye: Das wäre Klasse

Link to comment

kurios, im betrieb mit nem DVB-T device gings, jetzt zuhause wo ich weiterentwickel (und via Unicast übern den Server) den DVBViewer Betreibe, gehts nicht mehr....er bekommt einfach das OnChangeEvent nicht mit...der dvbspy aber auch nicht immer...

 

 

 

EDIT : jetzt ging es gerade wieder...komisch, ich glaub wenn man einmal nen error verursacht muss man den DVBViewer neu starten sonst sendet der das nicht mehr, der spy bekam das nämlich auch nicht mehr mit danach!

Edited by c-o-m-m-a-n-d-e-r
Link to comment
kurios, im betrieb mit nem DVB-T device gings, jetzt zuhause wo ich weiterentwickel (und via Unicast übern den Server) den DVBViewer Betreibe, gehts nicht mehr....er bekommt einfach das OnChangeEvent nicht mit...der dvbspy aber auch nicht immer...

EDIT : jetzt ging es gerade wieder...komisch, ich glaub wenn man einmal nen error verursacht muss man den DVBViewer neu starten sonst sendet der das nicht mehr, der spy bekam das nämlich auch nicht mehr mit danach!

 

Der DVBViewer scheint etwas sensibel zu reagieren, wenn im Eventhandler für OnChannelChange zuviel Zeit verbraten wird. Ich habe dort mal eine Messagebox anzeigen lassen und habe mir mit dem OK drücken Zeit gelassen. Das mochte der DVBViewer gar nicht.

 

Zum Thema DLL: Der DVBiewer wird lediglich aktiv, wenn es sich um ein Plugin handelt. Siehe dazu SDK.

Link to comment

Jepp der ist da echt fix pissig.....das merk ich auch!

 

 

Also als DLL gehts nicht wie ich es jetzt mache oder wie ??

Link to comment
Jepp der ist da echt fix pissig.....das merk ich auch!

Also als DLL gehts nicht wie ich es jetzt mache oder wie ??

 

Eine Plugin-DLL muss bestimmte Funktionen exportieren, die im SDK beschrieben sind. Kannst Du Dir in der Membersarea runterladen. Dazu gibts auch eine Doku, was diese Funktionen machen. erwin hat in folgendem Post in diesem Thread ein Grundgerüst für eine solche DLL gepostet:

 

http://www.DVBViewer.info/forum/index.php?...st&p=242940

 

Ich habe selbst noch kein Plugin geschrieben. Warum möchtest Du denn unbedingt eine DLL entwickeln? Ein normales Programm tut es doch auch. Du musst nur dafür sorgen, dass es automatisch gestartet wird.

Link to comment

ja sein gerüst aber ich natürlich gesehen, ich dachte aber ich könnte auch mit dem COM eine DLL bauen!? Die SDK etc hab ich alles hier liegen :bye:

 

 

Wieso DLL ? Mhhh weils einfacher ist die DLL einmal da in den Ordner zu schubsen und sich dann um nix mehr kümmern müssen denk ich... ausserdem nervts mich wenn ich etwas anfange und dann nicht hinbekomme...Möchte so gut es geht immer verstehen was ich da überhaupt mache :bye:

Link to comment

So hatte gestern abend als ich so im Bett lag ne Vermutung wieso der bei mir immer abgekackt ist wenn er den funktion aufgerufen hat.

Gerade ausgetestet und siehe da daran lags :bye:

 

Ich hatte noch ein

 

CDC *pDC = this->GetDC();

 

um mir das Bild was ich ans LCD schicke noch auf dem Dialog anzuzeigen....den mehrfachaufruf mochte er nicht :bye: Nehm ich das raus klappts...

Jetzt nur noch die Sache mit der DLL klären dann bin ich mehr als glücklich..

Link to comment
So hatte gestern abend als ich so im Bett lag ne Vermutung wieso der bei mir immer abgekackt ist wenn er den funktion aufgerufen hat.

Gerade ausgetestet und siehe da daran lags :bye:

 

Ich hatte noch ein

 

CDC *pDC = this->GetDC();

 

um mir das Bild was ich ans LCD schicke noch auf dem Dialog anzuzeigen....den mehrfachaufruf mochte er nicht :bye: Nehm ich das raus klappts...

Jetzt nur noch die Sache mit der DLL klären dann bin ich mehr als glücklich..

 

Bei der Eventbehandlung solltest Du immer darauf achten, dass Du mit der Abarbeitung eines Events fertig bist, bevor der nächste kommt. Sonst könnten die sich ins Gehege kommen (wenn Dein Programm nicht gerade jeden Event in einem eigenen Thread handelt).

 

Ich habe das so gelöst: Wenn ein Event kommt, setze ich im Programm nur ein Flag und gehe wieder aus der Eventfunktion raus. Dann wird Timer gesteuert alle x Sekunden vom Programm nachgeschaut, welche Eventflags gesetzt sind und die entsprechenden Routinen aufgerufen. Danach wird das Flag auf 0 gesetzt. Dadurch werden mehrerer aufeinanderfolgende Events vom gleichen Typ (kommt z.B. bei OnPlaystateChange vor) ignoriert bzw. es wird nur der erste betrachtet.

Link to comment

ich fang nur das eine event ab, das ist nicht das Problem :bye:;)

 

Das mit dem OnChangeEvent klappt jetzt genau wie ich das möchte :bye:

 

 

Ich muss jetzt lediglich noch das mit der DLL hinbekommen, wobei ich zusätzlich überleg das ganze erstmal als Tool fertig zu proggen...

 

Hab das auch zum Teil schon zum laufen gebracht mit DLL, wenn ich auf erwins basis aufbaue! Nur wäre das natürlich geil wenn ich dann mit dem jetzigen NET Konstrukt weiter machen könnte!

 

EDIT : ach ja dbraner: wenn ich das probier wie von dir beschrieben auf seite 1 mit der wrapper klasse...bekomme ich beim Kompilieren einen Fehler

 

Error 1 error C3803: 'IMatchPtr IFreeDB_HTTP::Matchlist[]': property has a type which is incompatible with one of its accessors 'long IFreeDB_HTTP::GetMatchlist(VARIANT *)' e:\c++\l4mdvblcd\l4mdvblcd\debug\DVBViewer.tlh 2846 l4mdvblcd

 

*grübel*

Edited by c-o-m-m-a-n-d-e-r
Link to comment
  • 2 months later...

Sorry wenn ich den Thread nun Mißbrauche, aber der Titel passt halt exakt zu meiner Frage :blush:

 

Ich möchte unbedingt auch mal ein Plugin via dll schreiben, habe aber imense Startschwierigkeiten (bräuchte mal ein Erfolgserlebnis). Ich hatte mich mal in den letzten Tagen an Delphi versucht, bekomme auch die Beispiele kompiliert, würde aber lieber mit c++ eines Erstellen. Finde erwins Headerdatei genial und Danke, daß Du die hier zur Verfügung stellst, aber ich habe Probleme beim Erstellen der-C Datei. Beim nachprogrammieren des Menu Beispiels aus dem pluginsrc Beispiel bleibe ich bei der Stelle, wo es um das Hinzufügen des Menues hängen. In Delphi lautet die Prozedur:

Ich verstehe z.B. nicht, wo hInstance herkommt.

 

procedure SetMenuHandle(Menu:HMenu);stdcall;
var Handle:HMenu;
begin
Handle:= CreateMenu;
InsertMenu(Handle, $FFFFFFFF,
			  (MF_BYPOSITION or MF_POPUP or MF_ENABLED),
			  LoadMenu(hInstance,'EXTERN'),PluginName);
InsertMenu(Menu, $FFFFFFFF,
			  (MF_BYPOSITION or MF_POPUP or MF_ENABLED),
			  Handle,PluginName);
end;

 

Hat vielleicht jemand ein paar Zeilen Code oder ein Beispiel cpp Project um entweder einen Menueintrag im DVBViewer zu erzeugen, oder einen Hauptmenueeintrage (wie z.B. das MyPrograms Demo ?

 

Ich tue mich dabei sehr schwer das zu verstehen, da ich seit Jahren in c# Programmiere. :wacko:

 

Danke im Vorraus für die Bemühungen

 

Gruß

Carsten

Link to comment
Beim nachprogrammieren des Menu Beispiels aus dem pluginsrc Beispiel bleibe ich bei der Stelle, wo es um das Hinzufügen des Menues hängen. Ich verstehe z.B. nicht, wo hInstance herkommt.

Hat vielleicht jemand ein paar Zeilen Code oder ein Beispiel cpp Project um entweder einen Menueintrag im DVBViewer zu erzeugen, oder einen Hauptmenueeintrage (wie z.B. das MyPrograms Demo ?

 

In C++ kannst Du folgendermaßen einen Menüeintrag hinzufügen:

 

#include <windows.h>

...

void __stdcall SetMenuHandle(HMENU Menu)
{
HMENU 	myMenu = CreateMenu();
AppendMenu(myMenu, MF_STRING, MY_MENU_ID, "Mein Plugin");
InsertMenu(Menu, 0, MF_BYPOSITION | MF_POPUP | MF_ENABLED, (UINT) myMenu , "Mein Plugin");
}

 

Bitte hierzu alles Relevante nachlesen:

 

http://msdn.microsoft.com/en-us/library/ms...28VS.85%29.aspx

 

Viel Erfolg!

Stefan.

Edited by Rayman
Link to comment

Rayman hat Dir ja schon geholfen. Trotzdem noch wg. der Vollständigkeit ein paar Tipps zu hInstance. Dabei handelt es sich um ein Handle zur Instanz Deines Programms oder Deiner DLL. Wenn Du MFC verwendest, kannst Du Dir dieses Handle mit der Funkton AfxGetInstanceHandle() besorgen. hInstance wird aber auch an die beiden Hauptfunktionen WinMain() und DLLMain() beim Aufruf durch das Betriebssystem übergeben. Du kannst Dir den Wert dann einfach in einer globalen Variablen merken und bei Bedarf verwenden. Aus diversen Gründen würde ich davon abraten, den oft in Tipps genannten Aufruf GetModuleHandle (NULL) zu verwenden. Das kann funktionieren, muss aber nicht.

Link to comment
  • 1 year later...

Hi Forum, ich hänge mich mal hier dran. bin mich gerade auch bzgl. COM Schnittstelle am einlesen/rumspielen. Ich nutze Visual C# Express 2010. Kann auch dank diesem Thread schön mit der COM Schnittstelle hantieren indem ich sie folgendermaßen besorge:

DVBViewer dvb = (DVBViewer)System.Runtime.InteropServices.Marshal.GetActiveObject("DVBViewerServer.DVBViewer");

 

Allerdings würde ich auch gerne den DVBViewer starten wenn er noch nicht läuft. Im Eventghost zum Beispiel gibt es auch die Funktion "Start DVBViewer". Von daher muss es ja irgendwie funktionieren.

 

Ich habe folgendes probiert:

DVBViewer dvb = new DVBViewer();

Damit startet der DVBViewer auch aber ich habe anschließend keine Kontrolle über COM.

Vielleicht hat jemand Erfahrung damit bzw. kann einen Tip geben?

 

Happy Coding und Gruß!

 

ViperXXL

Link to comment

Hi Forum, ich hänge mich mal hier dran. bin mich gerade auch bzgl. COM Schnittstelle am einlesen/rumspielen. Ich nutze Visual C# Express 2010. Kann auch dank diesem Thread schön mit der COM Schnittstelle hantieren indem ich sie folgendermaßen besorge:

DVBViewer dvb = (DVBViewer)System.Runtime.InteropServices.Marshal.GetActiveObject("DVBViewerServer.DVBViewer");

 

Allerdings würde ich auch gerne den DVBViewer starten wenn er noch nicht läuft. Im Eventghost zum Beispiel gibt es auch die Funktion "Start DVBViewer". Von daher muss es ja irgendwie funktionieren.

 

Ich habe folgendes probiert:

DVBViewer dvb = new DVBViewer();

Damit startet der DVBViewer auch aber ich habe anschließend keine Kontrolle über COM.

Vielleicht hat jemand Erfahrung damit bzw. kann einen Tip geben?

 

Happy Coding und Gruß!

 

ViperXXL

Hi,

 

ich denke du musst nach erfolgreichem? Start trotzdem nochmal das COM Objekt anfordern.

Link to comment
  • 8 months later...

Hi zusammen,

 

bin gerade dran in C# eine Anzeige für meinen USB Monitor zu stricken.

Kann mir jemand nen Tipp geben wie ich die Senderlogos über die DVBViewerServer.dll bekomme??

Habe alle anderen Daten auslesen können. Nur die Logos fehlen noch :(

 

Ist das mal fertig fehlt nur noch die Sachen bzgl. den Aktualisieren bei Senderwechsel UND die Sachen mit den Threads. Das Event OnChanelChange hab ich schon eingebaut. Jedoch sagt VS10 dass das Label schon von einem anderen Thread verwendet wird.

 

:biggrin: :biggrin: Für Tipps wäre ich echt dankbar. :biggrin: :biggrin:

Link to comment

Was macht die DVBViewerServer.dll nochmal? :wacko:

 

Der Pfad zum Logo steht auf jedem Fall im Datamanager (#channellogo).

Was es da so alles gibt kannst du dir über den Helfer "DVBViewer Spy" anschauen.

 

Das zweite Problem hab ich jetzt nicht verstanden.

Scheint mir aber an deinem Programm zu liegen? :biggrin:

Link to comment

Hey super danke. DVBViewer Spy schaue ich mir gleich mal an.

 

Ja, das 2te Ding ist eher ne Programmiersache. Hat nicht direkt was mit dem DVBViewer zu tun. Aber ohne ne Lösung geht mein Prog leider nicht.

Also: Ich hab ne Funktion welche mir alle Labels in meiner Anzeige aktualisiert. Diese Funktion möchte ich beim Senderwechsel aufrufen. Das Event für einen Senderwechsel habe ich gefunden. Jedoch sagt mir VisualStudio beim Senderwechsel, dass meine labels welche ich neu befüllen möchte schon von einem anderen Thread benutzt werden.

Link to comment

Hm? Was du dort siehst ist das DVBV COM Objekt mit den verschiedenen "Funktionen".

Aus dem Datamanger kannst du mit "get_value" die dort angebotenen Werte auslesen.

 

IDatamanager.Get_value(#channellogo)

Edited by nuts
Link to comment

Ist das mal fertig fehlt nur noch die Sachen bzgl. den Aktualisieren bei Senderwechsel UND die Sachen mit den Threads. Das Event OnChanelChange hab ich schon eingebaut. Jedoch sagt VS10 dass das Label schon von einem anderen Thread verwendet wird.

Die Information ist etwas knapp, ich rate einfach mal: aus dem OnChannelChange greifst Du auf ein UI Element zu, e.g. label1.Text = "Moin" und dabei gibt es eine Meldung, dass irgendwas mit dem Thread falsch ist? UI Elemente dürfen nur vom UI Thread benutzt werden, das Event kann aber irgendwo her kommen. Bei WinForms gibt es auf der Form eine InvokeRequired Eigenschaft. Meldet die true, so musst Du den Aufruf via (Begin)Invoke auf den UI Thread umlenken. Unter WPF ähnlich, aber anders. Vielleicht reicht das ja als Recherche Hinweis.

 

Jochen

Link to comment
  • 3 months later...

Hallo,

 

ich möchte dieses schon etwas ältere Thema nochmal "reaktivieren", und zwar im Hinblick auf die Plugin-Entwicklung.

 

Gibt es irgendwo ein Beispiel für ein Plugin in C++? Optimal wäre, wenn eine Visual-Studio Projektdatei dabei wäre.

 

Ich habe immer nur Bruchstücke und einzelne Code-Schnipsel in einigen Beiträgen gefunden.

 

Ich möchte erst mal ein primitives Dummy-Plugin mit C++ zum Laufen bekommen.

 

EDIT: Hat sich erledigt. Habe erwins Wrapper gefunden. Schau mir das erst mal an. Scheint auch C++ zu unterstützen

Edited by dbraner
Link to comment

War das nicht ein C#/C++ Mix der im freien C++ von Micosoft nicht durchlaeuft?

 

 

Hat zwar nichts mit dem Thema zu tun, aber das "kleine" Delphi kostet jetzt unter 200 U$ oder evtl. Euro. Ist nicht wenig aber auch nicht mehr 800 Euro.

 

Klar ware ein Beispielcode welcher in MinGW kompiliert natuerlich das Beste.

Link to comment

Hat zwar nichts mit dem Thema zu tun, aber das "kleine" Delphi kostet jetzt unter 200 U$ oder evtl. Euro. Ist nicht wenig aber auch nicht mehr 800 Euro.

mpiliert natuerlich das Beste.

 

Ich fand schon beim Studium die Pascal-Vorlesung langweilig und überflüssig. Da werde ich auf meine alten Tage nicht mehr damit anfangen. :bounce:

 

Irgendwann wird es hoffentlich mal eine Art Framework für C++ geben. Noch besser wäre eine Plugin-Script-Schnittstelle mit Python, wie sie z.B. XBMC anbietet.

Link to comment

Ich fand schon beim Studium die Pascal-Vorlesung langweilig und überflüssig. Da werde ich auf meine alten Tage nicht mehr damit anfangen. :bounce:

 

Irgendwann wird es hoffentlich mal eine Art Framework für C++ geben. Noch besser wäre eine Plugin-Script-Schnittstelle mit Python, wie sie z.B. XBMC anbietet.

 

:D Ich find sie alle langweilig. Vermutlich weil ich noch aelter bin :P Jedenfalls geht mir der ganze OO Mist maechtig auf den S..., was ich aber inzwischen meinem Alterstarrsinn zuschreibe :) Ich muss den Muell in 10 Jahren nicht mehr debuggen. Da bin ich tot oder in Rente.

 

Ohne interne Kenntnisse wirst du aber kaum mehr als den Wortschatz von VB Skripten ausreizen koennen. Und dann ist die Sprache wieder voellig egal.

 

 

Ich denke Phyton ist der falsche Ansatz. LUA mit XML verheiratet ist meiner Meinung nach besser. Nimm mal World of Warcraft. Das ist, technisch betrachtet, auch nur ein DirectX Video mit einem OSD. Es hat deutlich mehr Benutzerinteraktion (Datenein- und ausgabe) als ein Multimedia Programm. Getestet von 10 Millionen usern und es gibt so um die 10.000 addons. Da muss ich das Rad nicht neu erfinden.

Link to comment
  • 1 month later...

Also, ich benutze die mitgelieferten Wrapper-Klassen und werde nicht so recht glücklich damit. Spätestens beim Beenden Hängt sich der DVBViewer auf. Hier mein Code:

 

	m_pDVBDisp = GetDVBInterface();
if (m_pDVBDisp) m_pDvbv = new CDVBViewer(m_pDVBDisp);
...
...
			if (m_pDvbv->isDVD())
			{
				CString csName = "DVD Playback";
				TextEx(&dcMem, 0, 10, 128, 58, csName.GetBuffer(0));
			}
			else if (m_pDvbv->isMediaplayback())
			{
				CString csName = "Media Playback";
				TextEx(&dcMem, 0, 10, 128, 58, csName.GetBuffer(0));
			}
			else
			{
				csText.Format("#%d", m_pDvbv->get_CurrentChannelNr());
				TextEx(&dcMem, 56, -2, 99, 12, csText.GetBuffer(0));
/*
				CChannelItem *pChannel = new CChannelItem(m_pDvbv->get_CurrentChannel());
				if (pChannel)
				{
					CString csName = pChannel->get_Name();
					TextEx(&dcMem, 0, 32, 128, 64, csName.GetBuffer(0));

					delete pChannel;
				}
*/
				CEPGManager *pEPGMan = new CEPGManager(m_pDvbv->get_EPGManager());
				if (pEPGMan)
				{
					CEPGItem *pEPGItem = new CEPGItem(pEPGMan->get_EPGNow());
					if (pEPGItem)
					{
						// title of currently broadcasted show
						CString csName = pEPGItem->get_Title();
						TextEx(&dcMem, 0, 10, 128, 58, csName.GetBuffer(0));

						// compute progress bar position for show
						SYSTEMTIME st;

						DATE start = pEPGItem->get_Time();
						COleDateTime olestart(start);
						olestart.GetAsSystemTime(st);
						CTime ctStart(st);

						DATE end = pEPGItem->get_EndTime();
						COleDateTime oleend(end);
						oleend.GetAsSystemTime(st);
						CTime ctEnd(st);

						CTime ctNow = CTime::GetCurrentTime();
						CTimeSpan ctsExpired = ctNow - ctStart;
						CTimeSpan ctsDuration = ctEnd - ctStart;
						pos1000 = (int)((LONGLONG)1000 * ctsExpired.GetTotalSeconds() / ctsDuration.GetTotalSeconds());
						if (pos1000 < 0) pos1000 = 0;
						if (pos1000 > 1000) pos1000 = 1000;

						delete pEPGItem;
					}

					delete pEPGMan;
				}
			}

 

Also bis inklusive m_pDvbv->get_CurrentChannelNr() funktioniert noch alles problemlos. Aber sobald ich mir den EPGManager hole wird DVBViewer instabil. Ich würde gern vermeiden das alles mit IDispatch zu Fuß zu machen. Habe ich hier irgendwas falsch falsch verstanden? Reference counts etc. müssten ja im Wrapper gemanaged werden. Vielleicht fällt ja jemandem was sofort ins Auge...

 

Übrigens habe ich noch ein Problem: Ich möchte DVBViewer beim Start durch das Plugin maximieren, aber das maximierte Fenster erscheint einfach nur in voller Bildschirmgröße mit der linken oberen Ecke da, wo vorher das nicht-maximierte Fenster war. Das sieht dann so aus:

 

post-45827-0-72500400-1330000185_thumb.jpg

 

Beide Aufrufe hier führen zum selben Ergebnis:

	::PostMessage(GetParent()->m_hWnd, WM_SYSCOMMAND, SC_MAXIMIZE , 0);
::PostMessage(GetParent()->m_hWnd, 0xb2c2, 0x0815, 105); 

 

Ich denke, meim Maximieren mit SendMessage 0815 müsste in DVBViewer die Fensterposition noch auf 0,0 zurückgesetzt werden... any workaround?

 

Zuguterletzt: Wie stelle ich es an, die Abspielposition bei CD- oder DVD-Wiedergabe über COM herauszukriegen?

 

1000dank für jeden Hinweis schonmal!

Link to comment
Übrigens habe ich noch ein Problem: Ich möchte DVBViewer beim Start durch das Plugin maximieren

Fragt sich, welches Handle du mit GetParent erhälst. Probiere es mal mit FindWindow('TfrmMain','DVBViewer'). Das funktioniert hier in einer separaten EXE in beiden Fällen.

Link to comment

Fragt sich, welches Handle du mit GetParent erhälst. Probiere es mal mit FindWindow('TfrmMain','DVBViewer'). Das funktioniert hier in einer separaten EXE in beiden Fällen.

 

Danke für den Hinweis!

 

In einer separaten EXE funktioniert es auch bei mir. Hmmm.... Ich hab den Code dann mal zeitverzögert per OnTimer Event ausgeführt und das funktioniert. Man muss DVBViewer wohl erstmal etwas Zeit geben bis er komplett initialisiert ist, schätze ich.

 

Irgendwelche Ideen zu den anderen Fragen?

Link to comment
  • 5 months later...

Update:

 

So, ich habs jetzt für mich rausgetüftelt. Im Wesentlichen war das Problem, dass man nicht die CDVBViewer Funktionen wie get_DataManager() benutzen darf, um sich die Spezial-Interfaces zu holen. Stattdessen geht es nur auf dem Zahnfleisch gerobbt (andere Wrapper-Funktionen wie get_CurrentChannelNr(), die keinen Dispatch-Pointer liefern, gehen problemlos):

 

LPDISPATCH GetDataManagerInterface()
{
HRESULT hr;
//hr = getItemProperty(  m_pDVBDisp, L"DataManager", VT_DISPATCH, & pDispatchDataManager  );  <-- doesn't work

DISPPARAMS dispparams = { NULL, NULL, 0, 0 };
OLECHAR FAR szMember[12];
MultiByteToWideChar(CP_ACP, 0, "DataManager", -1, szMember, 12);
OLECHAR FAR *pszMember = szMember;

VARIANT vRet;
EXCEPINFO excepinfo;
UINT nArgErr;
dispparams.rgvarg = NULL;
dispparams.cArgs = 0;
dispparams.cNamedArgs = 0;

DISPID dispid;
hr = m_pDVBDisp->GetIDsOfNames(IID_NULL, &pszMember, 1, LOCALE_SYSTEM_DEFAULT, &dispid);
if ( FAILED( hr ) ) {
	AfxMessageBox("Unable to get dispid of DataManager" );
}
else
{
	hr = m_pDVBDisp->Invoke(dispid/*0xf8*/, IID_NULL, LOCALE_SYSTEM_DEFAULT, DISPATCH_PROPERTYGET, &dispparams, &vRet, &excepinfo, &nArgErr);
	if ( FAILED( hr ) || vRet.vt != VT_DISPATCH ) {
		AfxMessageBox("Unable to get IDataManager Dispatch" );
	}
	else
	{
		return vRet.pdispVal;			
	}
}

return NULL;
}

 

Zuvor muss natürlich noch das Haupt-Interface, wie von erwin beschrieben, in m_pDVBDisp geholt werden:

 

LPDISPATCH GetDVBInterface()
{
 HRESULT  hr;

 VARIANT  varRetVal;
 DISPID   dispID;

 // Translate server ProgID into a CLSID. ClsidFromProgID
 // gets this information from the registry.
 //
 CLSID clsid;
 CLSIDFromProgID( L"DVBViewerServer.DVBViewer", & clsid );

 IUnknown * pIUnknown = NULL;

 hr = GetActiveObject( clsid, NULL, & pIUnknown );
 if ( FAILED( hr ) ) {
   AfxMessageBox("GetActiveObject failed");
   return NULL;
 }

 // get IDispatch pointer for IDVBViewer
 //
 IDispatch * pIDispatch;
 hr = pIUnknown->QueryInterface( IID_IDispatch, ( void * * ) & pIDispatch );
 pIUnknown->Release();
 if ( FAILED( hr ) ) {
   AfxMessageBox("QueryInterface( IID_IDispatch ... ) failed");
   return NULL;
 }

 return pIDispatch;
}

 

Aufruf also in etwa so:

 

	// COM initialisieren
hr = CoInitialize( NULL );
if ( FAILED( hr ) ) {
	AfxMessageBox("CoInitialize failed");
	return FALSE;
}

...
...
// Dispatch-Pointer holen und Wrapper-Klassen damit beleben
m_pDVBDisp = GetDVBInterface();
if (m_pDVBDisp) 
{
	m_pDvbv = new CDVBViewer(m_pDVBDisp);
	m_pDispatchDataManager = GetDataManagerInterface();
	if (m_pDispatchDataManager) m_pDataManager = new CDataManager(m_pDispatchDataManager);
}
...
...
// Hier m_pDvbv und m_pDataManager Wrapper-Klassen benutzen um Daten abzufragen, z.B.
CString percentage = m_pDataManager->get_Value(m_pDvbv->isMediaplayback() ? "#percentage" : "#TV.Now.Percentage");
int nr = m_pDvbv->get_CurrentChannelNr();
...
...
// Wrapper-Klassen zerstören und Dispatch-Pointer releasen
if (m_pDvbv) delete m_pDvbv;
m_pDvbv = NULL;
m_pDVBDisp->Release();

if (m_pDataManager) delete m_pDataManager;
m_pDataManager = NULL;
m_pDispatchDataManager->Release();
...
...
// Bei COM abmelden
CoUninitialize();

 

Zwar nicht ganz so einfach wie mit einem .NET Programm, aber für ein schlankes DVBViewer-Plugin, das nicht erstmal sekundenlang ein Framework laden muss, ist man mit unmanaged C++ meiner Meinung nach besser beraten.

Link to comment

Die Wrapper Klassen funktionieren. Ich verwende in meinem Beispiel (im PDF Kapitel 2.3) auch die Funktion get_Datamanager. Da musst Du an anderer Stelle einen Fehler haben, der zum Absturz führt.

 

Versuch doch mal, das DispInterface nicht beim Erzeugen des Objekts zu übergeben. Du legst einfach ein "leeres" Objekt an, holst Dir das Interface und weist es mit der Methode AttachDispatch() Deinem Objekt zu. Natürlich darfst Du das Aufräumen nicht vergessen. Das geht mit DetachDispatch().

Edited by dbraner
Link to comment

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...