Microsoft DirectX 8.0 |
A property page is one way for a filter to support properties that the user can set. This article describes how to display a filter's property pages in an application. It presents a sample console application that builds a file playback graph, displays any property pages defined by the filters in the graph, and then plays a file.
This article contains the following sections:
For more information about property pages, see the Platform SDK documentation.
Filters with property pages expose the ISpecifyPropertyPages interface. To determine whether a filter defines a property page, query the filter for this interface using QueryInterface and test the return value using the SUCCEEDED macro. The following code example shows an outline of what to do:
IBaseFilter *pFilter; // Obtain the filter's IBaseFilter interface. (Not shown) ISpecifyPropertyPages *pSpecify; HRESULT hr = pFilter->QueryInterface(IID_ISpecifyPropertyPages, (void **)&pSpecify); if (SUCCEEDED(hr)) { // Show the page. }
If you directly created an instance of a filter (by calling CoCreateInstance), you already have a pointer to the filter. If not, you can do one of the following:
Once you have the ISpecifyPropertyPages interface pointer, you can retrieve the filter's property pages by calling the ISpecifyPropertyPages::GetPages method. This method fills a counted array of globally unique identifiers (GUIDs) with the class identifier (CLSID) of each property page. The counted array is defined by a CAUUID structure, which you must allocate but do not have to initialize. The array itself, contained in the pElems member of the CAUUID structure, is allocated by the method.
CAUUID caGUID; pSpecify->GetPages(&caGUID); pSpecify->Release();
The OleCreatePropertyFrame function provides a simple way to display the property pages in a modal dialog box, as shown in the following code example:
OleCreatePropertyFrame( NULL, // Parent window 0, // x (Reserved) 0, // y (Reserved) FilterInfo.achName, // Caption for the dialog box 1, // Number of filters (IUnknown **)&pFilter, // Pointer to the filter caGUID.cElems, // Number of property pages caGUID.pElems, // Pointer to property page CLSIDs 0, // Locale identifier 0, // Reserved NULL // Reserved );
The sample code uses the name of the filter for the dialog box caption. It obtains the name by calling the IBaseFilter::QueryFilterInfo method on the filter. See the following sample code for details. When you are done, always free the GUID array by calling the CoTaskMemFree function.
CoTaskMemFree(caGUID.pElems);
The following sample code is a console application. It takes a file name as a command-line argument, builds a graph to play the file, displays any property pages defined by the filters in the graph, and plays the file.
#include <dshow.h> #include <stdio.h> int main(int argc, char *argv[]) { HRESULT hr; WCHAR wPath[MAX_PATH]; IGraphBuilder *pGraph = NULL; if (argc < 2) { printf("Usage: %s movie.ext\n", argv[0]); exit(0); } CoInitialize(NULL); CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, IID_IGraphBuilder, (LPVOID *)&pGraph); // Convert the file name to a wide-character string. MultiByteToWideChar(CP_ACP, 0, argv[1], -1, wPath, MAX_PATH); hr = pGraph->RenderFile(wPath, NULL); if (FAILED(hr)) { printf("Error: Could not open file named %s.\n", argv[1]); pGraph->Release(); CoUninitialize(); exit(1); } // Enumerate the filters and display their property pages. IEnumFilters *pEnum; IBaseFilter *pFilter = NULL; pGraph->EnumFilters(&pEnum); while(pEnum->Next(1, &pFilter, NULL) == S_OK) { ISpecifyPropertyPages *pSpecify; hr = pFilter->QueryInterface(IID_ISpecifyPropertyPages, (void **)&pSpecify); if (SUCCEEDED(hr)) { FILTER_INFO FilterInfo; pFilter->QueryFilterInfo(&FilterInfo); CAUUID caGUID; pSpecify->GetPages(&caGUID); pSpecify->Release(); OleCreatePropertyFrame( NULL, // Parent window 0, // x (Reserved) 0, // y (Reserved) FilterInfo.achName, // Caption for the dialog box 1, // Number of filters (IUnknown **)&pFilter, // Pointer to the filter caGUID.cElems, // Number of property pages caGUID.pElems, // Pointer to property page CLSIDs 0, // Locale identifier 0, // Reserved NULL // Reserved ); CoTaskMemFree(caGUID.pElems); FilterInfo.pGraph->Release(); } pFilter->Release(); } pEnum->Release(); // Run the graph. IMediaControl *pMediaControl = NULL; pGraph->QueryInterface(IID_IMediaControl, (void **)&pMediaControl); pMediaControl->Run(); MessageBox(NULL, "Click to end playback.", "DirectShow", MB_OK); pMediaControl->Release(); pGraph->Release(); CoUninitialize(); return 0; }