下载本过滤器DLL
在过滤器的开发中,有时,我们需要抓取过滤器引脚输出的样本,对样本数据进行分析,获取样本的有效数据长度,时间戳,媒体时间,中断标志,同步点标志,预卷标志。出于此种考虑,开发了此过滤器。将样本的所有参数,通过列表直观的显示出来,同时还可以抓取样本数据,输出到磁盘。下面是此过滤器的样本信息窗口图片:

还可以在连接引脚时,指定连接使用的媒体类型。

过滤器的参数信息

过滤器名称:采样
过滤器GUID:{484DFA06-F5D3-48AF-9AA0-6E3188F9F4C3}
DLL注册函数名:DllRegisterServer
删除注册函数名:DllUnregisterServer
过滤器有1个输入引脚。
输入引脚标识:In
输入引脚媒体类型:
主要类型:GUID_NULL
子类型:GUID_NULL
格式类型:GUID_NULL
在一个过滤器图中,最多可以创建10个此采样过滤器。

过滤器开发过程

过滤器从CBaseFilter派生。重写了Run,JoinFilterGraph,GetPinCount,GetPin函数。添加了GetString,GetMediaTypeString,GetFormatString自定义函数。

GetString函数,用于从GUID获取其定义字符串。
首先创建一个M.dat文件,创建方法是:首先,写入一个int值,占4字节,其包含了项的总数。然后写入每一项。
每项的结构是:先写入一个DWORD值,占4字节,其包含了该项“GUID定义“字符串的长度(包含空终止符),然后写入“GUID定义“字符串;最后写入与该定义对应的GUID的字符形式,占39字节(包含空终止符)。

DWORD(16)MEDIATYPE_Video {73646976-0000-0010-8000-00AA00389B71}
DWORD(18)MEDIASUBTYPE_H264 {34363248-0000-0010-8000-00AA00389B71}

DWORD(16)MEDIATYPE_Audio {73647561-0000-0010-8000-00AA00389B71}

将有定义的媒体类型主要类型,子类型,格式类型的定义字符串和其字符形式的GUID,分别写入项。这些GUID获取自uuids.h,wmcodecdsp.h,ksuuids.h,dxva.h,Bdamedia.h头文件。
准备好M.dat文件后,将其添加到资源。然后加载资源,获取资源地址。将,要获取其定义的GUID转换为字符形式,与M.dat文件中每一项的GUID的字符形式进行对比,如果相同,返回与其对应的定义字符串。具体代码如下:

char* CFilter::GetString(GUID guid)//获取GUID定义字符串
{LPWSTR lp=NULL;HRESULT hr = StringFromCLSID(guid, (LPOLESTR*)&lp);//将GUID转换为字符串形式char* chX=new char[39];for(int i=0;i<39;i++){chX[i]=(char)lp[i];}CoTaskMemFree(lp);//释放StringFromCLSID分配的内存HRSRC hRes=FindResource(Hinstance,MAKEINTRESOURCE(IDR_DAT1),L"DAT");HGLOBAL hMem=LoadResource(Hinstance,hRes);BYTE* pb=(BYTE*)LockResource(hMem);//获取数据的起始内存地址DWORD count, LEN; char ch[39];CopyMemory(&count,pb,4);pb+=4;for (int i = 0; i < (int)count; i++){CopyMemory(&LEN,pb,4);pb+=4;char* pch = new char[LEN];CopyMemory(pch,pb,LEN);pb+=LEN;memset(ch, 0, 39);CopyMemory(ch,pb,39);pb+=39;if(strcoll(chX,ch)==0)//如果字符串相等{FreeResource(hMem);//释放资源delete[] chX;return pch;}delete[] pch;}FreeResource(hMem);//释放资源return chX;
}

GetMediaTypeString函数获取媒体类型描述字符串。
GetFormatString函数获取格式结构描述字符串。
创建了自定义过滤器指针数组类,管理过滤器指针。
创建了过滤器名称数组类,为过滤器指定名称。
将10个过滤器名称,保存在wchar_t WCH[10][20]二维数组中:
采样 1 FALSE
采样 2 FALSE
采样 3 FALSE
采样 4 FALSE
采样 5 FALSE
采样 6 FALSE
采样 7 FALSE
采样 8 FALSE
采样 9 FALSE
采样 10 FALSE
同时创建BOOL变量数组,标记名称是否已使用。TRUE表示已使用,FALSE未使用。GetName函数获取过滤器名称,它从1到10遍历每个名称,当该名称标记为FALSE时,返回该名称的地址,并将该名称标记设置为TRUE。
在过滤器的构造函数中,创建线程,用于创建样本信息窗口,并在窗口中创建要使用的控件,为窗口添加窗口过程函数。安装键盘消息钩子,当按F2键时,显示样本信息窗口。

输入引脚从CBaseInputPin派生。重写了CheckConnect,CheckMediaType,SetMediaType,Receive函数。在引脚开始连接时,CheckConnect最先调用,参数pPin为对方引脚的指针。在CheckConnect函数中,枚举对方引脚的所有媒体类型,并将获取到的媒体类型指针,和媒体类型描述字符串,添加到自定义数组。在CheckMediaType函数的首次调用中,弹出媒体类型选择模态对话框。为对话框添加过程函数,在对话框的初始化中,从自定义数组加载媒体类型项,到对话框的列表视图控件,用于选择连接使用的媒体类型。在SetMediaType函数中,将媒体类型描述文本,指定给样本信息窗口中的编辑框。Receive函数接收上游输出引脚发送的样本。在该函数中,获取样本所有信息,并将信息文本指定给样本信息窗口中的列表视图控件;如果需要,复制样本数据写到磁盘文件。

下面是本过滤器DLL的全部代码:

DLL头文件:GetSample.h

#ifndef  DLL_FILE
#define DLL_FILE#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// {484DFA06-F5D3-48AF-9AA0-6E3188F9F4C3}
DEFINE_GUID(CLSID_GetSample,
0x484dfa06, 0xf5d3, 0x48af, 0x9a, 0xa0, 0x6e, 0x31, 0x88, 0xf9, 0xf4, 0xc3);#endif // DLL_FILE

DLL源文件:GetSample.cpp

#include "GetSample.h"
#include "CFilter.h"HINSTANCE Hinstance;//DLL模块句柄const AMOVIESETUP_MEDIATYPE sudPinTypes =
{&MEDIATYPE_NULL,            // 主要类型&MEDIASUBTYPE_NULL          // 子类型
};const AMOVIESETUP_PIN sudPin  =  // 引脚信息
{L"In",                       //引脚名称FALSE,                       // 必须渲染输入引脚FALSE,                       // 输出引脚FALSE,                       // 具有该引脚的零个实例FALSE,                       // 可以创建一个以上引脚的实例&CLSID_NULL,                 //该引脚连接的过滤器的类标识NULL,                        //该引脚连接的引脚名称1,                           //引脚支持的媒体类型数&sudPinTypes                 //媒体类型信息
};   const AMOVIESETUP_FILTER GetSample =  //过滤器的注册信息
{&CLSID_GetSample,            //过滤器的类标识L"采样",                      //过滤器的名称MERIT_DO_NOT_USE,            //过滤器优先值1,                           //引脚数量&sudPin                      //引脚信息
};CFactoryTemplate g_Templates []  = {{L"采样", &CLSID_GetSample, CFilter::CreateInstance, NULL, &GetSample}
};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);
}

过滤器头文件:CFilter.h

#ifndef  FILTER_FILE
#define FILTER_FILE#include "GetSample.h"
#include "CInputPin.h"class CFilter : public CBaseFilter, public CCritSec
{friend class CInputPin;
public:CFilter(LPWSTR lpName, LPUNKNOWN pUnk,HRESULT *phr);virtual ~CFilter();DECLARE_IUNKNOWNstatic CUnknown * WINAPI CreateInstance(LPUNKNOWN, HRESULT *);STDMETHODIMP Run(REFERENCE_TIME tStart);STDMETHODIMP JoinFilterGraph(IFilterGraph * pGraph, LPCWSTR pName);int GetPinCount();CBasePin *GetPin(int n);char* GetString(GUID guid);//获取GUID定义字符串char *GetMediaTypeString(const CMediaType *pmt);//获取媒体类型描述字符串char* GetFormatString(GUID guid, BYTE* P);//获取格式结构描述字符串int index;//样本索引int sel;//选择的媒体类型索引DWORD StartTime;//运行开始时间,单位毫秒HWND hSampleDlg;//样本信息窗口句柄HWND hPathEdit;//显示输出文件夹路径编辑框HWND hwndButton;//按钮窗口句柄HWND hEdit;//媒体类型编辑框窗口句柄HWND hL;//样本参数列表窗口句柄HMENU hMenu;//菜单句柄HFONT hFont1,hFont2;wchar_t DirectoryName[MAX_PATH];//数据文件夹路径wchar_t FilterName[20];//过滤器名称int Setup;//设置选项索引BOOL B100;//100数量限制标志HANDLE hHasCreate;//"样本信息窗口创建完成"事件句柄CInputPin *m_pInputPin;   //输入引脚指针
}; class CFilterPtr//过滤器指针数组类
{public:CFilterPtr();DWORD dw[10];int Count;int Find(DWORD* p);//查找某个过滤器指针的索引void Add(DWORD* p);//添加过滤器指针void Delete(DWORD* p);//删除过滤器指针DWORD GetAt(int i);//获取指定索引处的过滤器指针int GetCount();//获取数组元素数量
};class CName//过滤器名称数组类
{public:CName();wchar_t WCH[10][20];//保存名称的2维数组BOOL Use[10];//名称使用标记数组,元素为TRUE,已使用;FALSE,未使用int Count;//已使用名称的数量int GetCount();//获取数组元素数量wchar_t* GetName();//从数组中获取可用名称void Delete(wchar_t* p);//在名称数组中删除参数指定的项(标记p未使用。已使用数量-1)wchar_t* GetAt(int i);//在名称数组中,获取指定索引处的名称
};#endif // FILTER_FILE

过滤器源文件:CFilter.cpp

