Moving a Video Window (Video Renderer Filter) by Using the Mouse

Environment: VC++, MFC, DirectX

Introduction

If you are creating your own video player and you are using a Video Renderer Filter, I guess you'll have a problem getting the HWND of the Video Window because the IVideoWindow interface of DirectShow doesn't provide you with a GetVideoWindowHandler method. To get the HWND of the Video Window and drag it with the mouse, please complete the following steps:

Step 1

The main problem of the IVideoWindow interface is that a method such as "GetVideoWindowHandler" doesn't exist. Really, I don't understand why Microsoft didn't create such a method. So, you can find the GetWindowHandle method in the IOverlay interface on the input pin (!) of the Video Renderer Filter. First, let's get the IOverlay interface:

IGraphBuilder m_pFilterGraph;
IOverlay m_pOverlay;
// here you should create a filter graph and render your video file
...
hr = m_pFilterGraph->Render(...);
...
// getting IOverlay interface.
IBaseFilter *pFilter= NULL;
IPin *pin = NULL;
if (SUCCEEDED(m_pFilterGraph->FindFilterByName(L"Video Renderer",
    &pFilter))) {
  if (SUCCEEDED(pFilter->FindPin(L"VMR Input0", &pin))) {
    if (SUCCEEDED(pin->QueryInterface(IID_IOverlay,
        (void **)&m_pOverlay))){
      pin->Release();
      pFilter->Release();
    }
  } else {
    pFilter->Release();
  }
}

Step 2

Create a window class to receive the ON_WM_LBUTTONDOWN message from your Video Window. It can be a main application window, or some hidden child window.

CVideoWindowListner : public CWnd
{
...
};
...
void CVideoWindowListner::OnLButtonDown(UINT nFlags, CPoint point)
{
  if(m_pOverlay == NULL) return;
  HWND hWnd;
  // getting HWND of Video Window
  HRESULT hr = m_pOverlay->GetWindowHandle(&hWnd);
  // move it!
  ::SendMessage(hWnd,WM_SYSCOMMAND, SC_MOVE | HTCAPTION, 0);

  CWnd::OnLButtonDown(nFlags, point);
}

Step 3

Your Video Window should send an ON_WM_LBUTTONDOWN message to the window defined in the previous step.

// this is your target window for the Video Window messages
CVideoWindowListner m_VideoWindowListner;
m_VideoWindowListner.Create(...);
...
// getting IVideoWindow interface
IVideoWindow  *pVW ;
hr = m_pFilterGraph->QueryInterface(IID_IVideoWindow,
                                       (void **)&pVW);

// specifying m_VideoWindowListner like receiver all Video Window
// messages
pVW->put_MessageDrain((OAHWND)m_VideoWindowListner.m_hWnd);

Step 4

If you want to put a Video Window to the main application window:

pVW->put_Owner((OAHWND)AfxGetApp()->m_pMainWnd->m_hWnd);
CRect rect;
rect.left = ... ;
rect.top  = ... ;
...
pVW->SetWindowPosition(rect.left, rect.top, rect.right,
                       rect.bottom);

If you want to detach the Video Window from the main window and show it separately:

pVW->put_Owner(NULL);

In both cases, m_VideoWindowListner will receive all Video Window messages!

Tip

If you have some problems with the video (blinking, or not properly repainting) in the child window: "MFC applications which place the video window in a child window must define an empty WM_ERASEBKGND message handler, or the video display area will not repaint correctly."© Microsoft: IVideoWindow Interface.



Comments

  • Please how to resizing video window

    Posted by microbit on 01/20/2006 04:57pm

    Please how to resizing video window

    • How to make this work

      Posted by hulzinator on 08/14/2007 02:38pm

      After spending some time looking into how to get events from a cstatic(picture control) that is no longer a cstatic once you give the handle to the video renderer I got this working.  Below is my code with comments I hope this helps everyone out.
      Alex Hulst
      
      You should include the header files of the class that owns the picture control & its member variable to your class that is building the filter graph it is a good idea to separate these.
      
      below are the definitions of the variables:
      CComPtr< IGraphBuilder > m_pGraph;
      
      pstatic is the member variable for the picture control
      
      //create an instance of Ivideowindow
      CComQIPtr< IVideoWindow, &IID_IVideoWindow>pWindow = m_pGraph;
      
      //basic rect
      RECT rc;
      
      //get handle of picture control
      HWND hwndPreview = pstatic->GetSafeHwnd();
      
      //get the rect from the picture control
      pstatic->GetClientRect(&rc);
      
      //make owner of cstatic(picture control) handle //ivideowindow
      hr = pWindow->put_Owner( (OAHWND) hwndPreview );
      
      //get parent of cstatic(picture control)***
      CWnd *cwndParent =pstatic->GetAncestor(GA_PARENT);
      
      //get handle of parent application or window***
      HWND hwndParent = cwndParent->GetSafeHwnd();		
      
      //post messages to the parent window that owns the //cstatic(picture control) *****most important //part
      hr=pWindow->put_MessageDrain((OAHWND)hwndParent);	
      
      //standard ivideowindow control for size & //position
      hr = pWindow->put_Left( 0 );
      
      hr = pWindow->put_Top( 0 );
      
      hr = pWindow->put_Width( rc.right - rc.left );
      
      hr = pWindow->put_Height( rc.bottom - rc.top);
      
      hr=pWindow->put_WindowStyle(WS_CHILD|WS_CLIPSIBLINGS);
      
      hr = pWindow->put_Visible( OATRUE );

      Reply
    Reply
  • Please Help To Render two or more layer Video

    Posted by abyjoyce on 09/06/2005 04:41am

    I Am in a need of VC++ code to accomodate two or more video layers in a single window Please Help Me

    Reply
  • how to select video mode

    Posted by Straw on 04/22/2004 12:22pm

    for example pal_m ,how to select video input pin

    Reply
  • Failed to find Pin

    Posted by Legacy on 10/06/2003 12:00am

    Originally posted by: Sanjay

    The following call is failing when I tried to run it under win2k. I am running DirectX 9.0 on my system.
    
    

    if (SUCCEEDED(pFilter->FindPin(L"VMR Input0", &pin)))
    {
    ----
    }

    I feel my render filter does not support this particular pin. Please let me know if there is any other way to get IID_IOverlay interface.

    Thanks.

    • Can not save a image file

      Posted by Straw on 04/22/2004 11:54am

      ImageCapture function cannot save a bmp file,please tell me why?

      Reply
    Reply
Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • Live Event Date: October 29, 2014 @ 11:00 a.m. ET / 8:00 a.m. PT Are you interested in building a cognitive application using the power of IBM Watson? Need a platform that provides speed and ease for rapidly deploying this application? Join Chris Madison, Watson Solution Architect, as he walks through the process of building a Watson powered application on IBM Bluemix. Chris will talk about the new Watson Services just released on IBM bluemix, but more importantly he will do a step by step cognitive …

  • Businesses are moving more and more of their customer transactions to the web. Security is understandably a top concern as online transactions increase, so it is important to make sure your electronic signature provider meets the highest security standards. That means more than simply passing a security audit or obtaining a certification. This white paper provides recommendations for taking a broader view of e-signature security, and answers key questions that help identify the security requirements against …

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds