下载本过滤器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_IUNKNOWN
static 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)//禁用警告C4355
CFilter::CFilter(LPWSTR lpName, LPUNKNOWN pUnk,HRESULT *phr) : CBaseFilter(lpName, pUnk, (CCritSec *) this, CLSID_GetSample)
{
wmemset(FilterName,0,20);wcscat_s(FilterName,20,lpName);//将过滤器名称赋值给FilterName
wmemset(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");
else
strcat_s(ch,2000,"样本为固定大小:\tFALSE\r\n");
if(pmt->bTemporalCompression)
strcat_s(ch,2000,"使用时间压缩:\tTRUE\r\n");
else
strcat_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(//创建"样本信息窗口"
WS_EX_TOPMOST, //窗口扩展样式
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);
};
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;//将选择标记重置为FALSE
ptr.DeleteAll();//删除数组中的所有媒体类型信息
}
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();//同步点
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)<);//列表视图添加项,文本为样本序号
wmemset(wch1,0,20);_itow_s(T,wch1,10);LT.iSubItem=1;LT.pszText=wch1;
SendMessage(pCFilter->hL,LVM_SETITEMTEXT,0,(LPARAM)<);//列表视图设置子项文本项,文本为调用时间
LT.iSubItem=2;LT.pszText=L"产生样本时间,单位毫秒";
SendMessage(pCFilter->hL,LVM_SETITEMTEXT,0,(LPARAM)<);//列表视图设置子项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)<);//列表视图添加项,文本为GetSize()
wmemset(wch1,0,100);_itow_s(BufferSize,wch1,10);
LT.iSubItem=1;LT.pszText=wch1;
SendMessage(pCFilter->hL,LVM_SETITEMTEXT,1,(LPARAM)<);//列表视图设置子项文本项,文本为缓冲区大小
LT.iSubItem=2;LT.pszText=L"缓冲区大小,单位字节";
SendMessage(pCFilter->hL,LVM_SETITEMTEXT,1,(LPARAM)<);//列表视图设置子项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)<);//列表视图添加项,文本为GetActualDataLength()
wmemset(wch1,0,100);_itow_s(Len,wch1,10);
LT.iSubItem=1;LT.pszText=wch1;
SendMessage(pCFilter->hL,LVM_SETITEMTEXT,2,(LPARAM)<);//列表视图设置子项1文本,文本为有效数据的长度
LT.iSubItem=2;LT.pszText=L"有效数据的长度,单位字节";
SendMessage(pCFilter->hL,LVM_SETITEMTEXT,2,(LPARAM)<);//列表视图设置子项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)<);//列表视图添加项,文本为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)<);//列表视图设置子项1文本,文本为时间戳
LT.iSubItem=2;LT.pszText=L"样本时间戳,单位100纳秒";
SendMessage(pCFilter->hL,LVM_SETITEMTEXT,3,(LPARAM)<);//列表视图设置子项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)<);//列表视图添加项,文本为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)<);//列表视图设置子项1文本,文本为媒体的开始和结束时间
LT.iSubItem=2;LT.pszText=L"媒体时间,单位音频或视频帧,或100纳秒";
SendMessage(pCFilter->hL,LVM_SETITEMTEXT,4,(LPARAM)<);//列表视图设置子项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)<);//列表视图添加项,文本为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)<);//列表视图设置子项1文本,文本为
LT.iSubItem=2;LT.pszText=L"中断标志";
SendMessage(pCFilter->hL,LVM_SETITEMTEXT,5,(LPARAM)<);//列表视图设置子项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)<);//列表视图添加项,文本为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)<);//列表视图设置子项1文本,文本为
LT.iSubItem=2;LT.pszText=L"同步点标志";
SendMessage(pCFilter->hL,LVM_SETITEMTEXT,6,(LPARAM)<);//列表视图设置子项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)<);//列表视图添加项,文本为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)<);//列表视图设置子项1文本,文本为
LT.iSubItem=2;LT.pszText=L"预卷标志";
SendMessage(pCFilter->hL,LVM_SETITEMTEXT,7,(LPARAM)<);//列表视图设置子项2文本,文本为说明
LT.iItem=8;LT.iSubItem=0;LT.pszText=L"";
SendMessage(pCFilter->hL,LVM_INSERTITEM,8,(LPARAM)<);//列表视图添加空项
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.iSubItem=1;LT.pszText=wch2;
SendMessage(hList,LVM_SETITEMTEXT,i,(LPARAM)<);//列表视图设置子项1文本项,文本为子类型字符串
LT.iSubItem=2;LT.pszText=wch3;
SendMessage(hList,LVM_SETITEMTEXT,i,(LPARAM)<);//列表视图设置子项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;
}