#include "CFilter.h"
#include "Commctrl.h"
#include "wchar.h"
#include "stdio.h"
#include "Dvdmedia.h"
#include "Mmreg.h"
#include "Mpegtype.h"
#include "Shlobj.h"//文件夹选择对话框使用CFilterPtr::CFilterPtr()//过滤器指针数组类构造函数
{Count=0;for(int i=0;i<10;i++){dw[i]=0;}
}int CFilterPtr::Find(DWORD* p)//根据过滤器指针,获取其索引
{for(int i=0;i<Count;i++){if(dw[i]==(DWORD)p)return i;}return -1;
}void CFilterPtr::Add(DWORD* p)//向过滤器指针数组,添加过滤器指针
{if(Count==10)return;//最多添加10个过滤器指针dw[Count]=(DWORD)p;Count++;
}void CFilterPtr::Delete(DWORD* p)//删除参数指定的过滤器指针
{int find=Find(p);if(find==-1)return;for(int i=find;i<Count-1;i++){dw[i]=dw[i+1];}Count--;for(int i=Count;i<10;i++)//将后面的元素置0{dw[i]=0;}
}int CFilterPtr::GetCount()//获取过滤器指针数组中,保存的指针的数量
{return Count;
}DWORD CFilterPtr::GetAt(int i)//获取过滤器指针数组中,指定索引处的指针
{return dw[i];
}CName::CName()//过滤器名称数组类构造函数
{Count=0;for(int i=0;i<10;i++){Use[i]=FALSE;wmemset(WCH[i],0,20);wcscat_s(WCH[i],20,L"采样 ");wchar_t wch[4];_itow_s(i+1,wch,20,10);wcscat_s(WCH[i],20,wch);}
}int CName::GetCount()//获取过滤器名称数组中,已使用名称的总数
{int n=0;for(int i=0;i<10;i++){if(Use[i])n++;}return n;
}wchar_t* CName::GetName()//从数组中获取名称
{if(Count==10)return NULL;wchar_t* pwch=NULL;for(int i=0;i<10;i++){if(Use[i]==FALSE){Use[i]=TRUE;pwch=WCH[i];break;}}Count++;return pwch;
}void CName::Delete(wchar_t* p)//从数组中,删除参数指定的名称(实际为,标记该名称未使用)
{if(Count==0)return;for(int i=0;i<10;i++){if(wcscmp(WCH[i],p)==0){Use[i]=FALSE;Count--;return;}}
}wchar_t* CName::GetAt(int i)//获取指定索引处的名称
{return WCH[i];
}CFilterPtr FilterArray;//过滤器指针数组对象
CName NameArray;//过滤器名称数组对象extern HINSTANCE Hinstance;//DLL模块句柄
HHOOK hHook=NULL;//键盘消息钩子句柄LRESULT CALLBACK WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);//样本信息窗口过程函数声明DWORD WINAPI  CreateWindowThread(LPVOID pParam);//“创建样本信息窗口”线程函数声明LRESULT CALLBACK LowLevelKeyboardProc(int  nCode, WPARAM wParam, LPARAM lParam);//钩子过程函数声明#pragma warning(disable:4355 4127)//禁用警告C4355CFilter::CFilter(LPWSTR lpName, LPUNKNOWN pUnk,HRESULT *phr) : CBaseFilter(lpName, pUnk, (CCritSec *) this, CLSID_GetSample)
{wmemset(FilterName,0,20);wcscat_s(FilterName,20,lpName);//将过滤器名称赋值给FilterNamewmemset(DirectoryName,0,MAX_PATH);wcscat_s(DirectoryName,MAX_PATH,L"D:\\");wcscat_s(DirectoryName,MAX_PATH, FilterName);//以过滤器名称,作为文件夹名称CreateDirectory(DirectoryName,NULL);//创建数据输出文件夹hHasCreate=CreateEvent( NULL, TRUE, FALSE, NULL); //创建事件,手动重置,初始状态无信号hSampleDlg=NULL;hEdit=NULL;hL=NULL;B100=TRUE;hFont1 = CreateFont(20,0,0,0,FW_DONTCARE,FALSE,FALSE,FALSE,DEFAULT_CHARSET,OUT_OUTLINE_PRECIS,CLIP_DEFAULT_PRECIS,CLEARTYPE_QUALITY, VARIABLE_PITCH,TEXT("微软雅黑"));hFont2 = CreateFont(18,0,0,0,FW_DONTCARE,FALSE,FALSE,FALSE,DEFAULT_CHARSET,OUT_OUTLINE_PRECIS,CLIP_DEFAULT_PRECIS,CLEARTYPE_QUALITY, VARIABLE_PITCH,TEXT("微软雅黑"));CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)CreateWindowThread,this,0,NULL);//创建“创建样本信息窗口”线程,将过滤器地址作为线程参数if(hHook==NULL)hHook = SetWindowsHookEx(WH_KEYBOARD_LL, &LowLevelKeyboardProc, (HINSTANCE)NULL, 0);//安装键盘消息钩子m_pInputPin = new CInputPin(this,phr,L"In");//创建输入引脚if(m_pInputPin == NULL){if (phr)*phr = E_OUTOFMEMORY;}
} CFilter::~CFilter()
{CloseHandle(hHasCreate);SendMessage(hSampleDlg,WM_CLOSE,0,0);//关闭样本信息窗口DestroyWindow(hSampleDlg);//销毁样本信息窗口NameArray.Delete(FilterName);//标记FileName中过滤器名称未使用FilterArray.Delete((DWORD*)this);//从数组中删除该过滤器指针if(FilterArray.GetCount()==0)//如果过滤器指针数组元素数为0{UnhookWindowsHookEx(hHook);//删除钩子hHook=NULL;UnregisterClass(L"样本信息窗口类", Hinstance);//删除窗口类注册}
}CUnknown * WINAPI CFilter::CreateInstance(LPUNKNOWN pUnk, HRESULT *phr)
{if(FilterArray.GetCount()==10){MessageBox(0,L"最多创建10个采样过滤器",0,MB_OK);*phr=S_FALSE;return NULL;}return new CFilter(NameArray.GetName(), pUnk, phr);//创建过滤器
} STDMETHODIMP CFilter::Run(REFERENCE_TIME tStart)
{HRESULT hr = NOERROR;hr = CBaseFilter::Run(tStart);if(FAILED(hr)) return hr;index=0;StartTime=timeGetTime();SendMessage(hL,LVM_DELETEALLITEMS,0,0);//在样本信息窗口中,删除样本参数列表所有项return NOERROR;
} STDMETHODIMP CFilter::JoinFilterGraph(IFilterGraph * pGraph, LPCWSTR pName)
{if(pGraph!=NULL){pName=FilterName;}return CBaseFilter::JoinFilterGraph(pGraph, pName);
}int CFilter::GetPinCount()
{return 1;
}CBasePin *CFilter::GetPin(int n)
{if(n != 0){return NULL;}return m_pInputPin;
} char* CFilter::GetString(GUID guid)//获取GUID定义字符串
{LPWSTR lp=NULL;HRESULT hr = StringFromCLSID(guid, (LPOLESTR*)&lp);//将GUID转换为字符串形式char* chX=new char[39];for(int i=0;i<39;i++){chX[i]=(char)lp[i];}CoTaskMemFree(lp);//释放StringFromCLSID分配的内存HRSRC hRes=FindResource(Hinstance,MAKEINTRESOURCE(IDR_DAT1),L"DAT");HGLOBAL hMem=LoadResource(Hinstance,hRes);BYTE* pb=(BYTE*)LockResource(hMem);//获取数据的起始内存地址DWORD count, LEN; char ch[39];CopyMemory(&count,pb,4);pb+=4;for (int i = 0; i < (int)count; i++){CopyMemory(&LEN,pb,4);pb+=4;char* pch = new char[LEN];CopyMemory(pch,pb,LEN);pb+=LEN;memset(ch, 0, 39);CopyMemory(ch,pb,39);pb+=39;if(strcoll(chX,ch)==0)//如果字符串相等{FreeResource(hMem);//释放资源delete[] chX;return pch;}delete[] pch;}FreeResource(hMem);//释放资源return chX;
}char* CFilter::GetMediaTypeString(const CMediaType *pmt)//获取媒体类型描述字符串
{char* ch=new char[2000];char* pMain=GetString(pmt->majortype);//主要类型char* pSub=GetString(pmt->subtype);//子类型char* pFormat=GetString(pmt->formattype);//格式类型memset(ch,0,2000);strcat_s(ch,2000,"主要类型:\t");//strcat_s在char字符串后附加字符串strcat_s(ch,2000,pMain);strcat_s(ch,2000,"\r\n");strcat_s(ch,2000,"子类型:\t\t");strcat_s(ch,2000,pSub);strcat_s(ch,2000,"\r\n");strcat_s(ch,2000,"格式类型:\t");strcat_s(ch,2000,pFormat);strcat_s(ch,2000,"\r\n");if(pmt->bFixedSizeSamples)strcat_s(ch,2000,"样本为固定大小:\tTRUE\r\n");elsestrcat_s(ch,2000,"样本为固定大小:\tFALSE\r\n");if(pmt->bTemporalCompression)strcat_s(ch,2000,"使用时间压缩:\tTRUE\r\n");elsestrcat_s(ch,2000,"使用时间压缩:\tFALSE\r\n");char cch[50];sprintf_s(cch,50, "格式块大小:\t%u\r\n",pmt->cbFormat);strcat_s(ch,2000,cch);delete[] pMain;delete[] pSub;delete[] pFormat;char* pFormatString=GetFormatString(pmt->formattype, pmt->pbFormat);strcat_s(ch,2000, pFormatString );delete[] pFormatString;return ch;
}char* CFilter::GetFormatString(GUID guid, BYTE* P)//获取格式结构描述字符串
{if(P==NULL)return NULL;char* cch=new char[1000];memset(cch,0,1000);if (guid == FORMAT_DvInfo){DVINFO* p = (DVINFO*)P;int  j;j  = sprintf_s( cch, 1000,     "格式结构:\tDVINFO\r\n");j += sprintf_s( cch + j, 1000 - j,  "\t\tdwDVAAuxSrc=%u\r\n", p->dwDVAAuxSrc );j += sprintf_s( cch + j, 1000 - j, "\t\tdwDVAAuxCtl=%u\r\n", p->dwDVAAuxCtl );j += sprintf_s( cch + j, 1000 - j,  "\t\tdwDVAAuxSrc1=%u\r\n", p->dwDVAAuxSrc1 );j += sprintf_s( cch + j, 1000 - j, "\t\tdwDVAAuxCtl1=%u\r\n", p->dwDVAAuxCtl1 );j += sprintf_s( cch + j, 1000 - j,  "\t\tdwDVVAuxSrc=%u\r\n", p->dwDVVAuxSrc );j += sprintf_s( cch + j, 1000 - j, "\t\tdwDVVAuxCtl=%u\r\n", p->dwDVVAuxCtl );j += sprintf_s( cch + j, 1000 - j, "\t\tdwDVReserved[0]=%u\r\n", p->dwDVReserved[0] );j += sprintf_s( cch + j, 1000 - j, "\t\tdwDVReserved[1]=%u\r\n", p->dwDVReserved[1] );}if (guid == FORMAT_MPEG2Video){MPEG2VIDEOINFO* p = (MPEG2VIDEOINFO*)P;int  j;j  = sprintf_s( cch, 1000,     "格式结构:\tMPEG2VIDEOINFO\r\n");j += sprintf_s( cch + j, 1000 - j,  "\t\thdr=VIDEOINFOHEADER2\r\n" );j += sprintf_s( cch + j, 1000 - j, "\t\thdr.rcSource={%d, ", p->hdr.rcSource.left );j += sprintf_s( cch + j, 1000 - j, "%d, ", p->hdr.rcSource.top );j += sprintf_s( cch + j, 1000 - j, "%d, ", p->hdr.rcSource.right );j += sprintf_s( cch + j, 1000 - j, "%d}\r\n", p->hdr.rcSource.bottom );j += sprintf_s( cch + j, 1000 - j,  "\t\thdr.rcTarget={%d, ", p->hdr.rcTarget.left );j += sprintf_s( cch + j, 1000 - j, "%d, ", p->hdr.rcTarget.top );j += sprintf_s( cch + j, 1000 - j, "%d, ", p->hdr.rcTarget.right );j += sprintf_s( cch + j, 1000 - j, "%d}\r\n", p->hdr.rcTarget.bottom );j += sprintf_s( cch + j, 1000 - j, "\t\thdr.dwBitRate=%u\r\n", p->hdr.dwBitRate );j += sprintf_s( cch + j, 1000 - j, "\t\thdr.dwBitErrorRate=%u\r\n", p->hdr.dwBitErrorRate );j += sprintf_s( cch + j, 1000 - j, "\t\thdr.AvgTimePerFrame=%I64d\r\n", p->hdr.AvgTimePerFrame );j += sprintf_s( cch + j, 1000 - j, "\t\thdr.dwInterlaceFlags=%u\r\n", p->hdr.dwInterlaceFlags );j += sprintf_s( cch + j, 1000 - j, "\t\thdr.dwCopyProtectFlags=%u\r\n", p->hdr.dwCopyProtectFlags );j += sprintf_s( cch + j, 1000 - j, "\t\thdr.dwPictAspectRatioX=%u\r\n", p->hdr.dwPictAspectRatioX );j += sprintf_s( cch + j, 1000 - j, "\t\thdr.dwPictAspectRatioY=%u\r\n", p->hdr.dwPictAspectRatioY );j += sprintf_s( cch + j, 1000 - j, "\t\thdr.dwControlFlags=%u\r\n", p->hdr.dwControlFlags );j += sprintf_s( cch + j, 1000 - j, "\t\thdr.dwReserved1=%u\r\n", p->hdr.dwReserved1 );j += sprintf_s( cch + j, 1000 - j, "\t\thdr.dwReserved2=%u\r\n", p->hdr.dwReserved2 );j += sprintf_s( cch + j, 1000 - j, "\t\thdr.bmiHeader=BITMAPINFOHEADER\r\n" );j += sprintf_s( cch + j, 1000 - j, "\t\thdr.bmiHeader.biSize=%u\r\n", p->hdr.bmiHeader.biSize );j += sprintf_s( cch + j, 1000 - j, "\t\thdr.bmiHeader.biWidth=%d\r\n", p->hdr.bmiHeader.biWidth );j += sprintf_s( cch + j, 1000 - j, "\t\thdr.bmiHeader.biHeight=%d\r\n", p->hdr.bmiHeader.biHeight );j += sprintf_s( cch + j, 1000 - j, "\t\thdr.bmiHeader.biPlanes=%d\r\n", p->hdr.bmiHeader.biPlanes );j += sprintf_s( cch + j, 1000 - j, "\t\thdr.bmiHeader.biBitCount=%d\r\n", p->hdr.bmiHeader.biBitCount );j += sprintf_s( cch + j, 1000 - j, "\t\thdr.bmiHeader.biCompression=%u\r\n", p->hdr.bmiHeader.biCompression );j += sprintf_s( cch + j, 1000 - j, "\t\thdr.bmiHeader.biSizeImage=%u\r\n", p->hdr.bmiHeader.biSizeImage );j += sprintf_s( cch + j, 1000 - j, "\t\thdr.bmiHeader.biXPelsPerMeter=%d\r\n", p->hdr.bmiHeader.biXPelsPerMeter );j += sprintf_s( cch + j, 1000 - j, "\t\thdr.bmiHeader.biYPelsPerMeter=%d\r\n", p->hdr.bmiHeader.biYPelsPerMeter );j += sprintf_s( cch + j, 1000 - j, "\t\thdr.bmiHeader.biClrUsed=%u\r\n", p->hdr.bmiHeader.biClrUsed );j += sprintf_s( cch + j, 1000 - j, "\t\thdr.bmiHeader.biClrImportant=%u\r\n", p->hdr.bmiHeader.biClrImportant );j += sprintf_s( cch + j, 1000 - j, "\t\tdwStartTimeCode=%u\r\n", p->dwStartTimeCode );j += sprintf_s( cch + j, 1000 - j, "\t\tcbSequenceHeader=%u\r\n", p->cbSequenceHeader );j += sprintf_s( cch + j, 1000 - j, "\t\tdwProfile=%u\r\n", p->dwProfile );j += sprintf_s( cch + j, 1000 - j, "\t\tdwLevel=%u\r\n", p->dwLevel );j += sprintf_s( cch + j, 1000 - j, "\t\tdwFlags=%u\r\n", p->dwFlags );j += sprintf_s( cch + j, 1000 - j, "\t\tdwSequenceHeader=%u\r\n", p->dwSequenceHeader );}if (guid == FORMAT_MPEGStreams){AM_MPEGSYSTEMTYPE* p=(AM_MPEGSYSTEMTYPE*)P;int  j;j  = sprintf_s( cch, 1000,     "格式结构:\tAM_MPEGSYSTEMTYPE\r\n");j += sprintf_s( cch + j, 1000 - j, "\t\tdwBitRate=%u\r\n", p->dwBitRate );j += sprintf_s( cch + j, 1000 - j, "\t\tcStreams=%u\r\n", p->cStreams );    AM_MPEGSTREAMTYPE* pAm=p->Streams;j += sprintf_s( cch + j, 1000 - j, "\t\tStreams[n]=AM_MPEGSTREAMTYPE\r\n");j += sprintf_s( cch + j, 1000 - j, "\t\tStreams[0].dwStreamID=%u\r\n", pAm->dwStreamId );j += sprintf_s( cch + j, 1000 - j, "\t\tStreams[0].dwReserved=%u\r\n", pAm->dwReserved );j += sprintf_s( cch + j, 1000 - j, "\t\tStreams[0].mt=AM_MEDIA_TYPE\r\n");j += sprintf_s( cch + j, 1000 - j, "\t\tStreams[0].bFormat=%u\r\n", pAm->bFormat);for(int i=1;i<(int)(p->cStreams);i++){pAm=AM_MPEGSTREAMTYPE_NEXT(pAm);j += sprintf_s( cch + j, 1000 - j, "\t\tStreams[%d]", i );j += sprintf_s( cch + j, 1000 - j, ".dwStreamID=%u\r\n", pAm->dwStreamId );j += sprintf_s( cch + j, 1000 - j, "\t\tStreams[%d]", i );j += sprintf_s( cch + j, 1000 - j, ".dwReserved=%u\r\n", pAm->dwReserved );            j += sprintf_s( cch + j, 1000 - j, "\t\tStreams[%d]", i );j += sprintf_s( cch + j, 1000 - j, ".mt=AM_MEDIA_TYPE\r\n");j += sprintf_s( cch + j, 1000 - j, "\t\tStreams[%d]", i );j += sprintf_s( cch + j, 1000 - j, ".bFormat=%u\r\n", pAm->bFormat);}}if (guid == FORMAT_MPEGVideo){MPEG1VIDEOINFO* p = (MPEG1VIDEOINFO*)P;int  j;j  = sprintf_s( cch, 1000,     "格式结构:\tMPEG1VIDEOINFO\r\n");j += sprintf_s( cch + j, 1000 - j, "\t\thdr=VIDEOINFOHEADER\r\n");j += sprintf_s( cch + j, 1000 - j, "\t\thdr.rcSource={%d, ", p->hdr.rcSource.left );j += sprintf_s( cch + j, 1000 - j, "%d, ", p->hdr.rcSource.top );j += sprintf_s( cch + j, 1000 - j, "%d, ", p->hdr.rcSource.right );j += sprintf_s( cch + j, 1000 - j, "%d}\r\n", p->hdr.rcSource.bottom );j += sprintf_s( cch + j, 1000 - j,  "\t\thdr.rcTarget={%d, ", p->hdr.rcTarget.left );j += sprintf_s( cch + j, 1000 - j, "%d, ", p->hdr.rcTarget.top );j += sprintf_s( cch + j, 1000 - j, "%d, ", p->hdr.rcTarget.right );j += sprintf_s( cch + j, 1000 - j, "%d}\r\n", p->hdr.rcTarget.bottom );j += sprintf_s( cch + j, 1000 - j, "\t\thdr.dwBitRate=%u\r\n", p->hdr.dwBitRate );j += sprintf_s( cch + j, 1000 - j, "\t\thdr.dwBitErrorRate=%u\r\n", p->hdr.dwBitErrorRate );j += sprintf_s( cch + j, 1000 - j, "\t\thdr.AvgTimePerFrame=%I64d\r\n", p->hdr.AvgTimePerFrame );j += sprintf_s( cch + j, 1000 - j, "\t\thdr.bmiHeader=BITMAPINFOHEADER\r\n" );j += sprintf_s( cch + j, 1000 - j, "\t\thdr.bmiHeader.biSize=%u\r\n", p->hdr.bmiHeader.biSize );j += sprintf_s( cch + j, 1000 - j, "\t\thdr.bmiHeader.biWidth=%d\r\n", p->hdr.bmiHeader.biWidth );j += sprintf_s( cch + j, 1000 - j, "\t\thdr.bmiHeader.biHeight=%d\r\n", p->hdr.bmiHeader.biHeight );j += sprintf_s( cch + j, 1000 - j, "\t\thdr.bmiHeader.biPlanes=%d\r\n", p->hdr.bmiHeader.biPlanes );j += sprintf_s( cch + j, 1000 - j, "\t\thdr.bmiHeader.biBitCount=%d\r\n", p->hdr.bmiHeader.biBitCount );j += sprintf_s( cch + j, 1000 - j, "\t\thdr.bmiHeader.biCompression=%u\r\n", p->hdr.bmiHeader.biCompression);j += sprintf_s( cch + j, 1000 - j, "\t\thdr.bmiHeader.biSizeImage=%u\r\n", p->hdr.bmiHeader.biSizeImage );j += sprintf_s( cch + j, 1000 - j, "\t\thdr.bmiHeader.biXPelsPerMeter=%d\r\n", p->hdr.bmiHeader.biXPelsPerMeter );j += sprintf_s( cch + j, 1000 - j, "\t\thdr.bmiHeader.biYPelsPerMeter=%d\r\n", p->hdr.bmiHeader.biYPelsPerMeter );j += sprintf_s( cch + j, 1000 - j, "\t\thdr.bmiHeader.biClrUsed=%u\r\n", p->hdr.bmiHeader.biClrUsed );j += sprintf_s( cch + j, 1000 - j, "\t\thdr.bmiHeader.biClrImportant=%u\r\n", p->hdr.bmiHeader.biClrImportant );j += sprintf_s( cch + j, 1000 - j, "\t\tdwStartTimeCode=%u\r\n", p->dwStartTimeCode );j += sprintf_s( cch + j, 1000 - j, "\t\tcbSequenceHeader=%u\r\n", p->cbSequenceHeader );j += sprintf_s( cch + j, 1000 - j, "\t\tbSequenceHeader=%u\r\n", p->bSequenceHeader );}if(guid==FORMAT_VideoInfo){VIDEOINFOHEADER* p = (VIDEOINFOHEADER*)P;int  j;j  = sprintf_s( cch, 1000,     "格式结构:\tVIDEOINFOHEADER\r\n");j += sprintf_s( cch + j, 1000 - j,     "\t\trcSource={%d, ", p->rcSource.left );j += sprintf_s( cch + j, 1000 - j, "%d, ", p->rcSource.top );j += sprintf_s( cch + j, 1000 - j, "%d, ", p->rcSource.right );j += sprintf_s( cch + j, 1000 - j, "%d}\r\n", p->rcSource.bottom );j += sprintf_s( cch + j, 1000 - j,  "\t\trcTarget={%d, ", p->rcTarget.left );j += sprintf_s( cch + j, 1000 - j, "%d, ", p->rcTarget.top );j += sprintf_s( cch + j, 1000 - j, "%d, ", p->rcTarget.right );j += sprintf_s( cch + j, 1000 - j, "%d}\r\n", p->rcTarget.bottom );j += sprintf_s( cch + j, 1000 - j, "\t\tdwBitRate=%u\r\n", p->dwBitRate );j += sprintf_s( cch + j, 1000 - j, "\t\tdwBitErrorRate=%u\r\n", p->dwBitErrorRate );j += sprintf_s( cch + j, 1000 - j, "\t\tAvgTimePerFrame=%I64d\r\n", p->AvgTimePerFrame );j += sprintf_s( cch + j, 1000 - j, "\t\tbmiHeader=BITMAPINFOHEADER\r\n" );j += sprintf_s( cch + j, 1000 - j, "\t\tbmiHeader.biSize=%u\r\n", p->bmiHeader.biSize );j += sprintf_s( cch + j, 1000 - j, "\t\tbmiHeader.biWidth=%d\r\n", p->bmiHeader.biWidth );j += sprintf_s( cch + j, 1000 - j, "\t\tbmiHeader.biHeight=%d\r\n", p->bmiHeader.biHeight );j += sprintf_s( cch + j, 1000 - j, "\t\tbmiHeader.biPlanes=%d\r\n", p->bmiHeader.biPlanes );j += sprintf_s( cch + j, 1000 - j, "\t\tbmiHeader.biBitCount=%d\r\n", p->bmiHeader.biBitCount );j += sprintf_s( cch + j, 1000 - j, "\t\tbmiHeader.biCompression=%u\r\n", p->bmiHeader.biCompression);j += sprintf_s( cch + j, 1000 - j, "\t\tbmiHeader.biSizeImage=%u\r\n", p->bmiHeader.biSizeImage );j += sprintf_s( cch + j, 1000 - j, "\t\tbmiHeader.biXPelsPerMeter=%d\r\n", p->bmiHeader.biXPelsPerMeter );j += sprintf_s( cch + j, 1000 - j, "\t\tbmiHeader.biYPelsPerMeter=%d\r\n", p->bmiHeader.biYPelsPerMeter );j += sprintf_s( cch + j, 1000 - j, "\t\tbmiHeader.biClrUsed=%u\r\n", p->bmiHeader.biClrUsed );j += sprintf_s( cch + j, 1000 - j, "\t\tbmiHeader.biClrImportant=%u\r\n", p->bmiHeader.biClrImportant );}if (guid == FORMAT_VideoInfo2){VIDEOINFOHEADER2* p=(VIDEOINFOHEADER2*)P;int  j;j  = sprintf_s( cch, 1000,     "格式结构:\tVIDEOINFOHEADER2\r\n" );j += sprintf_s( cch + j, 1000 - j, "\t\trcSource={%d, ", p->rcSource.left );j += sprintf_s( cch + j, 1000 - j, "%d, ", p->rcSource.top );j += sprintf_s( cch + j, 1000 - j, "%d, ", p->rcSource.right );j += sprintf_s( cch + j, 1000 - j, "%d}\r\n", p->rcSource.bottom );j += sprintf_s( cch + j, 1000 - j,  "\t\trcTarget={%d, ", p->rcTarget.left );j += sprintf_s( cch + j, 1000 - j, "%d, ", p->rcTarget.top );j += sprintf_s( cch + j, 1000 - j, "%d, ", p->rcTarget.right );j += sprintf_s( cch + j, 1000 - j, "%d}\r\n", p->rcTarget.bottom );j += sprintf_s( cch + j, 1000 - j, "\t\tdwBitRate=%u\r\n", p->dwBitRate );j += sprintf_s( cch + j, 1000 - j, "\t\tdwBitErrorRate=%u\r\n", p->dwBitErrorRate );j += sprintf_s( cch + j, 1000 - j, "\t\tAvgTimePerFrame=%I64d\r\n", p->AvgTimePerFrame );j += sprintf_s( cch + j, 1000 - j, "\t\tdwInterlaceFlags=%u\r\n", p->dwInterlaceFlags );j += sprintf_s( cch + j, 1000 - j, "\t\tdwCopyProtectFlags=%u\r\n", p->dwCopyProtectFlags );j += sprintf_s( cch + j, 1000 - j, "\t\tdwPictAspectRatioX=%u\r\n", p->dwPictAspectRatioX );j += sprintf_s( cch + j, 1000 - j, "\t\tdwPictAspectRatioY=%u\r\n", p->dwPictAspectRatioY );j += sprintf_s( cch + j, 1000 - j, "\t\tdwControlFlags=%u\r\n", p->dwControlFlags );j += sprintf_s( cch + j, 1000 - j, "\t\tdwReserved1=%u\r\n", p->dwReserved1 );j += sprintf_s( cch + j, 1000 - j, "\t\tdwReserved2=%u\r\n", p->dwReserved2 );j += sprintf_s( cch + j, 1000 - j, "\t\tbmiHeader=BITMAPINFOHEADER\r\n" );j += sprintf_s( cch + j, 1000 - j, "\t\tbmiHeader.biSize=%u\r\n", p->bmiHeader.biSize );j += sprintf_s( cch + j, 1000 - j, "\t\tbmiHeader.biWidth=%d\r\n", p->bmiHeader.biWidth );j += sprintf_s( cch + j, 1000 - j, "\t\tbmiHeader.biHeight=%d\r\n", p->bmiHeader.biHeight );j += sprintf_s( cch + j, 1000 - j, "\t\tbmiHeader.biPlanes=%d\r\n", p->bmiHeader.biPlanes );j += sprintf_s( cch + j, 1000 - j, "\t\tbmiHeader.biBitCount=%d\r\n", p->bmiHeader.biBitCount );j += sprintf_s( cch + j, 1000 - j, "\t\tbmiHeader.biCompression=%u\r\n", p->bmiHeader.biCompression );j += sprintf_s( cch + j, 1000 - j, "\t\tbmiHeader.biSizeImage=%u\r\n", p->bmiHeader.biSizeImage );j += sprintf_s( cch + j, 1000 - j, "\t\tbmiHeader.biXPelsPerMeter=%d\r\n", p->bmiHeader.biXPelsPerMeter );j += sprintf_s( cch + j, 1000 - j, "\t\tbmiHeader.biYPelsPerMeter=%d\r\n", p->bmiHeader.biYPelsPerMeter );j += sprintf_s( cch + j, 1000 - j, "\t\tbmiHeader.biClrUsed=%u\r\n", p->bmiHeader.biClrUsed );j += sprintf_s( cch + j, 1000 - j, "\t\tbmiHeader.biClrImportant=%u\r\n", p->bmiHeader.biClrImportant );}if (guid == FORMAT_WaveFormatEx){WAVEFORMATEX* p = (WAVEFORMATEX*)P;int  j;j  = sprintf_s( cch, 1000,     "格式结构:\tWAVEFORMATEX\r\n" );j += sprintf_s( cch + j, 1000 - j, "\t\twFormatTag=%d\r\n", p->wFormatTag );j += sprintf_s( cch + j, 1000 - j, "\t\tnChannels=%d\r\n", p->nChannels );j += sprintf_s( cch + j, 1000 - j, "\t\tnSamplesPerSec=%u\r\n", p->nSamplesPerSec );j += sprintf_s( cch + j, 1000 - j, "\t\tnAvgBytesPerSec=%u\r\n", p->nAvgBytesPerSec );j += sprintf_s( cch + j, 1000 - j, "\t\tnBlockAlign=%d\r\n", p->nBlockAlign );j += sprintf_s( cch + j, 1000 - j, "\t\twBitsPerSample=%d\r\n", p->wBitsPerSample );j += sprintf_s( cch + j, 1000 - j, "\t\tcbSize=%d\r\n", p->cbSize );}return cch;
}void DeleteAllSamples(int sel)//删除数据输出文件夹中所有样本数据函数
{CFilter* m_pCFilter=(CFilter*)FilterArray.GetAt(sel);SHFILEOPSTRUCT ss;ss.hwnd=NULL;ss.wFunc =FO_DELETE;wchar_t wch[MAX_PATH];wmemset(wch,0,MAX_PATH);wcscat_s(wch,MAX_PATH,m_pCFilter->DirectoryName);wcscat_s(wch,MAX_PATH,L"\\*.dat");ss.pFrom =wch;ss.pTo =NULL;ss.fFlags=FOF_FILESONLY|FOF_SILENT;ss.fAnyOperationsAborted=NULL;ss.hNameMappings=NULL;ss.lpszProgressTitle=NULL;SHFileOperation(&ss);
}COLORREF color1=RGB(230,210,182),color2=RGB(100,90,70),color3=RGB(240,255,255);
LRESULT CALLBACK WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)//样本信息窗口过程函数
{int sel;//窗口在”过滤器指针数组“中的索引CFilter* m_pCFilter=NULL;HBRUSH hbrBkgnd=NULL,hbrBkgnd2=NULL,hbrBtn=NULL;for(int i=0;i<FilterArray.GetCount();i++)//确定窗口在”过滤器指针数组“中的索引{m_pCFilter=(CFilter*)FilterArray.GetAt(i);if(m_pCFilter!=NULL){if(m_pCFilter->hSampleDlg==hwnd)//如果”过滤器指针数组“中的某项的样本列表窗口句柄,等于hwnd{sel=i;break;//确定句柄为hwnd的窗口的索引}}}    switch(uMsg){case WM_COMMAND:switch(HIWORD(wParam)) {case BN_CLICKED:{if(m_pCFilter==NULL)break;if((HWND)lParam==m_pCFilter->hwndButton)//如果点击了“更改”按钮{BROWSEINFO bi;char buffer[MAX_PATH];ZeroMemory(buffer, MAX_PATH);bi.hwndOwner = NULL;bi.pidlRoot = NULL;bi.pszDisplayName = LPWSTR(buffer);bi.lpszTitle = L"选择一个文件夹";bi.ulFlags = BIF_EDITBOX;   bi.lpfn = NULL;bi.lParam = 0;bi.iImage = 0;LPITEMIDLIST pList = NULL;if ((pList = SHBrowseForFolder(&bi)) != NULL){wmemset(m_pCFilter->DirectoryName,0,MAX_PATH);SHGetPathFromIDList(pList, m_pCFilter->DirectoryName);size_t len=wcslen(m_pCFilter->DirectoryName);if(m_pCFilter->DirectoryName[len-1]!='\\')//如果最后一个字符不是"\"wcscat_s(m_pCFilter->DirectoryName,MAX_PATH, L"\\");//在字符串后面添加"\"wcscat_s(m_pCFilter->DirectoryName,MAX_PATH, m_pCFilter->FilterName);wchar_t wchPathName[MAX_PATH]=L" 输出文件夹:  ";wcscat_s(wchPathName,MAX_PATH,m_pCFilter->DirectoryName);SendMessage(m_pCFilter->hPathEdit,WM_SETTEXT,0,(LPARAM)wchPathName);CreateDirectory(m_pCFilter->DirectoryName,NULL);//创建数据输出文件夹}}}break;}switch(LOWORD(wParam)) //响应点击菜单项{ case ID_Menu: //”清空列表“if(m_pCFilter==NULL)break;SendMessage(m_pCFilter->hL,LVM_DELETEALLITEMS,0,0);//列表视图删除所有项break; case ID_40005: //”删除所有样本数据“if(m_pCFilter==NULL)break;DeleteAllSamples(sel);//删除所有样本数据break;case ID_40006: //”最多获取100个样本“if(m_pCFilter==NULL)break;if(m_pCFilter->B100){CheckMenuItem(m_pCFilter->hMenu,ID_40006,MF_UNCHECKED);m_pCFilter->B100=FALSE;}else{CheckMenuItem(m_pCFilter->hMenu,ID_40006,MF_CHECKED);m_pCFilter->B100=TRUE;}break;case ID_40002: //”不获取样本数据“if(m_pCFilter==NULL)break;m_pCFilter->Setup=0;CheckMenuItem(m_pCFilter->hMenu,ID_40002,MF_CHECKED);CheckMenuItem(m_pCFilter->hMenu,ID_40003,MF_UNCHECKED);CheckMenuItem(m_pCFilter->hMenu,ID_40004,MF_UNCHECKED);break; case ID_40003: //”只获取同步点样本数据“if(m_pCFilter==NULL)break;m_pCFilter->Setup=1;CheckMenuItem(m_pCFilter->hMenu,ID_40003,MF_CHECKED);CheckMenuItem(m_pCFilter->hMenu,ID_40002,MF_UNCHECKED);CheckMenuItem(m_pCFilter->hMenu,ID_40004,MF_UNCHECKED);break; case ID_40004: //”获取所有样本数据“if(m_pCFilter==NULL)break;m_pCFilter->Setup=2;CheckMenuItem(m_pCFilter->hMenu,ID_40004,MF_CHECKED);CheckMenuItem(m_pCFilter->hMenu,ID_40002,MF_UNCHECKED);CheckMenuItem(m_pCFilter->hMenu,ID_40003,MF_UNCHECKED);break; default:break; } case WM_CTLCOLORSTATIC://绘制只读编辑控件{if(m_pCFilter==NULL)break;HDC hdcStatic = (HDC) wParam;if((HWND)lParam==m_pCFilter->hEdit)//绘制显示媒体类型编辑框{SetTextColor(hdcStatic, color3);SetBkColor(hdcStatic, color2);if (hbrBkgnd == NULL){hbrBkgnd = CreateSolidBrush(color2);}return (INT_PTR)hbrBkgnd;}if((HWND)lParam==m_pCFilter->hPathEdit)//绘制显示输出文件夹路径编辑框{SetTextColor(hdcStatic, RGB(123,36,6));SetBkColor(hdcStatic, color1);if (hbrBkgnd2 == NULL){hbrBkgnd2 = CreateSolidBrush(color1);}return (INT_PTR)hbrBkgnd2;}}break;case WM_CTLCOLORBTN://绘制按钮{if(m_pCFilter==NULL)break;HDC hdcBtn = (HDC)wParam;HWND hBtn=(HWND)lParam;SetBkColor(hdcBtn, color1);SetTextColor(hdcBtn,RGB(123,36,6));RECT rect;GetClientRect(hBtn,&rect);SelectObject(hdcBtn,m_pCFilter->hFont2);DrawText(hdcBtn,L"更改",2,&rect,DT_CENTER|DT_VCENTER|DT_SINGLELINE);if(hbrBtn==NULL){hbrBtn= CreateSolidBrush(color1);}return (INT_PTR)hbrBtn;}break;case WM_CLOSE://点击了样本窗口关闭按钮ShowWindow(hwnd, SW_HIDE);//隐藏窗口return 0;//不调用DefWindowProc,防止销毁窗口}return DefWindowProc(hwnd, uMsg, wParam, lParam);
}DWORD WINAPI  CreateWindowThread(LPVOID pParam)//创建"样本信息窗口”线程函数,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(color2);wcx.hbrBackground = hBrush;  //背景笔刷wcx.lpszMenuName = L"MainMenu"; //菜单资源名称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));//加载菜单int ScreenWidth=GetSystemMetrics(SM_CXSCREEN);//获取主显示器的宽度,以像素为单位int ScreenHeight=GetSystemMetrics(SM_CYSCREEN);//获取主显示器的高度,以像素为单位int Width=600;int Height=800;//窗口的宽高HWND hwnd= CreateWindowEx(//创建"样本信息窗口"0,                      //没有扩展样式      L"样本信息窗口类",       //类名                p->FilterName,          //窗口名称         WS_SYSMENU|WS_CAPTION|WS_CLIPCHILDREN|WS_MINIMIZEBOX|WS_POPUP,   //窗口样式      (ScreenWidth-Width)/2,    //水平居中(ScreenHeight-Height)/2,  //垂直居中Width,           //宽度        Height,          //高度       (HWND)NULL,      //没有父窗口或所有者窗口p->hMenu,        //使用的菜单      Hinstance,       //实例句柄     NULL);           //没有窗口创建数据RECT rect;GetClientRect(hwnd,&rect);wchar_t wchPathName[MAX_PATH]=L" 输出文件夹:  ";wcscat_s(wchPathName,MAX_PATH,p->DirectoryName);p->hPathEdit=CreateWindow(L"Edit", wchPathName,WS_CHILD|WS_VISIBLE| ES_READONLY ,5,5,rect.right-51,20,hwnd,NULL,Hinstance,NULL);//创建路径编辑框SendMessage(p->hPathEdit,WM_SETFONT,(WPARAM)p->hFont2,0);//给路径编辑框设置字体p->hwndButton = CreateWindow(L"BUTTON", L"更改", WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON|BS_OWNERDRAW , rect.right-45, 5, 40, 20, hwnd, NULL, Hinstance, NULL);//创建按钮p->hEdit=CreateWindow(L"Edit",NULL,WS_CHILD|WS_VISIBLE|WS_VSCROLL|ES_MULTILINE| ES_READONLY ,5,30,rect.right-10,120,hwnd,NULL,Hinstance,NULL);//创建编辑框SendMessage(p->hEdit,WM_SETFONT,(WPARAM)p->hFont1,0);//给编辑框设置字体p->hL=CreateWindow(L"SysListView32",NULL,WS_CHILD|WS_VISIBLE|LVS_REPORT|LVS_SINGLESEL|LVS_NOSORTHEADER  ,5,155, rect.right-10,rect.bottom-160,hwnd,NULL,Hinstance,NULL);//创建列表视图控件LVCOLUMN LV;LV.mask=LVCF_WIDTH|LVCF_TEXT;LV.pszText=L"参数";LV.cx=140;SendMessage(p->hL,LVM_INSERTCOLUMN,(WPARAM)0,(LPARAM)&LV);//列表视图控件添加第1列LV.pszText=L"值";LV.cx=240;SendMessage(p->hL,LVM_INSERTCOLUMN,(WPARAM)1,(LPARAM)&LV);//列表视图控件添加第2列LV.pszText=L"说明";LV.cx=260;SendMessage(p->hL,LVM_INSERTCOLUMN,(WPARAM)2,(LPARAM)&LV);//列表视图控件添加第3列SendMessage(p->hL,LVM_SETBKCOLOR,0,(LPARAM)color1);//设置列表视图控件背景色SendMessage(p->hL,LVM_SETTEXTBKCOLOR,0,(LPARAM)color1);//设置列表视图控件文本背景色SendMessage(p->hL,LVM_SETTEXTCOLOR,0,(LPARAM)RGB(123,36,6));//设置列表视图控件文本颜色FilterArray.Add((DWORD*)p);//将过滤器指针添加到数组p->hSampleDlg=hwnd;SetEvent(p->hHasCreate);//发送"样本信息窗口创建完成"信号MSG msg;BOOL fGotMessage;while ((fGotMessage = GetMessage(&msg, hwnd, 0, 0)) != 0 && fGotMessage != -1) { TranslateMessage(&msg); DispatchMessage(&msg); } return 1;
}LRESULT CALLBACK LowLevelKeyboardProc(int  nCode, WPARAM wParam, LPARAM lParam)//键盘消息钩子过程
{if (nCode < 0)   //不处理消息return CallNextHookEx(hHook, nCode, wParam, lParam); KBDLLHOOKSTRUCT* p=(KBDLLHOOKSTRUCT*)lParam;if(wParam==WM_KEYDOWN){if(p->vkCode==113 && p->flags==0)//如果按下F2键{for(int i=0;i<FilterArray.GetCount();i++){CFilter* m_pCFilter=(CFilter*)FilterArray.GetAt(i);if(m_pCFilter!=NULL){ShowWindow(m_pCFilter->hSampleDlg, SW_SHOWDEFAULT);//显示"样本信息窗口”UpdateWindow(m_pCFilter->hSampleDlg);SendMessage(m_pCFilter->hEdit,EM_SETSEL,0,0);//设置编辑框插入符的位置为0}}}}return CallNextHookEx(hHook, nCode, wParam, lParam);
}

