我刚写了一个简单的 DirectShow过滤器(继承自CTransformFilter)。
But I want to be able to set a variable of my filter dynamically.
This can be done today using Property Page.
But what i want is change this property programatically.
我定义了一个自定义 COM接口来设置过滤器中的变量,但无法弄清楚如何使用它 - 访问它...
How to set a DirectShow filter's properties value without open the
filter's property page ?
有人有想法吗?
更多详情:
好吧
i) 我刚刚定义的简单界面
DEFINE_GUID(IID_IApplyFilterControl, X, X, X, X, X, X, X, X, X, X, X);
interface IApplyFilterControl : public IUnknown
{
STDMETHOD(SetWillApplyFilterX)(bool applyFilter) = 0;
};
ii) 然后在我的过滤器C ++代码中实现此接口
class MyFilter : public CTransformFilter , public IApplyFilterControl
{
....
STDMETHODIMP SetWillApplyFilter(bool apply)
{
CAutoLock lock(&m_csShared);
willApplyFilter = apply;
return S_OK;
}
...
}
iii)在我的C#代码中(使用DirectShowNet)
我希望能够访问我的过滤器
IBaseFilter myFilter =
(IBaseFilter)Activator.CreateInstance(Type.GetTypeFromCLSID(myFilterGuid));
....
IApplyFilterControl filterControl = (IApplyFilterControl ) myFilter;
.....
filterControl->SetWillApplyFilter(true)
最后我修复了
接受yms的建议并使用链接中的提示: Some advices about custom filters
i)您的COM接口
// The GUID that identifies your interface
// {13F23FD9-A90C-480d-A597-F46BA20070AC}
static const GUID IIDTransformFilterControl =
{
0x13f23fd9, 0xa90c, 0x480d, { 0xa5, 0x97, 0xf4, 0x6b, 0xa2, 0x0, 0x70, 0xac }
};
DECLARE_INTERFACE_(ITransformFilterControl, IUnknown)
{
STDMETHOD(setGreyscale)(bool enable) = 0;
};
ii)您的转换过滤器
class YourTransformFilter :
public CTransformFilter, public ITransformFilterControl
{
public:
STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void **ppv);
STDMETHODIMP setGreyscale(bool enable);
};
...
STDMETHODIMP YourTransformFilter::NonDelegatingQueryInterface(REFIID riid, void **ppv)
{
CheckPointer(ppv, E_POINTER);
if(riid==IIDTransformFilterControl)
return GetInterface((ITransformFilterControl*) this, ppv);
return CTransformFilter::NonDelegatingQueryInterface(riid, ppv);
}
STDMETHODIMP YourTransformFilter:: setGreyscale(bool enable)
{
bGreyscale = enable;
return S_OK;
}
iii)最后在您的C#主机应用程序中定义COM接口
[ComImport, System.Security.SuppressUnmanagedCodeSecurity,
Guid("13F23FD9-A90C-480d-A597-F46BA20070AC"),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface ITransformControl
{
[PreserveSig]
int setGreyscale(bool enable);
}
iv)并使用您的C#代码
ITransformFilterControl transformControl =
yourFilterInstance as ITransformFilterControl;
if(transformControl!=null)
{
transformControl->setGreyscale(true);
}
答案 0 :(得分:0)
如果您定义了一个COM接口来访问您的过滤器,那么您现在需要做的就是在C#/ VB.Net或您正在使用的任何.net语言中声明相同的接口(使用相同的GUI)。然后,您可以对新界面进行过滤器的类型转换。这是一个关于如何声明这样一个接口的C#示例:
using System.Runtime.InteropServices;
// Declare IMediaControl as a COM interface which
// derives from the IDispatch interface.
[Guid("56A868B1-0AD4-11CE-B03A-0020AF0BA770"),
InterfaceType(ComInterfaceType.InterfaceIsDual)]
interface IMediaControl // cannot list any base interfaces here
{
// Note that the members of IUnknown and Interface are NOT
// listed here
//
void Run();
void Pause();
void Stop();
void GetState( [In] int msTimeout, [Out] out int pfs);
void RenderFile(
[In, MarshalAs(UnmanagedType.BStr)] string strFilename);
void AddSourceFilter(
[In, MarshalAs(UnmanagedType.BStr)] string strFilename,
[Out, MarshalAs(UnmanagedType.Interface)] out object ppUnk);
[return : MarshalAs(UnmanagedType.Interface)]
object FilterCollection();
[return : MarshalAs(UnmanagedType.Interface)]
object RegFilterCollection();
void StopWhenReady();
}
修改强>
关于在投射期间E_NOINTERFACE的问题,它看起来像是一个线程问题。 1-使用Activator创建过滤器不是一个好主意,您应该始终允许DS图形创建过滤器,尝试使用“enumarate filters”。 2-确认您用于过滤器的趋势模型是“两者”。阅读here和here以获取更多信息。