meilon Posted August 8, 2006 Share Posted August 8, 2006 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 Quote Link to comment
erwin Posted August 9, 2006 Share Posted August 9, 2006 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 Quote Link to comment
meilon Posted August 9, 2006 Author Share Posted August 9, 2006 (edited) 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 August 9, 2006 by meilon Quote Link to comment
erwin Posted August 9, 2006 Share Posted August 9, 2006 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 Quote Link to comment
meilon Posted August 9, 2006 Author Share Posted August 9, 2006 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 Quote Link to comment
erwin Posted August 9, 2006 Share Posted August 9, 2006 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 Quote Link to comment
meilon Posted August 9, 2006 Author Share Posted August 9, 2006 Big Thankx! I Hope that you won't have to hear from me soon ;D Quote Link to comment
tmielke Posted May 14, 2008 Share Posted May 14, 2008 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. Quote Link to comment
brutus Posted October 21, 2009 Share Posted October 21, 2009 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 ; } } Quote Link to comment
brutus Posted October 23, 2009 Share Posted October 23, 2009 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); 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.