//=========================================================================
//
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
// KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
// PURPOSE.
//
// Copyright (c) 1996 - 1997 Microsoft Corporation. All Rights Reserved.
//
//=========================================================================
#include <windows.h>
#include <mmsystem.h>
#include <streams.h>
#include "mpegprop.h"
#define APPLICATIONNAME "MPEGProp"
#define CLASSNAME "MPEGProp"
#define WM_GRAPHNOTIFY WM_USER+13
#define HELPER_RELEASE(x) { if (x) x->Release(); x = NULL; }
HWND ghApp;
HINSTANCE ghInst;
HRESULT hr;
LONG evCode;
LONG evParam1;
LONG evParam2;
// Collection of interfaces
IBaseFilter *pif = NULL;
IGraphBuilder *pigb = NULL;
IMediaControl *pimc = NULL;
IMediaEventEx *pimex = NULL;
IVideoWindow *pivw = NULL;
IFilterGraph *pifg = NULL;
void MPEGProp (LPSTR szFile)
{ // MPEGProp //
WCHAR wFile[MAX_PATH];
MultiByteToWideChar( CP_ACP, 0, szFile, -1, wFile, MAX_PATH );
hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, IID_IGraphBuilder, (void **)&pigb);
if (SUCCEEDED(hr))
{ // Graphbuilder instance
// QueryInterface for some basic interfaces
pigb->QueryInterface(IID_IMediaControl, (void **)&pimc);
pigb->QueryInterface(IID_IMediaEventEx, (void **)&pimex);
pigb->QueryInterface(IID_IVideoWindow, (void **)&pivw);
// Have the graph construct its the appropriate graph automatically
hr = pigb->RenderFile(wFile, NULL);
// Have the graph signal event via window callbacks for performance
pimex->SetNotifyWindow((OAHWND)ghApp, WM_GRAPHNOTIFY, 0);
pigb->QueryInterface(IID_IFilterGraph, (void **)&pifg);
// The easiest way to find the single MPEG video codec
// in the graph is via IBaseFilter::FindFilterByName.
// Multiple instances of the same filter make things
// a bit more challenging...
IBaseFilter *pifPP = NULL;
ISpecifyPropertyPages *pispp = NULL;
if (SUCCEEDED(pifg->FindFilterByName(L"MPEG Video Decoder", &pifPP)))
{ // Found MPEG video decoder.
pifPP->QueryInterface(IID_ISpecifyPropertyPages, (void **)&pispp);
// Declare the counted array of GUIDs for the property page
CAUUID caGUID;
pispp->GetPages(&caGUID);
HELPER_RELEASE(pispp);
// Display the default MPEG Video Decoder filter's property page
OleCreatePropertyFrame(NULL,
0,
0,
L"Filter",
1,
(IUnknown **)&pifPP,
0,
NULL,
0,
0,
NULL);
} // Found MPEG video decoder.
else MessageBox(ghApp, "MPEG video decoder not found in the graph!", APPLICATIONNAME, MB_ICONHAND);
HELPER_RELEASE(pifPP);
// Run the graph if RenderFile succeeded
if (SUCCEEDED(hr))
pimc->Run();
} // Graphbuilder instance
} // MPEGProp //
// ---------------------------------------------------------------------------
// End of multimedia specific code.
// ---------------------------------------------------------------------------
BOOL GetClipFileName(LPSTR szName)
{ // GetClipFileName //
OPENFILENAME ofn;
ofn.lStructSize = sizeof(OPENFILENAME);
ofn.hwndOwner = ghApp;
ofn.lpstrFilter = NULL;
ofn.lpstrFilter = "MPEG files (*.mpg; *.mpeg; *.mpe)\0*.mpg; *.mpeg; *.mpe\0\0";
ofn.lpstrCustomFilter = NULL;
ofn.nFilterIndex = 1;
*szName = 0;
ofn.lpstrFile = szName;
ofn.nMaxFile = MAX_PATH;
ofn.lpstrInitialDir = NULL;
ofn.lpstrTitle = NULL;
ofn.lpstrFileTitle = NULL;
ofn.lpstrDefExt = "MPG";
ofn.Flags = OFN_FILEMUSTEXIST | OFN_READONLY | OFN_PATHMUSTEXIST;
return GetOpenFileName((LPOPENFILENAME)&ofn);
} // GetClipFileName //
LRESULT CALLBACK WndMainProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{ // WndMainProc //
switch(message)
{ // Window msgs handling
case WM_COMMAND:
switch(wParam)
{ // Menus
case ID_FILE_OPENCLIP:
TCHAR szFilename[MAX_PATH];
if (GetClipFileName(szFilename))
MPEGProp(szFilename);
break;
case ID_FILE_EXIT:
if (pimc)
pimc->Stop();
if (pivw)
pivw->put_Visible(OAFALSE);
HELPER_RELEASE(pivw);
HELPER_RELEASE(pif);
HELPER_RELEASE(pigb);
HELPER_RELEASE(pimc);
HELPER_RELEASE(pimex);
PostQuitMessage(0);
break;
} // Menus
break;
case WM_GRAPHNOTIFY:
if (NULL == pimex) // Trap potential NULL pointer fault
break;
while (SUCCEEDED(pimex->GetEvent(&evCode, &evParam1, &evParam2, 0)))
{ // Spin through the events
hr = pimex->FreeEventParams(evCode, evParam1, evParam2);
if ((EC_COMPLETE == evCode) || (EC_USERABORT == evCode))
{ // Finished
pimc->Stop();
pivw->put_Visible(OAFALSE);
HELPER_RELEASE(pivw);
HELPER_RELEASE(pif);
HELPER_RELEASE(pigb);
HELPER_RELEASE(pimc);
HELPER_RELEASE(pimex);
break;
} // Finished
} // Spin through the events
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
} // Window msgs handling
return FALSE;
} // WndMainProc //
int PASCAL WinMain(HINSTANCE hInstC, HINSTANCE hInstP, LPSTR lpCmdLine, int nCmdShow)
{ // WinMain //
MSG msg;
WNDCLASS wc;
// OLE subsystem requires applications to initialize things first!
CoInitialize(NULL);
ZeroMemory(&wc, sizeof wc);
wc.lpfnWndProc = WndMainProc;
ghInst = wc.hInstance = hInstC;
wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
wc.lpszClassName = CLASSNAME;
wc.lpszMenuName = MAKEINTRESOURCE(IDR_MENU);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hIcon = LoadIcon(hInstC, MAKEINTRESOURCE(IDI_MPEGPROP));
RegisterClass(&wc);
ghApp = CreateWindow(CLASSNAME,
APPLICATIONNAME,
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
0,
0,
ghInst,
0);
ShowWindow(ghApp, SW_NORMAL);
UpdateWindow(ghApp);
while (GetMessage(&msg,NULL,0,0))
{ // Message loop
TranslateMessage(&msg);
DispatchMessage(&msg);
} // Message loop
// Finished with OLE subsystem
CoUninitialize();
return msg.wParam;
} // WinMain //