Whilst it is good as it strips out all the usual fluff you get with
examples, it unfortunately uses a template that works fine under VS2005 but
doesn't seem to work under VC6 - and I have to use VC6 in this instance.
The template is :-
template <class C, class I> HRESULT STDMETHODCALLTYPE CreateInstance(I** ppv)
{
if(ppv == NULL) return E_POINTER; else *ppv = NULL;
HRESULT hr = S_OK;
C* p = new C(&hr);
if(NULL == p) { hr = E_OUTOFMEMORY; goto exit; }
if(S_OK != hr) goto exit;
if(S_OK != (hr = p->QueryInterface(__uuidof(I),(void**)ppv))) goto exit;
p = NULL;
exit:
if(p) delete p;
return hr;
}
Used in a class def
class __declspec(uuid("{F8DDAE70-63C7-4b38-B7A9-61223765ABA6}"))
CJpegPushSource : public CSource
{
friend HRESULT STDMETHODCALLTYPE
CreateInstance<CJpegPushSource,IBaseFilter>(IBaseFilter** ppv);
....
which gives the errors
error C2143: syntax error : missing ';' before '<'
warning C4229: anachronism used : modifiers on data are ignored
error C2433: 'CreateInstance' : 'friend' not permitted on data declarations
for the line beggining 'friend'.
Problem is I don't quite understand the code so don't know how to replace
the template. Why does it need the 'friend' declaration if it is a function
that is actually inside the class itself ? And if it is being used to create
an instance of the object shouldn't it be static ? Or, is the line just a
function prototype in which case where exactly does the code itself live ?
TTFN,
Jon
> Problem is I don't quite understand the code so don't
> know how to replace the template. Why does it need the
> 'friend' declaration if it is a function that is actually
> inside the class itself ?
It is not a member of the class. The template is istantiated
as a global function, hence the need to declare the template
instance as a friend of the class to give it access to the
private constructor.
> And if it is being used to
> create an instance of the object shouldn't it be static ?
It is global, so it is static.
> Or, is the line just a function prototype in which case
> where exactly does the code itself live ?
The template is defined in utils.h.
Anyway, you do not need the template and you can just expand
it as global function or a static method:
1.
class CJpegPushSource ...
{
...
public: static HRESULT STDMETHODCALLTYPE
CreateInstance(IBaseFilter** ppv)
{
if(ppv == NULL) return E_POINTER; else *ppv = NULL;
HRESULT hr = S_OK;
CJpegPushSource* p = new CJpegPushSource(&hr);
if(NULL == p) { hr = E_OUTOFMEMORY; goto exit; }
if(S_OK != hr) goto exit;
if(S_OK != (hr =
p->QueryInterface(__uuidof(IBaseFilter),(void**)ppv))) goto
exit;
p = NULL;
exit:
if(p) delete p;
return hr;
}
...
};
...CJpegPushSource::CreateInstance(&pSrcFilter)...
2.
HRESULT STDMETHODCALLTYPE CreateJpegPushSource(IBaseFilter**
ppv)
{
if(ppv == NULL) return E_POINTER; else *ppv = NULL;
HRESULT hr = S_OK;
CJpegPushSource* p = new CJpegPushSource(&hr);
if(NULL == p) { hr = E_OUTOFMEMORY; goto exit; }
if(S_OK != hr) goto exit;
if(S_OK != (hr =
p->QueryInterface(__uuidof(IBaseFilter),(void**)ppv))) goto
exit;
p = NULL;
exit:
if(p) delete p;
return hr;
}
class CJpegPushSource ...
{
friend HRESULT STDMETHODCALLTYPE
CreateJpegPushSource(IBaseFilter** ppv);
...
};
...CreateJpegPushSource(&pSrcFilter)...
--
// Alessandro Angeli
// MVP :: DirectShow / MediaFoundation
// mvpnews at riseoftheants dot com
// http://www.riseoftheants.com/mmx/faq.htm
Just a minor update for your sample code.
In 'jpeg2mjpeg.cpp', there is a minor bugette. In 'FillBuffer', the code :-
if(INVALID_HANDLE_VALUE == (hf = CreateFile(fn,.....
{
DWORD rc = GetLastError();
hr = ERROR_NOT_FOUND == rc ? S_FALSE : HRESULT_FROM_WIN32(rc);
'ERROR_NOT_FOUND' should read ERROR_FILE_NOT_FOUND, otherwise on stream
completion you not only get the graph notification EC_COMPLETE but also an
EC_ERROR_ABORT since FillBuffer never returns S_FALSE.
Like I said, only minor, thanks for posting the sample projects, they've
_really_ helped.
TTFN,
Jon
> 'ERROR_NOT_FOUND' should read ERROR_FILE_NOT_FOUND,
Thanks, I'll fix the code. That should teach me not to copy
from old code of mine when I don't really remember what the
macros mean.