Page 1 of 1
ActiveX + Visual C++
Posted: 26 Dec 2006 16:29
by MAK
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
Posted: 27 Dec 2006 03:05
by Tappen
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.
Posted: 27 Dec 2006 13:03
by MAK
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
Posted: 27 Dec 2006 13:58
by MAK
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
Posted: 28 Dec 2006 01:43
by Tappen
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;
}
Posted: 29 Dec 2006 08:13
by MAK
thanx
Posted: 08 Feb 2007 03:07
by cioris
are you using Visual C++? if yes, just declare a variable of COleVariant and pass it to the addTarget function.
Posted: 13 Feb 2007 15:18
by eido
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);
Posted: 13 Feb 2007 19:54
by cioris
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..
![Smile :)](./images/smilies/icon_smile.gif)
Posted: 13 Feb 2007 23:48
by Quovodis
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);
Posted: 14 May 2007 09:28
by kamo
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