Jump to content

How to access the COM Interface of DVB Viewer


meilon

Recommended Posts

Hello,

I try to make an app in c++. I need to get some information like the channel and title of the current tv show, start/stop time and so on. Someone told me, that the COM-Interface is what I need. But now: How can I use it? I never had something to do with COM and and I dont find anything for C++ (Dev-C++ is my IDE)

 

Hope someone can write me a little snippet!

 

-meilon

Link to comment

Hier ein Ausriss aus einem meiner DVBV.Progs.

 

#include <windows.h>
#include <objbase.h>
#include <comutil.h>
#include <stdio.h>
#include <time.h>
#include <locale.h>
#include "initguid.h"

int main( int argc, char *argv[] )
{
 HRESULT  hr;

 VARIANT  varRetVal;
 DISPID   dispID;

 hr = CoInitialize( NULL );
 if ( FAILED( hr ) ) {
MessageBox( NULL, "CoInitialize", "ERROR", MB_OK );
return 2;
 }

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

 IUnknown * pIUnknown;

 hr = GetActiveObject( clsid, NULL, & pIUnknown );
 if ( FAILED( hr ) ) {
MessageBox( NULL, "GetActiveObject", "ERROR", MB_OK );
return 2;
 }

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


 // from IDispatch pointer for IDVBViewer
 //  ... get IDispatch pointer for IEPGManager as EPGManager-property
 //
 IDispatch * pDispatchEPGManager;
 hr = getEPGItemProperty( pIDispatch, L"EPGManager", VT_DISPATCH, & pDispatchEPGManager );
 if ( FAILED( hr ) ) {
MessageBox( NULL, "getEPGItemProperty - EPGManager", "ERROR", MB_OK );
return 4;
 }

 // from IDispatch pointer for IDVBViewer
 //  ... get IDispatch pointer for IChannelCollection as ChannelManager-property
 //
 IDispatch * pDispatchChannelCollection;
 hr = getEPGItemProperty( pIDispatch, L"ChannelManager", VT_DISPATCH, & pDispatchChannelCollection );
 if ( FAILED( hr ) ) {
MessageBox( NULL, "getEPGItemProperty - ChannelManager", "ERROR", MB_OK );
return 4;
 }

 // now all needed from IDVBViewer-Interface is available and pIDispatch can be released
 //
 pIDispatch->Release();

 LPOLESTR szMeth = L"GetAsArray";
 hr = pDispatchEPGManager->GetIDsOfNames( IID_NULL, & szMeth, 1, LOCALE_SYSTEM_DEFAULT, & dispID );
 if ( FAILED( hr ) ) {
MessageBox( NULL, "GetIDsOfNames - GetAsArray", "ERROR", MB_OK );
return 5;
 }

 VARIANT resArray;
 resArray.vt = VT_EMPTY;


 VARIANTARG varg1[ 4 ];

varg1[ 3 ].vt = VT_INT;
varg1[ 3 ].intVal = 0; //28224 + 1073 * 1073;

	varg1[ 1 ].vt = VT_DATE;
varg1[ 1 ].date = 0; // 38580.750000;  //end

	varg1[ 2 ].vt = VT_DATE;
varg1[ 2 ].date = 0; // 38569.750000;

	varg1[ 0 ].vt = VT_VARIANT | VT_BYREF;
varg1[ 0 ].pvarVal = & resArray;


 DISPPARAMS dp20 = { varg1, NULL, 4, 0 };   

 hr = pDispatchEPGManager->Invoke( dispID, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, & dp20, & varRetVal, NULL, NULL );
 if ( FAILED( hr ) ) {

 char b[ 120];
  sprintf( b, "%x", hr );

MessageBox( NULL, "Invoke - GetAsArray", b, MB_OK );
return 4;
 }


 unsigned int cnt = varRetVal.intVal;

 // IChannelCollection as ChannelManager-property
 //
 DISPID dispIDGetChannelname;

 LPOLESTR szMethGetChannelname = L"GetChannelname";
 hr = pDispatchChannelCollection->GetIDsOfNames( IID_NULL, & szMethGetChannelname, 1, LOCALE_SYSTEM_DEFAULT, & dispIDGetChannelname );
 if ( FAILED( hr ) ) {
MessageBox( NULL, "GetIDsOfNames - 6", "ERROR", MB_OK );
return 4;
 }


 VARIANT HUGEP * pvar;
 hr = SafeArrayAccessData( resArray.parray, ( void HUGEP * * ) & pvar );
 if ( FAILED( hr ) ) {
MessageBox( NULL, "SafeArrayAccessData", "ERROR", MB_OK );
return 4;
 }

 ...

 

Wenn Du COM bisher noch nicht programmiert hast solltest Du Dich vorher mit der Materie vertraut machen. Ist nähmlich alles andere als trivial unter C++. Wenn Du C# kannst oder lernen möchtest empfehle ich Dir eine C#-Lösung (oder auch Delphi). Diese Sprachen bieten ein komfortable COM-Unterstützing, so das asich z.B. obiges auf wenige Zeilen reduziert.

 

 

mfG und viel Erfolg erwin

Link to comment

Thanks (This is the English Forum :()

 

The Problem: I can pogramm c++ for free, is there any IDE for C#, which is free? Also, I have to use another part of codes which I'm developing in C++, don't know if I can get it to work in C#

 

-meilon

 

EDIT: Your Code doesn't work in Dev-C++! There is an error with EPG

Compiler: Default compiler
Führt  g++.exe... aus
g++.exe "C:\Temp\C++\main.cpp" -o "C:\Temp\C++\main.exe"	-I"D:\Programme\Dev-cpp\lib\gcc\mingw32\3.4.2\include"  -I"D:\Programme\Dev-cpp\include\c++\3.4.2\backward"  -I"D:\Programme\Dev-cpp\include\c++\3.4.2\mingw32"  -I"D:\Programme\Dev-cpp\include\c++\3.4.2"  -I"D:\Programme\Dev-cpp\include"   -L"D:\Programme\Dev-cpp\lib" 
C:\Temp\C++\main.cpp:3:21: comutil.h: No such file or directory
C:\Temp\C++\main.cpp: In function `int main(int, char**)':
C:\Temp\C++\main.cpp:51: error: `getEPGItemProperty' undeclared (first use this function)
C:\Temp\C++\main.cpp:51: error: (Each undeclared identifier is reported only once for each function it appears in.)

C:\Temp\C++\main.cpp:129: error: expected `}' at end of input

Ausführung beendet

Edited by meilon
Link to comment
Your Code doesn't work in Dev-C++! There is an error with EPG

 

Yes, since its only a code-snippet. You haven't noticed the periods ... at the end of the file.

 

..is there any IDE for C#, which is free?

 

You can download the C#-Express-Version from Microsoft for free. Or you can take the free (open source) SharpDevelop IDE (google it).

 

erwin

Link to comment

Okay, I have downloaded MS C# Express, tried to use this code

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

using DVBViewerServer;

namespace WindowsApplication1
{
public partial class Form1 : Form
{
	public Form1()
	{
		InitializeComponent();
	}

	private void Form1_Load(object sender, EventArgs e)
	{
		DVBViewer dvb = new DVBViewer();
		label1.Text = dvb.EPGManager.EPGNow.Description;
	}
}
}

But it doesn't work. This may come from the fact that I am not that good in COM. I set a reference in the project to the DVBViewerServer.

 

Would you be pleease pleeaase that nice and giv me a little little bit of code in C#?

 

-meilon

 

PS: I like C#, it doesn't seem to be that complicated as C++ is and it is easier to make Forms :(

Link to comment
private void Form1_Load(object sender, EventArgs e)

{

DVBViewer dvb = new DVBViewer();

label1.Text = dvb.EPGManager.EPGNow.Description;

}

 

 

try this:

 

private void Form1_Load(object sender, EventArgs e) {
 DVBViewer dvb = ( DVBViewer ) System.Runtime.InteropServices.Marshal.GetActiveObject( "DVBViewerServer.DVBViewer" );
...

 

and DVBViewer must be running if you start your prog

 

erwin

Link to comment
  • 1 year later...

Working on another LCD support and want to thank erwin for his code snippet that saved me much time figuring out the C++ code from Delphi sources.

 

I still find it handy to access COM via C++ as I am used to it and it has the benefit of not needing to load the .NET framework everytime DVBViewer starts -- resulting in several seconds of delay.

 

Erwins missing getEPGItemProperty might look like this:

 

HRESULT getEPGItemProperty(LPDISPATCH pDispatch, LPOLESTR szProperty, VARTYPE nType, LPDISPATCH *ppDispatchProperty)
{
HRESULT  hr;
DISPID DispId;
hr = pDispatch->GetIDsOfNames( IID_NULL, & szProperty, 1, LOCALE_SYSTEM_DEFAULT, & DispId );
if ( FAILED( hr ) ) {
	return hr;
}

VARIANT vReturn;
vReturn.vt = nType;
vReturn.pdispVal = NULL;
DISPPARAMS dp = { NULL, 0, 0 };
hr = pDispatch->Invoke(DispId, IID_NULL, LOCALE_SYSTEM_DEFAULT, DISPATCH_PROPERTYGET, &dp, &vReturn, NULL, NULL);
if ( FAILED( hr ) ) {
	return hr;
}

*ppDispatchProperty = vReturn.pdispVal;
return S_OK;
}

 

If you have a Visual Studio instead of only a Visual C++ Express and are using Microsoft Foundation Classes, I would recommend you to let Visual Studio create wrapper classes for DVBViewers COM interfaces, which makes things much easier.

Link to comment
  • 1 year later...

Based on the code from this topic I tried to make an epg copy function !

The reason I need this is because some channels contains unwanted language or sometime it doesn't contain no epg at all, via MHW I search for similar channels and copy the epg from these channels.

 

The code runs without an error, but the epg seems to be not inserted in DVBViewer.

 

What is wrong, why isn't it working ? Why is HasEPG needed ? Is it also possible to insert directly into recordingservice via com interface ? An what to do with EventID, what number should be used ? If I Add a few EPGitems at once and then do commit, should then EventID number be increased, should it be unique ?

 

Please help !

 

Kind regards !

 

void CDvbViewerEpgDlg::AddEpgItem()
{
 HRESULT  hr;

 VARIANT  varRetVal;
 DISPID   dispID;
 LPOLESTR szMeth;
 DISPPARAMS dpNoArgs = { NULL, NULL, 0, 0 };

 hr = CoInitialize( NULL );
 if ( FAILED( hr ) ) {
   MessageBox( TEXT("CoInitialize"), TEXT("ERROR"), MB_OK );
   return;
 }

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

 IUnknown * pIUnknown;

 hr = GetActiveObject( clsid, NULL, & pIUnknown );
 if ( FAILED( hr ) ) {
   MessageBox( TEXT("GetActiveObject"), TEXT("ERROR"), MB_OK );
   return;
 }

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

 // from IDispatch pointer for IDVBViewer
 //  ... get IDispatch pointer for IEPGManager as EPGManager-property
 //
 IDispatch * pDispatchEPGManager;
 hr = getInterface( pIDispatch, L"EPGManager", VT_DISPATCH, & pDispatchEPGManager );
 if ( FAILED( hr ) ) {
   MessageBox( TEXT("getInterface - EPGManager"), TEXT("ERROR"), MB_OK );
   return ;
 }

 // now all needed from IDVBViewer-Interface is available and pIDispatch can be released
 //
 pIDispatch->Release();

 ///////////////////////////////////////////////////////////////////////////////////////
 szMeth = L"AddEPG";
 hr = pDispatchEPGManager->GetIDsOfNames( IID_NULL, & szMeth, 1, LOCALE_SYSTEM_DEFAULT, & dispID );
 if ( FAILED( hr ) ) {
   MessageBox( TEXT("GetIDsOfNames - AddItem"), TEXT("ERROR"), MB_OK );
   return ;
 }

   varRetVal.vt = VT_DISPATCH;
   varRetVal.pdispVal = NULL;

 hr = pDispatchEPGManager->Invoke( dispID, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, & dpNoArgs, & varRetVal, NULL, NULL );
 if ( FAILED( hr ) ) {
   return ;
 }
 IDispatch * pDispatchEPGAddBuffer;
 pDispatchEPGAddBuffer = varRetVal.pdispVal;

 ///////////////////////////////////////////////////////////////////////////////////////

 szMeth = L"NewItem";
 hr = pDispatchEPGAddBuffer->GetIDsOfNames( IID_NULL, & szMeth, 1, LOCALE_SYSTEM_DEFAULT, & dispID );
 if ( FAILED( hr ) ) {
   MessageBox( TEXT("GetIDsOfNames - NewItem"), TEXT("ERROR"), MB_OK );
   return ;
 }


   varRetVal.vt = VT_DISPATCH;
   varRetVal.pdispVal = NULL;

 hr = pDispatchEPGAddBuffer->Invoke( dispID, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, & dpNoArgs, & varRetVal, NULL, NULL );
 if ( FAILED( hr ) ) {
   return ;
 }
 IDispatch * pDispatchEPGItem;
 pDispatchEPGItem = varRetVal.pdispVal;

 ///////////////////////////////////////////////////////////////////////////////////////

 //Fill EpgItem: with some dummy data

 szMeth = L"SetEPGEventID";
 hr = pDispatchEPGItem->GetIDsOfNames( IID_NULL, & szMeth, 1, LOCALE_SYSTEM_DEFAULT, & dispID );
 if ( FAILED( hr ) ) {
   MessageBox( TEXT("GetIDsOfNames - SetEPGEventID"), TEXT("ERROR"), MB_OK );
   return ;
 }
 //SID 31200 TID 1091 Eurosport
 VARIANTARG varg2[ 2 ];
 varg2[ 0 ].vt = VT_INT;
 varg2[ 0 ].intVal = 1091; //TransportID
 varg2[ 1 ].vt = VT_INT;
 varg2[ 1 ].intVal = 31200; //ServiceID

 DISPPARAMS dpArgs = { varg2, NULL, 2, 0 };

 varRetVal.vt = VT_NULL;
 varRetVal.pdispVal = NULL;

 hr = pDispatchEPGItem->Invoke( dispID, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, & dpArgs, & varRetVal, NULL, NULL );
 if ( FAILED( hr ) ) {
   return ;
 }
 VARIANTARG varg[ 1 ];
 varg[ 0 ].vt = VT_INT;
 varg[ 0 ].intVal = 0;
 putEPGItemProperty(pDispatchEPGItem, L"Content", varg);

 varg[ 0 ].vt = VT_INT;
 varg[ 0 ].intVal = 0;
 putEPGItemProperty(pDispatchEPGItem, L"Charset", varg);

 varg[ 0 ].vt = VT_INT;
 varg[ 0 ].intVal = 233333; //take something random ??
 putEPGItemProperty(pDispatchEPGItem, L"EventID", varg);

 varg[ 0 ].vt = VT_DATE;
 varg[ 0 ].date = ConvertToDVBDateTime(CTime(2009,10,21,14,0,0,1));
 putEPGItemProperty(pDispatchEPGItem, L"Time", varg);

 varg[ 0 ].vt = VT_DATE;
 varg[ 0 ].date = 0.05;
 putEPGItemProperty(pDispatchEPGItem, L"Duration", varg);

 varg[ 0 ].vt = VT_BSTR;
 varg[ 0 ].bstrVal = L"TEST TEXT";
 putEPGItemProperty(pDispatchEPGItem, L"Event", varg);
 putEPGItemProperty(pDispatchEPGItem, L"Title", varg);
 putEPGItemProperty(pDispatchEPGItem, L"Description", varg);

 ///////////////////////////////////////////////////////////////////////////////////////

 szMeth = L"Add";
 hr = pDispatchEPGAddBuffer->GetIDsOfNames( IID_NULL, & szMeth, 1, LOCALE_SYSTEM_DEFAULT, & dispID );
 if ( FAILED( hr ) ) {
   MessageBox( TEXT("GetIDsOfNames - Add"), TEXT("ERROR"), MB_OK );
   return ;
 }
 VARIANTARG varg1[ 1 ];
 varg1[ 0 ].vt = VT_DISPATCH;
 varg1[ 0 ].pdispVal = pDispatchEPGItem;
 DISPPARAMS dpArgs1 = { varg1, NULL, 1, 0 };

 hr = pDispatchEPGAddBuffer->Invoke( dispID, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, & dpArgs1, NULL, NULL, NULL );
 if ( FAILED( hr ) ) {
   return ;
 }

 ///////////////////////////////////////////////////////////////////////////////////////
 szMeth = L"Commit";

 hr = pDispatchEPGAddBuffer->GetIDsOfNames( IID_NULL, & szMeth, 1, LOCALE_SYSTEM_DEFAULT, & dispID );
 if ( FAILED( hr ) ) {
   MessageBox( TEXT("GetIDsOfNames - Commit"), TEXT("ERROR"), MB_OK );
   return ;
 }

 hr = pDispatchEPGAddBuffer->Invoke( dispID, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, & dpNoArgs, NULL, NULL, NULL );
 if ( FAILED( hr ) ) {
   return ;
 }

}
HRESULT CDvbViewerEpgDlg::getInterface(LPDISPATCH pDispatch, LPOLESTR szProperty, VARTYPE nType, LPDISPATCH *ppDispatchProperty)
{
   HRESULT  hr;
   DISPID DispId;
   hr = pDispatch->GetIDsOfNames( IID_NULL, & szProperty, 1, LOCALE_SYSTEM_DEFAULT, & DispId );
   if ( FAILED( hr ) ) {
       return hr;
   }

   VARIANT vReturn;
   vReturn.vt = nType;
   vReturn.pdispVal = NULL;
   DISPPARAMS dp = { NULL, 0, 0 };
   hr = pDispatch->Invoke(DispId, IID_NULL, LOCALE_SYSTEM_DEFAULT, DISPATCH_PROPERTYGET, &dp, &vReturn, NULL, NULL);
   if ( FAILED( hr ) ) {
       return hr;
   }

   *ppDispatchProperty = vReturn.pdispVal;
   return S_OK;
}
void CDvbViewerEpgDlg::putEPGItemProperty(LPDISPATCH pDispatch, LPOLESTR szProperty, VARIANTARG *pvarg)
{
 HRESULT  hr;
 DISPID DispId;
 DISPID mydispid = DISPID_PROPERTYPUT;

 hr = pDispatch->GetIDsOfNames( IID_NULL, & szProperty, 1, LOCALE_SYSTEM_DEFAULT, & DispId );
 if ( FAILED( hr ) ) {
   MessageBox( TEXT("GetIDsOfNames"), TEXT("ERROR"), MB_OK );
   return ;
 }

 DISPPARAMS dp = { pvarg, &mydispid, 1, 1 };

 hr = pDispatch->Invoke( DispId, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYPUT, & dp, NULL, NULL, NULL );
 if ( FAILED( hr ) ) {
   MessageBox( TEXT("Invoke"), TEXT("ERROR"), MB_OK );
   return ;
 }
}

Link to comment

problem solved ! Needed to use SysAllocString to fill the bstrVal....

 

  varg[ 0 ].vt = VT_BSTR;
 varg[ 0 ].bstrVal = SysAllocString( EPGItem->Event );
 putProperty(pDispatchEPGItem, L"Event", varg);
 varg[ 0 ].bstrVal = SysAllocString( EPGItem->Title );
 putProperty(pDispatchEPGItem, L"Title", varg);
 varg[ 0 ].bstrVal = SysAllocString( EPGItem->Description );
 putProperty(pDispatchEPGItem, L"Description", varg);

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...