输入引脚头文件:CInputPin.h

#ifndef  PIN_FILE
#define PIN_FILE#include "GetSample.h"
#include "CFilter.h"class CInputPin : public CBaseInputPin
{friend class CFilter;CFilter *pCFilter;
public:CInputPin(CFilter *pFilter, HRESULT *phr, LPCWSTR pPinName);~CInputPin();HRESULT CheckConnect(IPin *pPin);HRESULT CheckMediaType(const CMediaType *pmt);HRESULT SetMediaType(const CMediaType *pmt);STDMETHODIMP Receive(IMediaSample *pSample);BOOL B_Pause;//为TRUE,表示过滤器处于暂停状态,FALSE运行或停止
}; class CPtr//用于保存媒体类型描述字符串和格式类型的数组类
{public:struct item{char* p1;char* p2;char* p3;char* p4;AM_MEDIA_TYPE* pmt;};CPtr();int Count;DWORD adres[300];void Add(char* pch1, char* pch2, char* pch3, char* pch4, AM_MEDIA_TYPE* pmt);void DeleteAll();item* GetAt(int i);
};#endif //PIN_FILE

输入引脚源文件:CInputPin.cpp

#include "CInputPin.h"
#include "Commctrl.h"
#include "wchar.h"
#include "stdio.h"CPtr::CPtr()//构造函数
{Count=0;
}void CPtr::Add(char* pch1,char* pch2,char* pch3,char* pch4, AM_MEDIA_TYPE* pmt)//向数组添加项
{if(Count==300){MessageBox(0,L"媒体类型数量不可大于300",0,MB_OK);return;}item* p=new item();p->p1=pch1;p->p2=pch2;p->p3=pch3;p->p4=pch4; p->pmt=pmt;adres[Count]=(DWORD)p;Count++;
}void _FreeMediaType(AM_MEDIA_TYPE& mt)//释放媒体类型的格式块。
{if (mt.cbFormat != 0){CoTaskMemFree((PVOID)mt.pbFormat);mt.cbFormat = 0;mt.pbFormat = NULL;}if (mt.pUnk != NULL){mt.pUnk->Release();mt.pUnk = NULL;}
}void _DeleteMediaType(AM_MEDIA_TYPE* pmt)//删除在堆上分配的媒体类型结构
{if (pmt != NULL){_FreeMediaType(*pmt);CoTaskMemFree(pmt);}
}void CPtr::DeleteAll()//删除数组所有项
{for(int i=0;i<Count;i++){item* p=(item*)adres[i];delete[] p->p1;delete[] p->p2;delete[] p->p3;delete[] p->p4; _DeleteMediaType(p->pmt);//必须删除获取到的媒体类型结构,包括它的格式块delete p;}Count = 0;
}CPtr::item* CPtr::GetAt(int i)//获取指定位置的项
{CPtr::item* p=(CPtr::item*)adres[i];return p;
}CPtr ptr;//媒体类型描述字符串和格式类型的数组类对象extern HINSTANCE Hinstance;//DLL模块句柄BOOL Check;//判断是否已使用媒体类型初始化列表。TRUE已初始化,FALSE未初始化
UINT Timer;//计时器标识INT_PTR CALLBACK DialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);//选择媒体类型模态对话框过程函数声明CInputPin::CInputPin(CFilter *pFilter, HRESULT *phr, LPCWSTR pPinName) : CBaseInputPin(NAME("In"), pFilter, pFilter, phr, pPinName)//输入引脚构造函数
{pCFilter = pFilter;pCFilter->sel=0;Check=FALSE;//将选择标记重置为FALSEptr.DeleteAll();//删除数组中的所有媒体类型信息B_Pause=FALSE;
} CInputPin::~CInputPin()//输入引脚析构函数
{ptr.DeleteAll();//删除数组中的所有媒体类型信息
}HRESULT CInputPin::CheckConnect(IPin* pPin)
{HRESULT hr;if(ptr.Count==0)//因为CheckConnect可能多次调用,只在“媒体类型描述字符串和格式类型数组“为空时,获取与此引脚连接的输出引脚的所有允许的媒体类型{IEnumMediaTypes* pEnum = NULL;hr = pPin->EnumMediaTypes(&pEnum);if (FAILED(hr))return hr;AM_MEDIA_TYPE* pmt = NULL; while (hr = pEnum->Next(1, &pmt, NULL), hr == S_OK)//获取与此引脚连接的输出引脚的所有允许的媒体类型{char* pMain=pCFilter->GetString(pmt->majortype);//获取主要类型字符串char* pSub=pCFilter->GetString(pmt->subtype);//获取子类型字符串char* pFormat=pCFilter->GetString(pmt->formattype);//获取格式类型字符串char* pFormatString=pCFilter->GetFormatString(pmt->formattype, pmt->pbFormat);//获取格式结构参数字符串ptr.Add(pMain, pSub, pFormat, pFormatString, pmt);//添加到“媒体类型描述字符串和格式类型数组“}pEnum->Release();Check=TRUE;//标记已选择了媒体类型}return CBasePin::CheckConnect(pPin);
}VOID CALLBACK TimerProc(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime)//计时器回调函数
{KillTimer(NULL,Timer);//销毁计时器ptr.DeleteAll();//删除数组中的所有媒体类型信息
}HRESULT CInputPin::CheckMediaType(const CMediaType *pmt)
{if(ptr.Count==0)return S_FALSE;if(Check){if(ptr.Count==1)//只有1个媒体类型,不显示媒体类型选择对话框{pCFilter->sel=0;//将选择索引置为选择第1项}else if(ptr.Count>1)//有1个以上的媒体类型,显示媒体类型选择对话框{DialogBoxParam(Hinstance,MAKEINTRESOURCE(IDD_DIALOG1),NULL,(DLGPROC)DialogProc,(LPARAM)pCFilter);//显示媒体类型选择模态对话框。将过滤器指针作为参数传递给对话框}Check=FALSE;//确保媒体类型选择模态对话框,只显示一次Timer=SetTimer(NULL,0,1000,(TIMERPROC)TimerProc);//确保1秒内,不再显示媒体类型选择对话框}CPtr::item* p=ptr.GetAt(pCFilter->sel);//获取选择的媒体类型项CMediaType cmt(*(p->pmt));//转换为CMediaType对象if(cmt.MatchesPartial(pmt))//如果选定的媒体类型与pmt匹配{return S_OK;//返回S_OK,确定连接使用的媒体类型}return S_FALSE;
} HRESULT CInputPin::SetMediaType(const CMediaType *pmt)
{WaitForSingleObject(pCFilter->hHasCreate,INFINITE);//等待样本对话框创建完成char* String=pCFilter->GetMediaTypeString(pmt);SendMessageA(pCFilter->hEdit,WM_SETTEXT,0,(LPARAM)String);//在编辑框中设置媒体类型描述文本delete[] String;return CBaseInputPin::SetMediaType(pmt);
} HRESULT CInputPin::Receive(IMediaSample * pSample)//接收函数
{DWORD T=timeGetTime()-pCFilter->StartTime;//调用时间,单位毫秒HRESULT hr;pCFilter->index++;BYTE* pBuffer=NULL;hr=pSample->GetPointer(&pBuffer);//获取样本缓冲区的指针long BufferSize=pSample->GetSize();//缓冲区的大小long Len=pSample->GetActualDataLength();//有效数据的长度hr=pSample->IsSyncPoint();//同步点Agan:FILTER_STATE fs;m_pFilter->GetState(0,&fs);//获取过滤器状态switch(fs){case State_Stopped:B_Pause=FALSE;return E_FAIL;case State_Paused:if(B_Pause==FALSE)//当过滤器处于暂停状态,Receive函数还可以执行一次。(设置此代码原因:运行过滤器图后,Receive函数的首次调用,过滤器仍处于暂停状态){B_Pause=TRUE;}else//暂停状态下,Receive函数的第2次调用被阻塞{goto Agan;}break;case State_Running:B_Pause=FALSE;break;}wchar_t wch[100]=L"样本";wchar_t wch1[100];wchar_t wch2[100];wmemset(wch1,0,100);_itow_s(pCFilter->index,wch1,10);wcscat_s(wch,100,wch1);//在wch后附加字符串if(pCFilter->B100 && pCFilter->index>100)return S_OK;//如果限制样本数量为100个,不再获取后面的样本if(pCFilter->Setup==2 || (pCFilter->Setup==1 && hr==S_OK)){HANDLE hFile;wchar_t path[MAX_PATH];wmemset(path,0,MAX_PATH);wcscat_s(path,MAX_PATH,pCFilter->DirectoryName);wcscat_s(path,MAX_PATH,L"\\");wcscat_s(path,MAX_PATH,wch);wcscat_s(path,MAX_PATH,L".dat");hFile=CreateFile(path,GENERIC_WRITE,0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);OVERLAPPED oa;WriteFile(hFile,pBuffer,Len,(LPDWORD)&oa,NULL);//写数据文件CloseHandle(hFile);}LVITEM LT;LT.mask=LVIF_TEXT;LT.iItem=0;LT.iSubItem=0;LT.pszText=wch;SendMessage(pCFilter->hL,LVM_INSERTITEM,0,(LPARAM)&LT);//列表视图添加项,文本为样本序号wmemset(wch1,0,20);_itow_s(T,wch1,10);LT.iSubItem=1;LT.pszText=wch1;SendMessage(pCFilter->hL,LVM_SETITEMTEXT,0,(LPARAM)&LT);//列表视图设置子项文本项,文本为调用时间LT.iSubItem=2;LT.pszText=L"产生样本时间,单位毫秒";SendMessage(pCFilter->hL,LVM_SETITEMTEXT,0,(LPARAM)&LT);//列表视图设置子项2文本,文本为说明wmemset(wch,0,100);wcscat_s(wch,100,L"GetSize()");//在wch后附加字符串LT.iItem=1;LT.iSubItem=0;LT.pszText=wch;SendMessage(pCFilter->hL,LVM_INSERTITEM,1,(LPARAM)&LT);//列表视图添加项,文本为GetSize()wmemset(wch1,0,100);_itow_s(BufferSize,wch1,10);LT.iSubItem=1;LT.pszText=wch1;SendMessage(pCFilter->hL,LVM_SETITEMTEXT,1,(LPARAM)&LT);//列表视图设置子项文本项,文本为缓冲区大小LT.iSubItem=2;LT.pszText=L"缓冲区大小,单位字节";SendMessage(pCFilter->hL,LVM_SETITEMTEXT,1,(LPARAM)&LT);//列表视图设置子项2文本,文本为说明wmemset(wch,0,100);wcscat_s(wch,100,L"GetActualDataLength()");//在wch后附加字符串LT.iItem=2;LT.iSubItem=0;LT.pszText=wch;SendMessage(pCFilter->hL,LVM_INSERTITEM,2,(LPARAM)&LT);//列表视图添加项,文本为GetActualDataLength()wmemset(wch1,0,100);_itow_s(Len,wch1,10);LT.iSubItem=1;LT.pszText=wch1;SendMessage(pCFilter->hL,LVM_SETITEMTEXT,2,(LPARAM)&LT);//列表视图设置子项1文本,文本为有效数据的长度LT.iSubItem=2;LT.pszText=L"有效数据的长度,单位字节";SendMessage(pCFilter->hL,LVM_SETITEMTEXT,2,(LPARAM)&LT);//列表视图设置子项2文本,文本为说明REFERENCE_TIME star,end;hr=pSample->GetTime(&star,&end);//时间戳wmemset(wch,0,100);wcscat_s(wch,100,L"GetTime()");//在wch后附加字符串LT.iItem=3;LT.iSubItem=0;LT.pszText=wch;SendMessage(pCFilter->hL,LVM_INSERTITEM,3,(LPARAM)&LT);//列表视图添加项,文本为GetTime()if(hr==S_OK)//如果获取时间戳成功{swprintf_s(wch1,100,L"star=%I64d,",star);swprintf_s(wch2,100,L"end=%I64d",end);wmemset(wch,0,100);wcscat_s(wch,100,wch1);//在wch后附加字符串wcscat_s(wch,100,wch2);//在wch后附加字符串}else{wmemset(wch,0,100);wcscat_s(wch,100,L"star=NULL,end=NULL");//在wch后附加字符串}LT.iSubItem=1;LT.pszText=wch;SendMessage(pCFilter->hL,LVM_SETITEMTEXT,3,(LPARAM)&LT);//列表视图设置子项1文本,文本为时间戳LT.iSubItem=2;LT.pszText=L"样本时间戳,单位100纳秒";SendMessage(pCFilter->hL,LVM_SETITEMTEXT,3,(LPARAM)&LT);//列表视图设置子项2文本,文本为说明hr=pSample->GetMediaTime(&star,&end);//媒体的开始和结束时间wmemset(wch,0,100);wcscat_s(wch,100,L"GetMediaTime()");//在wch后附加字符串LT.iItem=4;LT.iSubItem=0;LT.pszText=wch;SendMessage(pCFilter->hL,LVM_INSERTITEM,4,(LPARAM)&LT);//列表视图添加项,文本为GetMediaTime()if(hr==S_OK)//如果获取媒体成功{swprintf_s(wch1,100,L"Mstar=%I64d,",star);swprintf_s(wch2,100,L"Mend=%I64d",end);wmemset(wch,0,100);wcscat_s(wch,100,wch1);//在wch后附加字符串wcscat_s(wch,100,wch2);//在wch后附加字符串}else{wmemset(wch,0,100);wcscat_s(wch,100,L"Mstar=NULL,Mend=NULL");}LT.iSubItem=1;LT.pszText=wch;SendMessage(pCFilter->hL,LVM_SETITEMTEXT,4,(LPARAM)&LT);//列表视图设置子项1文本,文本为媒体的开始和结束时间LT.iSubItem=2;LT.pszText=L"媒体时间,单位音频或视频帧,或100纳秒";SendMessage(pCFilter->hL,LVM_SETITEMTEXT,4,(LPARAM)&LT);//列表视图设置子项2文本,文本为说明hr=pSample->IsDiscontinuity();//流中断wmemset(wch,0,100);wcscat_s(wch,100,L"IsDiscontinuity()");//在wch后附加字符串LT.iItem=5;LT.iSubItem=0;LT.pszText=wch;SendMessage(pCFilter->hL,LVM_INSERTITEM,5,(LPARAM)&LT);//列表视图添加项,文本为IsDiscontinuity()wmemset(wch,0,100);if(hr==S_OK)wcscat_s(wch,100,L"TRUE");//在wch后附加字符串else wcscat_s(wch,100,L"FALSE");//在wch后附加字符串LT.iSubItem=1;LT.pszText=wch;SendMessage(pCFilter->hL,LVM_SETITEMTEXT,5,(LPARAM)&LT);//列表视图设置子项1文本,文本为LT.iSubItem=2;LT.pszText=L"中断标志";SendMessage(pCFilter->hL,LVM_SETITEMTEXT,5,(LPARAM)&LT);//列表视图设置子项2文本,文本为说明hr=pSample->IsSyncPoint();//同步点wmemset(wch,0,100);wcscat_s(wch,100,L"IsSyncPoint()");//在wch后附加字符串LT.iItem=6;LT.iSubItem=0;LT.pszText=wch;SendMessage(pCFilter->hL,LVM_INSERTITEM,6,(LPARAM)&LT);//列表视图添加项,文本为IsSyncPoint()wmemset(wch,0,100);if(hr==S_OK)wcscat_s(wch,100,L"TRUE");//在wch后附加字符串else wcscat_s(wch,100,L"FALSE");//在wch后附加字符串LT.iSubItem=1;LT.pszText=wch;SendMessage(pCFilter->hL,LVM_SETITEMTEXT,6,(LPARAM)&LT);//列表视图设置子项1文本,文本为LT.iSubItem=2;LT.pszText=L"同步点标志";SendMessage(pCFilter->hL,LVM_SETITEMTEXT,6,(LPARAM)&LT);//列表视图设置子项2文本,文本为说明hr=pSample->IsPreroll();//预卷样本wmemset(wch,0,100);wcscat_s(wch,100,L"IsPreroll()");//在wch后附加字符串LT.iItem=7;LT.iSubItem=0;LT.pszText=wch;SendMessage(pCFilter->hL,LVM_INSERTITEM,7,(LPARAM)&LT);//列表视图添加项,文本为IsPreroll()wmemset(wch,0,100);if(hr==S_OK)wcscat_s(wch,100,L"TRUE");//在wch后附加字符串else wcscat_s(wch,100,L"FALSE");//在wch后附加字符串LT.iSubItem=1;LT.pszText=wch;SendMessage(pCFilter->hL,LVM_SETITEMTEXT,7,(LPARAM)&LT);//列表视图设置子项1文本,文本为LT.iSubItem=2;LT.pszText=L"预卷标志";SendMessage(pCFilter->hL,LVM_SETITEMTEXT,7,(LPARAM)&LT);//列表视图设置子项2文本,文本为说明LT.iItem=8;LT.iSubItem=0;LT.pszText=L"";SendMessage(pCFilter->hL,LVM_INSERTITEM,8,(LPARAM)&LT);//列表视图添加空项return S_OK;
}INT_PTR CALLBACK DialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)//选择媒体类型模态对话框过程函数
{CFilter* pF=NULL;//过滤器的指针HWND hList;//媒体类型列表窗口句柄switch(uMsg){case WM_INITDIALOG://初始化对话框pF=(CFilter*)lParam;hList=GetDlgItem(hwndDlg,IDC_LIST1);//获取媒体类型列表窗口句柄。IDC_LIST1为列表视图控件,样式为报表样式SetDlgItemInt(hwndDlg,IDC_EDIT2,(UINT)pF, FALSE);//将过滤器指针值,放置在不可见编辑框中LVCOLUMN LV;LV.mask=LVCF_WIDTH|LVCF_TEXT;LV.pszText=L"主要类型";LV.cx=160;SendMessage(hList,LVM_INSERTCOLUMN,(WPARAM)0,(LPARAM)&LV);//添加媒体类型列表第1列,并指定列的宽度LV.pszText=L"子类型";LV.cx=160;SendMessage(hList,LVM_INSERTCOLUMN,(WPARAM)1,(LPARAM)&LV);//添加媒体类型列表第2列,并指定列的宽度LV.pszText=L"格式类型";LV.cx=160;SendMessage(hList,LVM_INSERTCOLUMN,(WPARAM)2,(LPARAM)&LV);//添加媒体类型列表第3列,并指定列的宽度ListView_SetExtendedListViewStyle(hList,LVS_EX_FULLROWSELECT|LVS_EX_GRIDLINES);//指定扩展样式为:整行选择,显示网格for(int i=0;i<ptr.Count;i++)//将媒体类型数组中描述字符串添加到媒体类型列表{CPtr::item* p=(CPtr::item*)ptr.adres[i];wchar_t wch1[100],wch2[100],wch3[100];MultiByteToWideChar(CP_ACP,MB_COMPOSITE,p->p1,-1,wch1,100);//将char字符串转换为宽字符串MultiByteToWideChar(CP_ACP,MB_COMPOSITE,p->p2,-1,wch2,100);MultiByteToWideChar(CP_ACP,MB_COMPOSITE,p->p3,-1,wch3,100);LVITEM LT;LT.mask=LVIF_TEXT;LT.iItem=i;LT.iSubItem=0;LT.pszText=wch1;SendMessage(hList,LVM_INSERTITEM,i,(LPARAM)&LT);//列表视图添加项,文本为主要类型字符串LT.iSubItem=1;LT.pszText=wch2;SendMessage(hList,LVM_SETITEMTEXT,i,(LPARAM)&LT);//列表视图设置子项1文本项,文本为子类型字符串LT.iSubItem=2;LT.pszText=wch3;SendMessage(hList,LVM_SETITEMTEXT,i,(LPARAM)&LT);//列表视图设置子项2文本,文本为格式类型字符串}ListView_SetItemState(hList, 0, LVIS_FOCUSED|LVIS_SELECTED, LVIS_FOCUSED|LVIS_SELECTED);//选中第1项break;case WM_COMMAND:switch (LOWORD(wParam)) {case IDOK://按下“确定”按钮hList=GetDlgItem(hwndDlg,IDC_LIST1);//获取媒体类型列表窗口句柄pF=(CFilter*)GetDlgItemInt(hwndDlg,IDC_EDIT2,NULL,FALSE);//从隐藏的编辑控件中,获取过滤器指针pF->sel=ListView_GetSelectionMark(hList);//获取媒体类型列表选中项的索引if(pF->sel==-1){MessageBox(0,L"必须选择连接使用的媒体类型",0,MB_OK);return FALSE; }EndDialog(hwndDlg, 1);//终止模态对话框return FALSE;}break;case WM_NOTIFY:switch (((LPNMHDR)lParam)->code){case NM_CLICK://在媒体类型列表中,单击鼠标左键LPNMITEMACTIVATE lpnmitem = (LPNMITEMACTIVATE) lParam;if(lpnmitem->iItem!=-1)//如果有选中项{CPtr::item* p=(CPtr::item*)ptr.adres[lpnmitem->iItem];//根据媒体类型列表选中项的索引,获取“媒体类型描述字符串和格式类型数组“对应的项SetDlgItemTextA(hwndDlg,IDC_EDIT1,p->p4);//将与选中项对应的格式类型描述字符串,设置给IDC_EDIT1编辑框}break;}break;}return FALSE;
}

下载本过滤器DLL

DirectShow过滤器开发-抓取样本过滤器相关推荐

  1. Wireshark图解教程和过滤方法(简介、抓包、过滤器)

    Wireshark是世界上最流行的网络分析工具.这个强大的工具可以捕捉网络中的数据,并为用户提供关于网络和上层协议的各种信息.与很多其他网络工具一样,Wireshark也使用pcap network ...

  2. Wireshark图解教程(简介、抓包、过滤器)

    Wireshark是世界上最流行的网络分析工具.这个强大的工具可以捕捉网络中的数据,并为用户提供关于网络和上层协议的各种信息.与很多其他网络工具一样,Wireshark也使用pcap network ...

  3. 用OmniPeek快速定义的过滤器来抓网页提交信息

    编写网络程序的人,经常要抓取HTTP操作过程的一些数据,常用的软件有HTTPSniffer.httpLook等软件,这些软件比常简单,这儿就不作介绍了.这里重点介绍一下用OmniPeek来抓取数据包. ...

  4. Java Web开发中,自定义过滤器被执行两次的原因分析及解决办法

    本文出处:http://blog.csdn.net/chaijunkun/article/details/7646338,转载请注明.由于本人不定期会整理相关博文,会对相应内容作出完善.因此强烈建议在 ...

  5. 【转】Wireshark网络抓包(二)——过滤器

    转自:https://www.cnblogs.com/strick/p/6261915.html 一.捕获过滤器 选中捕获选项后,就会弹出下面这个框,在红色输入框中就可以编写过滤规则. 1)捕获单个I ...

  6. filter过滤器_不了解布隆过滤器?一文给你整的明明白白

    文章来源:https://mp.weixin.qq.com/s/_qsHjDemXUNObB0h0XHCkQ 作者:SnailClimb 海量数据处理以及缓存穿透这两个场景让我认识了布隆过滤器 ,我查 ...

  7. SpringBoot 手写过滤器amp;加载第三方过滤器

    版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/qq_36367789/article/details/81665638 如何手写一个过滤器呢.假设我 ...

  8. 【过滤器】(1)过滤器原理、使用方式的简单介绍

    一.过滤器原理图解 二.过滤器详细说明 1.过虑器能对客户的请求进行预先处理,然后再将请求转发给其他web组件. 2.过虑器是在Servlet2.3规范中定义的,它可以对Web组件的,ServletR ...

  9. 过滤流的主要特点是什么_高效过滤器工艺流程是什么 高效过滤器特点介绍【详解】...

    在很多地方都会使用到过滤器,过滤器的作用是非常大的,是很多地方都必不可少的,高效过滤器是过滤器的一种,制作工艺更加精良,很多人都不了解高效过滤器,今天小编就为大家简单的介绍一下高效过滤器的工艺流程和特 ...

  10. filter过滤器_不了解布隆过滤器?一文给你整的明明白白!

    海量数据处理以及缓存穿透这两个场景让我认识了 布隆过滤器 ,我查阅了一些资料来了解它,但是很多现成资料并不满足我的需求,所以就决定自己总结一篇关于布隆过滤器的文章.希望通过这篇文章让更多人了解布隆过滤 ...

最新文章

  1. Win10 15063 开始运行不保存历史记录原因和解决方法
  2. 2021年春季学期-信号与系统-第十五次作业参考答案
  3. [置顶] 也论百度轻应用--一个开发者的吐槽
  4. 解决ScrollView嵌套ViewPager出现的滑动冲突问题
  5. 二维数组求最大子矩阵的和
  6. r语言 去除双引号_tidyfst vs pandas(12):去除重复条目
  7. java_函数的重载
  8. 稀疏数组与二维数组相互转化
  9. matlab mex路径,使用matlab进行mex编译时的路径问题mexopts
  10. 红帽linux怎么装文件夹,红帽linux怎么安装第三方字体?
  11. 中文代码编写php,PHP开发网站代码编写规范
  12. python追加写入数据到excel表格
  13. Java InputStream转换为String
  14. 第十篇:复制对象时切记复制每一个成分
  15. Android企业级项目实战——基础篇(系列文章)
  16. html 字体立体效果,如何利用CSS3制作3D效果文字具体实现样式
  17. SanDisk cz48 16G TLC U盘量产经验分享
  18. 解决:VideoWriter保存视频无法打开以及保存的视频仅有几KB
  19. IPv6的思科培训启用SSH在Cisco IPv6路由器
  20. 在线文字生成音频工具

热门文章

  1. 奥鹏教师计算机培训总结,信息技术应用能力提升研修培训心得
  2. 名词解释:QDII与QFII
  3. Unity与讯飞语音交互的项目工程
  4. 微软和linux服务器地址,大跌眼镜:微软服务器操作系统是Linux
  5. python3.7海龟写字_Python:海龟绘图(三)
  6. 从0开始的图形学大师(1~4章)
  7. CWE-805: Buffer Access with Incorrect Length Value(以不正确的长度值方位缓冲区)
  8. Android 面试必备 - 计算机网络基本知识(TCP,UDP,移动终端开发考试题
  9. 乳腺癌预测 非负矩阵_如何在5分钟内对神经网络进行编程以预测乳腺癌
  10. 鲁照山编程致富六步学习方法