编者:李国帅
背景原因:
使用directShow进行文件播放,并监听事件。入门例子
播放
Some events are handled silently by the Filter Graph Manager, without the application being notified. Other events are placed on a queue for the application.
#include "stdafx.h"
#include <DShow.h>
#pragma comment(lib,"Strmiids.lib")
#pragma comment(lib,"Quartz.lib")
//Strmiids.lib Exports class identifiers (CLSIDs) and interface identifiers (IIDs). All DirectShow applications require this library.
//Quartz.lib Exports the AMGetErrorText function. If you do not call this function, this library is not required.
int _tmain(int argc, _TCHAR* argv[])
{
// Initialize the COM library.
HRESULT hr =CoInitialize(NULL);
if(FAILED(hr))
{
printf("ERROR - Could not initialize COM library");
perror("CoInitialize failed!");
exit(-1);
}
// Create the filter graph manager and query for interfaces.
IGraphBuilder *pGraph =NULL;
hr = CoCreateInstance(CLSID_FilterGraph,NULL,CLSCTX_INPROC_SERVER,IID_IGraphBuilder,(void **)&pGraph);
if(FAILED(hr))
{
printf("ERROR - Could not create the Filter Graph Manager.");
perror("IGraphBuilder get failed!");
CoUninitialize();
exit(-1);
}
IMediaControl *pControl =NULL;
IMediaEvent *pEvent =NULL;
hr = pGraph->QueryInterface(IID_IMediaControl,(void**)&pControl);
hr = pGraph->QueryInterface(IID_IMediaEvent,(void**)&pEvent);
// Build the graph. IMPORTANT: Change this string to a file on your system.
hr = pGraph->RenderFile(L"F:\\Samples\\Media\\chicken_divx.avi",NULL);
if(SUCCEEDED(hr))
{
// Run the graph.
hr = pControl->Run();
if(SUCCEEDED(hr))
{
// Wait for completion.
long evCode;
pEvent->WaitForCompletion(INFINITE,&evCode);
// Note: Do not use INFINITE in a real application, because it can block indefinitely.
}
}
if(FAILED(hr))
{
perror("RenderFile failed!");
pGraph->Release();
CoUninitialize();
exit(-1);
}
pControl->Release();
pEvent->Release();
pGraph->Release();
CoUninitialize();
return 0;
}
使用窗口句柄接收事件
#define WM_GRAPHNOTIFY WM_APP + 1
IMediaEventEx *g_pEvent =NULL;
pGraph->QueryInterface(IID_IMediaEventEx,(void **)&g_pEvent);
g_pEvent->SetNotifyWindow((OAHWND)g_hwnd, WM_GRAPHNOTIFY, 0);
//In your application's WindowProc function, add a case statement for the WM_GRAPHNOTIFY message:
case WM_GRAPHNOTIFY: HandleGraphEvent();break;
void HandleGraphEvent()
{
// Disregard if we don't have an IMediaEventEx pointer.
if(g_pEvent ==NULL)return;
// Get all the events
long evCode, param1, param2;
HRESULT hr;
while(SUCCEEDED(g_pEvent->GetEvent(&evCode,¶m1,¶m2, 0)))
{
g_pEvent->FreeEventParams(evCode, param1, param2);
switch(evCode)
{
case EC_COMPLETE: // Fall through.
case EC_USERABORT: // Fall through.
case EC_ERRORABORT:
CleanUp();
PostQuitMessage(0);
return;
}
}
}
// Disable event notification before releasing the graph.
g_pEvent->SetNotifyWindow(NULL, 0, 0);
g_pEvent->Release();
g_pEvent =NULL;