下载本过滤器DLL
本过滤器获取过滤器图事件,将事件代码及参数以列表形式显示在窗口中。下面是事件列表窗口图片:
过滤器信息
过滤器名称:事件
过滤器GUID:{380338B5-4292-4DB3-826C-2A582678737E}
DLL注册函数名:DllRegisterServer
删除注册函数名:DllUnregisterServer
过滤器没有引脚。
过滤器开发信息
过滤器类从CBaseFilter类派生。在过滤器加入过滤器图时(JoinFilterGraph函数),获取过滤器图管理器指针,获取图事件接口指针;创建事件列表窗口,创建“获取过滤器图事件”线程;并在该线程中,使用图事件接口,在图事件队列中获取事件。
下面是本过滤器DLL的全部代码
头文件:CFilter.h
#include "resource.h"
#include <streams.h>
#include <initguid.h>
#if _DEBUG
#pragma comment(lib, "Strmbasd.lib")//C:\Program Files\Microsoft SDKs\Windows\v7.1\Samples\multimedia\directshow\baseclasses\Debug\strmbasd.lib
#else
#pragma comment(lib, "Strmbase.lib")//C:\Program Files\Microsoft SDKs\Windows\v7.1\Samples\multimedia\directshow\baseclasses\Release\strmbase.lib
#endif
#pragma comment(lib, "Winmm.lib")//C:\Program Files\Microsoft SDKs\Windows\v7.1\Lib\Winmm.lib
#pragma comment(lib, "msvcrt.lib")//C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\lib\msvcrt.lib
// {380338B5-4292-4DB3-826C-2A582678737E}
DEFINE_GUID(CLSID_Event,
0x380338b5, 0x4292, 0x4db3, 0x82, 0x6c, 0x2a, 0x58, 0x26, 0x78, 0x73, 0x7e);
class CFilter : public CBaseFilter, public CCritSec
{
public:
CFilter(LPWSTR lpName, LPUNKNOWN pUnk,HRESULT *phr);
virtual ~CFilter();
DECLARE_IUNKNOWN
static CUnknown * WINAPI CreateInstance(LPUNKNOWN, HRESULT *);
STDMETHODIMP JoinFilterGraph(IFilterGraph * pGraph, LPCWSTR pName);
HRESULT FindFilters(IFilterGraph* pGraph, int& n);//自定义函数,查找图中事件过滤器数量
int GetPinCount();
CBasePin *GetPin(int n);
HMENU hMenu;//菜单句柄
HWND hwnd;//窗口句柄
HWND hList;//列表视图控件窗口句柄
HANDLE hDestroy;//“过滤器已销毁”事件句柄
IFilterGraph * m_pGraph;//过滤器图管理器指针
IMediaEvent* pEvent;//过滤器图事件接口
};
源文件:CFilter.cpp
#include "CFilter.h"
#include "Commctrl.h"
#include "wchar.h"
#include "wmsdkidl.h"
HINSTANCE Hinstance;//DLL模块句柄
CFilter* m_pCFilter=NULL;//过滤器指针
DWORD WINAPI CreateWindowThread(LPVOID pParam);//创建窗口线程函数声明
DWORD WINAPI GetEventThread(LPVOID pParam);//获取事件线程函数声明
LRESULT CALLBACK WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);//窗口过程函数声明
#pragma warning(disable:4355 4127)//禁用警告C4355
CFilter::CFilter(LPWSTR lpName, LPUNKNOWN pUnk,HRESULT *phr) : CBaseFilter(lpName, pUnk, (CCritSec *) this, CLSID_Event)
{
m_pGraph=NULL;pEvent=NULL;
hDestroy=CreateEvent( NULL, FALSE, FALSE, NULL); //创建“过滤器已销毁”事件,自动重置,初始状态无信号
m_pCFilter=this;
}
CFilter::~CFilter()
{
SetEvent(hDestroy);//发出“过滤器已销毁”信号
SendMessage(hwnd,WM_CLOSE,0,0);//关闭事件窗口
DestroyWindow(hwnd);//销毁事件窗口
if(m_pGraph!=NULL)m_pGraph->Release();
if(pEvent!=NULL)pEvent->Release();
UnregisterClass(L"事件窗口类", Hinstance);//删除窗口类注册
}
CUnknown * WINAPI CFilter::CreateInstance(LPUNKNOWN pUnk, HRESULT *phr)
{
return new CFilter(L"事件", pUnk, phr);//创建过滤器
}
STDMETHODIMP CFilter::JoinFilterGraph(IFilterGraph * pGraph, LPCWSTR pName)
{
HRESULT hr;
if(pGraph!=NULL)
{
int n=0;
FindFilters(pGraph,n);//获取图中“事件过滤器”数量
if(n>1)
{
MessageBox(0,L"只能创建一个事件过滤器",0,MB_OK);return S_FALSE;
}
hr=pGraph->QueryInterface(IID_IMediaEvent,(void**)&pEvent);
if(pEvent!=NULL)
{
hr=pEvent->CancelDefaultHandling(EC_STATE_CHANGE); //取消事件默认处理
hr=pEvent->CancelDefaultHandling(EC_DISPLAY_CHANGED);
hr=pEvent->CancelDefaultHandling(EC_NEED_RESTART);
hr=pEvent->CancelDefaultHandling(EC_REPAINT);
hr=pEvent->CancelDefaultHandling(EC_STARVATION);
hr=pEvent->CancelDefaultHandling(EC_STEP_COMPLETE);
hr=pEvent->CancelDefaultHandling(EC_WINDOW_DESTROYED);
}
m_pGraph=pGraph;pGraph->AddRef();
CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)CreateWindowThread,this,0,NULL);//创建窗口线程
CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)GetEventThread,this,0,NULL);//创建“获取过滤器图事件”线程
}
return CBaseFilter::JoinFilterGraph(pGraph, pName);
}
HRESULT CFilter::FindFilters(IFilterGraph* pGraph, int& n)//查找图中事件过滤器数量
{
IEnumFilters* pEnum = NULL;
IBaseFilter* pFilter;
ULONG cFetched;
HRESULT hr = pGraph->EnumFilters(&pEnum);//获取IEnumFilters接口
if (FAILED(hr)) return hr;
while (pEnum->Next(1, &pFilter, &cFetched) == S_OK)
{
GUID guid;
hr = pFilter->GetClassID(&guid);
if (guid==CLSID_Event)//如果是事件过滤器
{
n++;
}
pFilter->Release();
}
pEnum->Release();
return S_OK;
}
int CFilter::GetPinCount()
{
return 0;
}
CBasePin *CFilter::GetPin(int n)
{
return NULL;
}
COLORREF color1=RGB(95,108,163),color2=RGB(255,255,255);
DWORD WINAPI CreateWindowThread(LPVOID pParam)//创建窗口线程
{
CFilter* p=(CFilter*)pParam;
WNDCLASSEX wcx;
wcx.cbSize = sizeof(wcx);//结构的大小
wcx.style = CS_HREDRAW | CS_VREDRAW; //窗口类样式
wcx.lpfnWndProc = WndProc; //窗口过程
wcx.cbClsExtra = 0; //没有额外的类内存
wcx.cbWndExtra = 0; //没有额外的窗口内存
wcx.hInstance = Hinstance; //实例句柄
wcx.hIcon = LoadIcon(NULL, IDI_APPLICATION); //预定义的应用程序图标
wcx.hCursor = LoadCursor(NULL, IDC_ARROW); //预定义的光标
HBRUSH hBrush=CreateSolidBrush(RGB(57,64,97));
wcx.hbrBackground = hBrush; //背景笔刷
wcx.lpszMenuName = L"EventMenu"; //菜单资源名称
wcx.lpszClassName = L"事件窗口类"; //窗口类的名称
wcx.hIconSm = (HICON)LoadImage(Hinstance, MAKEINTRESOURCE(5),IMAGE_ICON,GetSystemMetrics(SM_CXSMICON),GetSystemMetrics(SM_CYSMICON),LR_DEFAULTCOLOR);//小类图标
RegisterClassEx(&wcx);//注册窗口类
p->hMenu=LoadMenu(Hinstance,MAKEINTRESOURCE(IDR_MENU1));//加载菜单
RECT PM_rect;
SystemParametersInfo(SPI_GETWORKAREA, 0, (PVOID)&PM_rect, 0);//获取桌面工作区矩形
int Width=915;int Height=400;//窗口的宽高
HWND hwnd= CreateWindowEx(//创建"事件列表窗口"
WS_EX_TOPMOST, //窗口扩展样式
L"事件窗口类", //类名
L"事件列表", //窗口名称
WS_VISIBLE|WS_SYSMENU|WS_CAPTION|WS_CLIPCHILDREN|WS_MINIMIZEBOX|WS_POPUP, //窗口样式
(PM_rect.right-PM_rect.left)/2-Width/2, //窗口左侧位置
PM_rect.bottom-Height-30, //窗口顶部位置
Width, //窗口宽度
Height, //窗口高度
(HWND)NULL, //没有父窗口或所有者窗口
p->hMenu, //使用的菜单
Hinstance, //实例句柄
NULL); //没有窗口创建数据
p->hwnd=hwnd;
RECT rect;
GetClientRect(hwnd,&rect);
p->hList=CreateWindow(L"SysListView32",NULL,WS_CHILD|WS_VISIBLE|LVS_REPORT|LVS_SINGLESEL|LVS_NOSORTHEADER ,5,5, rect.right-10,rect.bottom-10,hwnd,NULL,Hinstance,NULL);//创建列表视图控件
LVCOLUMN LV;
LV.mask=LVCF_WIDTH|LVCF_TEXT;
LV.pszText=L"事件";LV.cx=300;
SendMessage(p->hList,LVM_INSERTCOLUMN,(WPARAM)0,(LPARAM)&LV);//列表视图控件添加第1列
LV.pszText=L"事件参数1";LV.cx=300;
SendMessage(p->hList,LVM_INSERTCOLUMN,(WPARAM)1,(LPARAM)&LV);//列表视图控件添加第2列
LV.pszText=L"事件参数2";LV.cx=300;
SendMessage(p->hList,LVM_INSERTCOLUMN,(WPARAM)2,(LPARAM)&LV);//列表视图控件添加第3列
SendMessage(p->hList,LVM_SETBKCOLOR,0,(LPARAM)color1);//设置列表视图控件背景色
SendMessage(p->hList,LVM_SETTEXTBKCOLOR,0,(LPARAM)color1);//设置列表视图控件文本背景色
SendMessage(p->hList,LVM_SETTEXTCOLOR,0,(LPARAM)color2);//设置列表视图控件文本颜色
MSG msg;
BOOL fGotMessage;
while ((fGotMessage = GetMessage(&msg, hwnd, 0, 0)) != 0 && fGotMessage != -1)
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return 1;
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)//窗口过程函数
{
HMENU hMenu=GetMenu(hwnd);
switch(uMsg)
{
case WM_CLOSE://点击了样本窗口关闭按钮
ShowWindow(hwnd, SW_MINIMIZE);//最小化窗口
return 0;//不调用DefWindowProc,防止销毁窗口
case WM_COMMAND:
switch(LOWORD(wParam)) //响应点击菜单项
{
case ID_40001:
SendMessage(m_pCFilter->hList,LVM_DELETEALLITEMS,0,0);//列表视图删除所有项
break;
case ID_Menu://EC_ACTIVATE
if(GetMenuState(hMenu,ID_Menu,MF_BYCOMMAND)==MF_CHECKED)
{
CheckMenuItem(hMenu,ID_Menu,MF_UNCHECKED);m_pCFilter->pEvent->RestoreDefaultHandling(EC_ACTIVATE);//恢复事件默认处理
}
else
{
CheckMenuItem(hMenu,ID_Menu,MF_CHECKED);m_pCFilter->pEvent->CancelDefaultHandling(EC_ACTIVATE); //取消事件默认处理
}
break;
case ID_40004://EC_COMPLETE
if(GetMenuState(hMenu,ID_40004,MF_BYCOMMAND)==MF_CHECKED)
{
CheckMenuItem(hMenu,ID_40004,MF_UNCHECKED);m_pCFilter->pEvent->RestoreDefaultHandling(EC_COMPLETE);
}
else
{
CheckMenuItem(hMenu,ID_40004,MF_CHECKED);m_pCFilter->pEvent->CancelDefaultHandling(EC_COMPLETE);
}
break;
case ID_40002://EC_STATE_CHANGE
if(GetMenuState(hMenu,ID_40002,MF_BYCOMMAND)==MF_CHECKED)
{
CheckMenuItem(hMenu,ID_40002,MF_UNCHECKED);m_pCFilter->pEvent->RestoreDefaultHandling(EC_STATE_CHANGE);
}
else
{
CheckMenuItem(hMenu,ID_40002,MF_CHECKED);m_pCFilter->pEvent->CancelDefaultHandling(EC_STATE_CHANGE);
}
break;
case ID_40005://EC_DISPLAY_CHANGED
if(GetMenuState(hMenu,ID_40005,MF_BYCOMMAND)==MF_CHECKED)
{
CheckMenuItem(hMenu,ID_40005,MF_UNCHECKED);m_pCFilter->pEvent->RestoreDefaultHandling(EC_DISPLAY_CHANGED);
}
else
{
CheckMenuItem(hMenu,ID_40005,MF_CHECKED);m_pCFilter->pEvent->CancelDefaultHandling(EC_DISPLAY_CHANGED);
}
break;
case ID_40007://EC_NEED_RESTART
if(GetMenuState(hMenu,ID_40007,MF_BYCOMMAND)==MF_CHECKED)
{
CheckMenuItem(hMenu,ID_40007,MF_UNCHECKED);m_pCFilter->pEvent->RestoreDefaultHandling(EC_NEED_RESTART);
}
else
{
CheckMenuItem(hMenu,ID_40007,MF_CHECKED);m_pCFilter->pEvent->CancelDefaultHandling(EC_NEED_RESTART);
}
break;
case ID_40008://EC_REPAINT
if(GetMenuState(hMenu,ID_40008,MF_BYCOMMAND)==MF_CHECKED)
{
CheckMenuItem(hMenu,ID_40008,MF_UNCHECKED);m_pCFilter->pEvent->RestoreDefaultHandling(EC_REPAINT);
}
else
{
CheckMenuItem(hMenu,ID_40008,MF_CHECKED);m_pCFilter->pEvent->CancelDefaultHandling(EC_REPAINT);
}
break;
case ID_40010://EC_STARVATION
if(GetMenuState(hMenu,ID_40010,MF_BYCOMMAND)==MF_CHECKED)
{
CheckMenuItem(hMenu,ID_40010,MF_UNCHECKED);m_pCFilter->pEvent->RestoreDefaultHandling(EC_STARVATION);
}
else
{
CheckMenuItem(hMenu,ID_40010,MF_CHECKED);m_pCFilter->pEvent->CancelDefaultHandling(EC_STARVATION);
}
break;
case ID_40011://EC_STEP_COMPLETE
if(GetMenuState(hMenu,ID_40011,MF_BYCOMMAND)==MF_CHECKED)
{
CheckMenuItem(hMenu,ID_40011,MF_UNCHECKED);m_pCFilter->pEvent->RestoreDefaultHandling(EC_STEP_COMPLETE);
}
else
{
CheckMenuItem(hMenu,ID_40011,MF_CHECKED);m_pCFilter->pEvent->CancelDefaultHandling(EC_STEP_COMPLETE);
}
break;
case ID_40012://EC_WINDOW_DESTROYED
if(GetMenuState(hMenu,ID_40012,MF_BYCOMMAND)==MF_CHECKED)
{
CheckMenuItem(hMenu,ID_40012,MF_UNCHECKED);m_pCFilter->pEvent->RestoreDefaultHandling(EC_WINDOW_DESTROYED);
}
else
{
CheckMenuItem(hMenu,ID_40012,MF_CHECKED);m_pCFilter->pEvent->CancelDefaultHandling(EC_WINDOW_DESTROYED);
}
break;
}
break;
}
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
DWORD WINAPI GetEventThread(LPVOID pParam)//获取图事件线程
{
CFilter* p=(CFilter*)pParam;
long evCode; LONG_PTR lParam1, lParam2;
LVITEM LT0;
LT0.mask=LVIF_TEXT;LT0.iItem=0;LT0.iSubItem=0;
LVITEM LT1;
LT1.mask=LVIF_TEXT;LT1.iItem=0;LT1.iSubItem=1;
LVITEM LT2;
LT2.mask=LVIF_TEXT;LT2.iItem=0;LT2.iSubItem=2;
Agan:
if(p->pEvent->GetEvent(&evCode,&lParam1,&lParam2,1)==S_OK)
{
wchar_t wch1[100],wch2[100];
wmemset(wch1,0,100);wmemset(wch2,0,100);
_itow_s(lParam1,wch1,10);_itow_s(lParam2,wch2,10);
wchar_t WCH0[100];wmemset(WCH0,0,100);
wchar_t WCH1[100]=L"lParam1=";
wchar_t WCH2[100]=L"lParam2=";
wcscat_s(WCH1,100,wch1);wcscat_s(WCH2,100,wch2);
switch (evCode)
{
case EC_ACTIVATE:
wcscat_s(WCH0,100,L"EC_ACTIVATE//激活或停用窗口");
if(lParam1)wcscat_s(WCH1,100,L"//激活窗口");
else wcscat_s(WCH1,100,L"//停用窗口");
wcscat_s(WCH2,100,L"//渲染器IBaseFilter接口指针");
break;
case EC_BUFFERING_DATA:
wcscat_s(WCH0,100,L"EC_BUFFERING_DATA");
if(lParam1)wcscat_s(WCH1,100,L"//图开始缓冲");
else wcscat_s(WCH1,100,L"//图已停止缓冲");
break;
case EC_BUILT:
wcscat_s(WCH0,100,L"EC_BUILT//图构建完成。由视频控件发送");
break;
case EC_CLOCK_CHANGED:
wcscat_s(WCH0,100,L"EC_CLOCK_CHANGED//参考时钟已更改");
break;
case EC_CLOCK_UNSET:
wcscat_s(WCH0,100,L"EC_CLOCK_UNSET//时钟提供程序已断开连接");
break;
case EC_CODECAPI_EVENT:
wcscat_s(WCH0,100,L"EC_CODECAPI_EVENT//编码器发出编码信号。");
wcscat_s(WCH1,100,L"//用户数据");
wcscat_s(WCH2,100,L"//指向事件数据的指针");
break;
case EC_COMPLETE:
wcscat_s(WCH0,100,L"EC_COMPLETE//流渲染完成");
if(lParam1==0)wcscat_s(WCH1,100,L"//(HRESULT)返回S_OK");
else wcscat_s(WCH1,100,L"//(HRESULT)返回值");
if(lParam2!=0)wcscat_s(WCH2,100,L"//渲染器IBaseFilter接口的指针");
break;
case EC_DEVICE_LOST:
wcscat_s(WCH0,100,L"EC_DEVICE_LOST//即插即用设备已删除或再次可用");
wcscat_s(WCH1,100,L"//代表设备过滤器的IUnknown接口指针");
if(lParam2)wcscat_s(WCH2,100,L"//设备再次可用");
else wcscat_s(WCH2,100,L"//设备已删除");
break;
case EC_DISPLAY_CHANGED:
wcscat_s(WCH0,100,L"EC_DISPLAY_CHANGED//显示模式已更改");
if(lParam2)
{
if(lParam1)wcscat_s(WCH1,100,L"//输入引脚的IPin接口数组的指针");
wcscat_s(WCH2,100,L"//数组的大小");
}
else
{
if(lParam1)wcscat_s(WCH1,100,L"//输入引脚的IPin接口的指针");
}
break;
case EC_END_OF_SEGMENT:
wcscat_s(WCH0,100,L"EC_END_OF_SEGMENT\\到达段的结尾");
wcscat_s(WCH1,100,L"//自段开始的流时间,以100纳秒为单位");
wcscat_s(WCH2,100,L"//段号(从零开始)");
break;
case EC_ERROR_STILLPLAYING:
wcscat_s(WCH0,100,L"EC_ERROR_STILLPLAYING//异步命令运行图失败");
wcscat_s(WCH1,100,L"//失败代码");
break;
case EC_ERRORABORT:
wcscat_s(WCH0,100,L"EC_ERRORABORT//由于错误,操作被中止");
wcscat_s(WCH1,100,L"//(HRESULT)失败代码");
break;
case EC_EXTDEVICE_MODE_CHANGE:
wcscat_s(WCH0,100,L"EC_EXTDEVICE_MODE_CHANGE");
break;
case EC_FULLSCREEN_LOST:
wcscat_s(WCH0,100,L"EC_FULLSCREEN_LOST//视频渲染器将退出全屏模式");
wcscat_s(WCH2,100,L"//视频渲染器IBaseFilter接口的指针");
break;
case EC_GRAPH_CHANGED:
wcscat_s(WCH0,100,L"EC_GRAPH_CHANGED//图已更改");
break;
case EC_LENGTH_CHANGED:
wcscat_s(WCH0,100,L"EC_LENGTH_CHANGED//源的长度已更改");
break;
case EC_NEED_RESTART:
wcscat_s(WCH0,100,L"EC_NEED_RESTART//过滤器要求重新启动图");
break;
case EC_NOTIFY_WINDOW:
wcscat_s(WCH0,100,L"EC_NOTIFY_WINDOW//报告视频渲染器窗口");
wcscat_s(WCH1,100,L"//(HWND)窗口句柄");
break;
case EC_OLE_EVENT:
wcscat_s(WCH0,100,L"EC_OLE_EVENT//过滤器正将文本传递给应用程序");
wcscat_s(WCH1,100,L"//(BSTR)字符串");
wcscat_s(WCH2,100,L"//(BSTR)字符串");
break;
case EC_OPENING_FILE:
wcscat_s(WCH0,100,L"EC_OPENING_FILE//图正在打开文件,或已完成打开文件");
if(lParam1)wcscat_s(WCH1,100,L"//正在打开文件");
else wcscat_s(WCH1,100,L"//完成打开文件");
break;
case EC_PALETTE_CHANGED:
wcscat_s(WCH0,100,L"EC_PALETTE_CHANGED//视频调色板已更改");
break;
case EC_PAUSED:
wcscat_s(WCH0,100,L"EC_PAUSED//暂停请求已完成");
if(lParam1==0)wcscat_s(WCH1,100,L"//(HRESULT)返回S_OK");
else wcscat_s(WCH1,100,L"//(HRESULT)返回值");
break;
case EC_PREPROCESS_COMPLETE:
wcscat_s(WCH0,100,L"EC_PREPROCESS_COMPLETE//WM ASF Writer过滤器完成多遍编码的预处理");
wcscat_s(WCH2,100,L"//过滤器IBaseFilter接口的指针");
break;
case EC_PROCESSING_LATENCY:
wcscat_s(WCH0,100,L"EC_PROCESSING_LATENCY//处理每个样本所花费的时间");
wcscat_s(WCH1,100,L"//处理每个样本的时间,单位100纳秒");
break;
case EC_QUALITY_CHANGE:
wcscat_s(WCH0,100,L"EC_QUALITY_CHANGE//图正在删除样本,以进行质量控制");
break;
case EC_REPAINT:
wcscat_s(WCH0,100,L"EC_REPAINT//引脚需要重新发送数据");
wcscat_s(WCH1,100,L"//视频渲染器输入引脚IPin接口的指针");
break;
case EC_SAMPLE_LATENCY:
wcscat_s(WCH0,100,L"EC_SAMPLE_LATENCY//处理样本的进度落后");
wcscat_s(WCH1,100,L"//落后时间,单位100纳秒");
break;
case EC_SAMPLE_NEEDED://
wcscat_s(WCH0,100,L"EC_SAMPLE_NEEDED//请求新的输入样本");
wcscat_s(WCH1,100,L"//需要新输入的流的标识符");
break;
case EC_SCRUB_TIME:
wcscat_s(WCH0,100,L"EC_SCRUB_TIME//指定最近的帧步的时间戳");
wcscat_s(WCH1,100,L"//(DWORD)时间戳的低32位");
wcscat_s(WCH2,100,L"//(DWORD)时间戳的高32位");
break;
case EC_SEGMENT_STARTED:
wcscat_s(WCH0,100,L"EC_SEGMENT_STARTED//新段已经开始");
wcscat_s(WCH1,100,L"//自段开始的流时间,单位100纳秒");
wcscat_s(WCH2,100,L"//(DWORD)段号(从零开始)");
break;
case EC_SHUTTING_DOWN:
wcscat_s(WCH0,100,L"EC_SHUTTING_DOWN//图正在关闭");
break;
case EC_SNDDEV_IN_ERROR:
wcscat_s(WCH0,100,L"EC_SNDDEV_IN_ERROR//音频捕获过滤器发生了设备错误");
wcscat_s(WCH1,100,L"//SNDDEV_ERR枚举值,指示发生故障时如何访问设备");
wcscat_s(WCH2,100,L"//DWORD值,指示从声音设备调用返回的错误");
break;
case EC_SNDDEV_OUT_ERROR:
wcscat_s(WCH0,100,L"EC_SNDDEV_OUT_ERROR//音频渲染过滤器发生设备错误");
wcscat_s(WCH1,100,L"//SNDDEV_ERR枚举值,指示发生故障时如何访问设备");
wcscat_s(WCH2,100,L"//DWORD值,指示从声音设备调用返回的错误");
break;
case EC_STARVATION:
wcscat_s(WCH0,100,L"EC_STARVATION//过滤器未接收到足够的数据");
break;
case EC_STATE_CHANGE:
wcscat_s(WCH0,100,L"EC_STATE_CHANGE//图状态已更改");
if(lParam1 ==State_Stopped)wcscat_s(WCH1,100,L"//新的图状态为停止");
if(lParam1 ==State_Paused )wcscat_s(WCH1,100,L"//新的图状态为暂停");
if(lParam1 ==State_Running)wcscat_s(WCH1,100,L"//新的图状态为运行");
break;
case EC_STEP_COMPLETE:
wcscat_s(WCH0,100,L"EC_STEP_COMPLETE//过滤器已完成帧步进");
break;
case EC_STREAM_CONTROL_STARTED:
wcscat_s(WCH0,100,L"EC_STREAM_CONTROL_STARTED//流控制启动命令生效");
wcscat_s(WCH1,100,L"//启动流的引脚的IPin接口指针");
wcscat_s(WCH2,100,L"//(DWORD)用户定义的值");
break;
case EC_STREAM_CONTROL_STOPPED:
wcscat_s(WCH0,100,L"EC_STREAM_CONTROL_STOPPED//流控制停止命令已经生效");
wcscat_s(WCH1,100,L"//停止流的引脚的IPin接口指针");
wcscat_s(WCH2,100,L"//(DWORD)用户定义的值");
break;
case EC_STREAM_ERROR_STILLPLAYING:
wcscat_s(WCH0,100,L"EC_STREAM_ERROR_STILLPLAYING//流中发生错误,但流仍在运行");
wcscat_s(WCH1,100,L"//(HRESULT)失败代码");
wcscat_s(WCH2,100,L"//(DWORD)次要错误代码");
break;
case EC_STREAM_ERROR_STOPPED:
wcscat_s(WCH0,100,L"EC_STREAM_ERROR_STOPPED//由于错误,流已停止");
wcscat_s(WCH1,100,L"//(HRESULT)失败代码");
wcscat_s(WCH2,100,L"//(DWORD)次要错误代码");
break;
case EC_TIMECODE_AVAILABLE:
wcscat_s(WCH0,100,L"EC_TIMECODE_AVAILABLE//由支持时间码的过滤器发送");
break;
case EC_UNBUILT:
wcscat_s(WCH0,100,L"EC_UNBUILT//图从已构建状态转换为未构建状态");
break;
case EC_USERABORT:
wcscat_s(WCH0,100,L"EC_USERABORT//用户已终止运行");
break;
case EC_VIDEO_SIZE_CHANGED:
wcscat_s(WCH0,100,L"EC_VIDEO_SIZE_CHANGED//视频大小已更改");
wcscat_s(WCH1,100,L"//(DWORD)低位WORD新的宽度,高位WORD新高度;以像素为单位");
break;
case EC_VMR_RECONNECTION_FAILED:
wcscat_s(WCH0,100,L"EC_VMR_RECONNECTION_FAILED//尝试动态格式更改,VMR无法接受新格式");
break;
case EC_VMR_RENDERDEVICE_SET:
wcscat_s(WCH0,100,L"EC_VMR_RENDERDEVICE_SET//标识渲染机制");
if(lParam1 ==VMR_RENDER_DEVICE_OVERLAY)wcscat_s(WCH1,100,L"//渲染到表面");
if(lParam1 ==VMR_RENDER_DEVICE_VIDMEM)wcscat_s(WCH1,100,L"//渲染到视频内存");
if(lParam1 ==VMR_RENDER_DEVICE_SYSMEM )wcscat_s(WCH1,100,L"//渲染到系统内存");
break;
case EC_VMR_SURFACE_FLIPPED:
wcscat_s(WCH0,100,L"EC_VMR_SURFACE_FLIPPED//调用DirectDraw Flip方法");
wcscat_s(WCH1,100,L"//(HRESULT)从DirectDraw Flip方法返回的状态代码");
break;
case EC_WINDOW_DESTROYED:
wcscat_s(WCH0,100,L"EC_WINDOW_DESTROYED//窗口被销毁时由视频渲染器发送");
wcscat_s(WCH1,100,L"//视频渲染器的IBaseFilter接口指针");
break;
case EC_WMT_EVENT:
wcscat_s(WCH0,100,L"EC_WMT_EVENT//读取受数字版权管理(DRM)保护的ASF文件");
break;
case EC_WMT_INDEX_EVENT:
wcscat_s(WCH0,100,L"EC_WMT_INDEX_EVENT//使用WM ASF Writer过滤器索引WMV文件");
if(lParam1 ==WMT_STARTED)wcscat_s(WCH1,100,L"//索引已开始");
if(lParam1 ==WMT_CLOSED )wcscat_s(WCH1,100,L"//索引已完成");
if(lParam1 ==WMT_INDEX_PROGRESS )
{
wcscat_s(WCH1,100,L"//正在建立索引");
wcscat_s(WCH2,100,L"//当前进度百分比");
}
break;
default:
break;
}
if (p->pEvent != NULL)p->pEvent->FreeEventParams(evCode, lParam1, lParam2);
LT0.pszText=WCH0;LT1.pszText=WCH1;LT2.pszText=WCH2;
SendMessage(p->hList,LVM_INSERTITEM,0,(LPARAM)<0);//列表视图添加项
SendMessage(p->hList,LVM_SETITEMTEXT,0,(LPARAM)<1);//列表视图设置子项1文本
SendMessage(p->hList,LVM_SETITEMTEXT,0,(LPARAM)<2);//列表视图设置子项2文本
}
DWORD dw = WaitForSingleObject(p->hDestroy,0);//获取“过滤器已销毁”事件信号
if(dw!=WAIT_OBJECT_0)//如果没有信号
{
goto Agan;//再次获取事件
}
CloseHandle(p->hDestroy);
return 1;
}
const AMOVIESETUP_FILTER Event = //过滤器的注册信息
{
&CLSID_Event, //过滤器的类标识
L"事件", //过滤器的名称
MERIT_DO_NOT_USE, //过滤器优先值
0, // 引脚数量
NULL // 引脚信息
};
CFactoryTemplate g_Templates [] = {
{
L"事件"
, &CLSID_Event
, CFilter::CreateInstance
, NULL
, &Event
}
};
int g_cTemplates = 1;
STDAPI DllRegisterServer()//注册DLL
{
return AMovieDllRegisterServer2(TRUE);
}
STDAPI DllUnregisterServer()//删除DLL注册
{
return AMovieDllRegisterServer2(FALSE);
}
extern "C" BOOL WINAPI DllEntryPoint(HINSTANCE, ULONG, LPVOID);
BOOL APIENTRY DllMain(HANDLE hModule, DWORD dwReason, LPVOID lpReserved)
{
Hinstance=(HINSTANCE)hModule;
return DllEntryPoint((HINSTANCE)(hModule), dwReason, lpReserved);
}
DLL模块定义文件:事件.def
LIBRARY 事件.dll
EXPORTS
DllMain PRIVATE
DllGetClassObject PRIVATE
DllCanUnloadNow PRIVATE
DllRegisterServer PRIVATE
DllUnregisterServer PRIVATE