ActiveX + Visual C++

Microsoft Windows specific usage questions
Forum rules
Please post only Windows specific questions in this forum category. If you don't know where to post, please read the different forums' rules. Thanks.
MAK
Blank Cone
Blank Cone
Posts: 13
Joined: 26 Dec 2006 16:14
Contact:

ActiveX + Visual C++

Postby MAK » 26 Dec 2006 16:29

Hi.
I'm trying to create video player base on vlc, but i've got some problems
I'm creating vlc activex dynamically

Code: Select all

bStat = m_vlc.CreateControl("VideoLAN.VLCPlugin.1", "", WS_VISIBLE, rc, this, 5000, NULL, FALSE, NULL);
Then i'm getting interface

Code: Select all

CComQIPtr<IVLCControl> pVlc; HRESULT hr = pVlc.CoCreateInstance(CLSID_VLCPlugin);
After that i'm trying to add target

Code: Select all

hr = pVlc->addTarget((BSTR)"C:\\some_file.avi", NULL, VLCPlayListReplace, VLCPlayListEnd);
When compiling this code error appears - Can't convert parametr 2 from int to variant.

Can any one help me to solve this problem

p.s. can somebody send me files (.def, .h, libvlc.lib) to you them with libvlc.dll

Tappen
Cone that earned his stripes
Cone that earned his stripes
Posts: 150
Joined: 30 Oct 2006 07:55

Postby Tappen » 27 Dec 2006 03:05

The 2nd parameter needs to be a zero-length SAFEARRAY of BSTRs wrapped in a VARIANT. I'm sorry but you'll have to look all that stuff up if you want to program ActiveX in C++. It's a giant pain, which is the main reason M$ moved to .Net.

MAK
Blank Cone
Blank Cone
Posts: 13
Joined: 26 Dec 2006 16:14
Contact:

Postby MAK » 27 Dec 2006 13:03

i'd prefer to use c# (.net) too, but problem is .net framework.
the reason is that there are a lot of users that don't want to download ~20mb (.net framework) to use ~200kb program

and can you send me .h, .def files to use with .dll (i can't port it correctly from delphi (VLD)) (or maybe you can help me with it)?

thanks anyway

MAK
Blank Cone
Blank Cone
Posts: 13
Joined: 26 Dec 2006 16:14
Contact:

Postby MAK » 27 Dec 2006 13:58

The 2nd parameter needs to be a zero-length SAFEARRAY of BSTRs wrapped in a VARIANT...
when i'm trying to use something like that (found on forum)

Code: Select all

VARIANT v; long pos = 0; LPSAFEARRAY pSA = SafeArrayCreateVector(VT_VARIANT, 0, 1); _variant_t var(_bstr_t(":file-caching=1000")); SafeArrayPutElement(pSA, &pos, (void FAR *)&var); v.parray = pSA; v.vt = VT_ARRAY;
addTarget fails

Tappen
Cone that earned his stripes
Cone that earned his stripes
Posts: 150
Joined: 30 Oct 2006 07:55

Postby Tappen » 28 Dec 2006 01:43

The following is the code that's handling your 2nd parameter from 0.8.6\activex\vlccontrol.cpp. It's passed in as a variable (VARIANT *options) and converting the SAFEARRAY to an array of C strings (char ***cOptions) of length (int *cOptionCount).

Make a function around this code yourself and try it on your passed in 2nd parameter and hopefully you'll find the problem.

Code: Select all

// array parameter SAFEARRAY *array = V_ISBYREF(options) ? *V_ARRAYREF(options) : V_ARRAY(options); if( SafeArrayGetDim(array) != 1 ) return E_INVALIDARG; long lBound = 0; long uBound = 0; SafeArrayGetLBound(array, 1, &lBound); SafeArrayGetUBound(array, 1, &uBound); // have we got any options if( uBound >= lBound ) { VARTYPE vType; hr = SafeArrayGetVartype(array, &vType); if( FAILED(hr) ) return hr; long pos; // marshall options into an array of C strings if( VT_VARIANT == vType ) { *cOptions = (char **)CoTaskMemAlloc(sizeof(char *)*(uBound-lBound+1)); if( NULL == *cOptions ) return E_OUTOFMEMORY; ZeroMemory(*cOptions, sizeof(char *)*(uBound-lBound+1)); for(pos=lBound; (pos<=uBound) && SUCCEEDED(hr); ++pos ) { VARIANT option; hr = SafeArrayGetElement(array, &pos, &option); if( SUCCEEDED(hr) ) { if( VT_BSTR == V_VT(&option) ) { char *cOption = CStrFromBSTR(codePage, V_BSTR(&option)); (*cOptions)[pos-lBound] = cOption; if( NULL == cOption ) hr = ( SysStringLen(V_BSTR(&option)) > 0 ) ? E_OUTOFMEMORY : E_INVALIDARG; } else hr = E_INVALIDARG; VariantClear(&option); } } } else if( VT_BSTR == vType ) { *cOptions = (char **)CoTaskMemAlloc(sizeof(char *)*(uBound-lBound+1)); if( NULL == *cOptions ) return E_OUTOFMEMORY; ZeroMemory(*cOptions, sizeof(char *)*(uBound-lBound+1)); for(pos=lBound; (pos<=uBound) && SUCCEEDED(hr); ++pos ) { BSTR option; hr = SafeArrayGetElement(array, &pos, &option); if( SUCCEEDED(hr) ) { char *cOption = CStrFromBSTR(codePage, option); (*cOptions)[pos-lBound] = cOption; if( NULL == cOption ) hr = ( SysStringLen(option) > 0 ) ? E_OUTOFMEMORY : E_INVALIDARG; SysFreeString(option); } } } else { // unsupported type return E_INVALIDARG; } *cOptionCount = pos-lBound; if( FAILED(hr) ) { // free already processed elements FreeTargetOptions(*cOptions, *cOptionCount); } } else { // empty array *cOptions = NULL; *cOptionCount = 0; return NOERROR; }

MAK
Blank Cone
Blank Cone
Posts: 13
Joined: 26 Dec 2006 16:14
Contact:

Postby MAK » 29 Dec 2006 08:13

thanx

cioris
Blank Cone
Blank Cone
Posts: 13
Joined: 17 Nov 2006 23:02

Postby cioris » 08 Feb 2007 03:07

are you using Visual C++? if yes, just declare a variable of COleVariant and pass it to the addTarget function.

eido
New Cone
New Cone
Posts: 1
Joined: 13 Feb 2007 15:10

Postby eido » 13 Feb 2007 15:18

Try this.
it will work.

VARIANT vOptions;
long pos=0;
LPSAFEARRAY m_pSA = SafeArrayCreateVector(VT_VARIANT, 0, 1);
_variant_t var(_bstr_t(""));
SafeArrayPutElement(m_pSA, &pos, (void FAR*)&var);

vOptions.parray = m_pSA;
vOptions.vt = VT_NULL ;
long lPos=-666;
long lmode=10;//VLCPlayListReplaceAndGo
m_vlcPlayer.addTarget("c:\\test.avi",vOptions,lmode,lPos);

cioris
Blank Cone
Blank Cone
Posts: 13
Joined: 17 Nov 2006 23:02

Postby cioris » 13 Feb 2007 19:54

nice solution, but I still believe is much simplier to use COleVariant, as long as you need just an "empty" object:

COleVariant var; /* this will do all initializations you need */
m_player.addTarget("file_name",var,CVLCControl::VLCPlayListInsert,-666);

Hope it helps..:)

