Microsoft DirectX 8.1 (C++)

Hosting the Video Control in an MFC-based Application

This topic applies to Windows XP Home Edition and Windows XP Professional only.

This article shows how to create an MFC application that hosts the Video Control. To set up the project, perform the following steps.

  1. Create a new project using the MFC App Wizard. A dialog-based application without the document-view architecture is probably simplest, but that is up to you. Be sure to check the boxes for Active X Control and Automation support.
  2. Under Project > Settings, on the Link tab, enter strmiids.lib.
  3. Under Tools > Options, add the Microsoft Platform SDK lib and include paths and move them to the top of the list.
  4. Under Project > Add To Project > Registered Active X Controls, select the MS TV Video Control and accept all the wrapper classes that Class Wizard proposes to create. It is recommended that you change the name of the msvidctl.h and msvidctl.cpp files to something like msvidctl_1, in order not to confuse them with a separate msvidctl.h from the Platform SDK that must also be included. (You cannot use the #import statement to import the msvidctl type library from msvidctl.dll because that DLL actually contains two type libraries and Visual C++ cannot process them properly using the #import statement.)
  5. In Resource View, add the Video Control to the dialog box by using its icon on the control panel. Right click on the new rectangle, and use Class Wizard to add a data member for the control.
  6. In either the header or implementation file for your view class, you must include <tuner.h> for the Tuning Model definitions and <msvidctl.h> for the Video Control definitions. These are found in the Platform SDK include directory. You must include msvidctl.h because MFC does not provide wrapper classes for certain derived classes that you will need to use.

As mentioned in paragraph 4 above, msvidctl. dll contains two type libraries. But MFC only creates wrapper classes for some of the objects in one of the libraries. For an application developer, this means that you will be using a combination of techniques to access and control the various objects you will be working with. The following code snippets illustrate these techniques.

Create an instance of an MFC-generated wrapper class

All the COM calls are hidden. Notice that the method names in the wrapper classes are slightly different from the names generated by MIDL in the original header files.

CMSVidVideoRenderer myRenderer = m_VidCtl.GetActiveRenderer();
CRect sourceRect = myRenderer.GetSourceSize();

Create an instance of a Tuning Model COM object

Since MFC has not created any wrapper classes for the Tuning Model objects, we need to create and access them using the native COM methods such as CoCreateInstance and QueryInterface.

HRESULT hr;
  CComPtr<ITuningSpaceContainer> pTuningSpaceContainer;  
  hr = CoCreateInstance(CLSID_SystemTuningSpaces,
              NULL, 
              CLSCTX_INPROC_SERVER, 
              IID_ITuningSpaceContainer,
              reinterpret_cast<void**> (&pTuningSpaceContainer));
  if(FAILED(hr){
    AfxMessageBox("Failed to create system tuning spaces object");
    return false;
    }
  long count = 0;
  hr = pTuningSpaceContainer->get_Count(&count);
  if(FAILED(hr)){
    AfxMessageBox("Failed to get count");
    return false;
    }

Obtain a derived interface from a wrapper class

MFC does not give us a wrapper class for some derived interfaces such as IMSVidTuner, but the interface exists and we need to use it, so we have to use the m_lpDispatch member (an IDispatch pointer) of the wrapper class to call QueryInterface. It is in situations like this where we need the msvidctl.h file from the Platform SDK include file--in this case to supply the definition for IMSVidTuner.

  CMSVidInputDevice inputDevice = m_VidCtl.GetInputActive();
  if(inputDevice.m_lpDispatch) {   //we have an active input
    CComPtr<IMSVidTuner> myTuner;
    inputDevice.m_lpDispatch->QueryInterface(__uuidof(IMSVidTuner),
                                  reinterpret_cast<void**> &myTuner);
    if(FAILED(hr)){AfxMessageBox("Failed to QI for tuner");return;}
    //pATSCTR is an IATSCTuneRequest interface pointer
    myTuner->put_Tune(pATSCTR);
    } //end if