Quovodis
Cone that earned his stripes
Cone that earned his stripes
Posts: 271
Joined: 16 Jun 2004 11:13
Location: Cork, Ireland

Postby Quovodis » 13 Feb 2007 23:48

for the poor souls who can't use MFC or ATL, just like me, the following will also work

Code: Select all

VARIANT vOptions; VariantInit(&vOptions); // will make vOptions 'empty' long lPos=-666; long lmode=10;//VLCPlayListReplaceAndGo m_vlcPlayer->addTarget("c:\\test.avi",&vOptions,lmode,lPos);

kamo
New Cone
New Cone
Posts: 1
Joined: 14 May 2007 09:11

Postby kamo » 14 May 2007 09:28

I also want other ppl to know how they can get their vlc plugin work under c++ windows enviroment! here's my piece of code:

Code: Select all

// stop vlc if it plays something vlc.stop(); HRESULT hr; SAFEARRAY *pSA; SAFEARRAYBOUND aDim[1]; aDim[0].lLbound= 0; aDim[0].cElements= 2; // create bstr safe array pSA= SafeArrayCreate(VT_BSTR,1,aDim); if (!pSA ) { /// do something here on your own return 0; } BSTR HUGEP *pbstr; hr=SafeArrayAccessData(pSA,(void HUGEP**)&pbstr); if (FAILED(hr)) { // do something to prevent further errors return 0; } // got options? tell vlc activeX about it pbstr[0] = SysAllocString(OLESTR(":vout-filter=deinterlace")); pbstr[1] = SysAllocString(OLESTR(":deinterlace-mode=bop")); SafeArrayUnaccessData(pSA); // well, the vlc.playlistClear(); is not important here, if you want to safe your playlist vlc.playlistClear(); // declare safe array as Variant CComVariant vOptions(pSA); try { // try to add target vlc.addTarget ( trueUrl, vOptions, 1, 0); } catch (...) { // free your safe array // and do something to prevent further errors of your code return 0; } // waiting is a magic, but it works indeed // wait for 2 seconds Sleep(2000); // start playing vlc.play(); // destroy the array SafeArrayDestroy(pSA);
some comments on my ugly code:
--

vlc.addTarget ( trueUrl, vOptions, 1, 0);

you can see 1 here and it's a synonym to AppendUrl. Don't leave it as a digit, use enumerations. Don't forget about error handling anywhere in a code. Replace all 'return 0;' with your error handling.

thanks, and cheers


Return to “VLC media player for Windows Troubleshooting”

Who is online

Users browsing this forum: Google [Bot] and 13 guests