Using Windowed Mode
Microsoft DirectShow 9.0 |
Using Windowed Mode
- Note The legacy Video Renderer Filter always uses windowed mode. The VMR-7 and VMR-9 filters use windowed mode by default, but also support windowless mode.
In windowed mode, the video renderer creates its own window where it paints the video frames. Unless you specify otherwise, this window is a top-level window with its own borders and title bar. Most of the time, however, you will attach the video window to an application window, so that the video is integrated into your application UI. This requires the following steps:
- Query for IVideoWindow.
- Set the parent window.
- Set new window styles.
- Position the video window inside the owner window.
- Notify the video window of WM_MOVE messages.
Query for IVideoWindow
Before starting playback, query the Filter Graph Manager for the IVideoWindow interface:
IVideoWindow *pVidWin = NULL; pGraph->QueryInterface(IID_IVideoWindow, (void **)&pVidWin);
Set the Parent Window
To set the parent window, call the IVideoWindow::put_Owner method with a handle to your application window. This method takes a variable of type OAHWND, so cast the handle to this type:
pVidWin->put_Owner((OAHWND)hwnd);
Set New Window Styles
Change the style of the video window by calling the IVideoWindow::put_WindowStyle method:
pVidWin->put_WindowStyle(WS_CHILD | WS_CLIPSIBLINGS);
The WS_CHILD flag sets the window to be a child window, and the WS_CLIPSIBLINGS flag prevents the window from drawing inside the client area of another child window.
Position the Video Window
To set the position of the video relative to the application window's client area, call the IVideoWindow::SetWindowPosition method. This method takes a rectangle that specifies the left edge, top edge, width, and height of the video window. For example, the following code stretches the video window to fit the entire client area of the parent window:
RECT rc; GetClientRect(hwnd, &rc); pVidWin->SetWindowPosition(0, 0, rc.right, rc.bottom);
To get the native size of the video, call the IBasicVideo::GetVideoSize method on the Filter Graph Manager. You can use that information to scale the video and keep the correct aspect ratio.
Respond to WM_MOVE Messages
For best performance, you should notify the video renderer whenever the window moves while the graph is paused. Call the IVideoWindow::NotifyOwnerMessage method to forward the WM_MOVE message:
// (Inside your WindowProc) case WM_MOVE: pVidWin->NotifyOwnerMessage((OAHWND)hWnd, msg, wParam, lParam); break;
If the renderer is using a hardware overlay, this notification causes the renderer to update the overlay position. (The VMR-9 does not use overlays, so you do not need to call this method if you are using the VMR-9.)
Clean Up
Before the application exits, stop the graph and reset the video window's owner to NULL. Otherwise, window messages might be sent to the wrong window, which is likely to cause errors. Also, hide video window, or else you might see a video image flicker on the screen momentarily:
pControl->Stop(); pVidWin->put_Visible(OAFALSE); pVidWin->put_Owner(NULL);
- Note If the parent of the video window is a child of your main application window (in other words, if the video window is a child of a child), you should create the video window using CoCreateInstance and add it to the graph, instead of letting the Filter Graph Manager add the video renderer during Intelligent Connect. This ensures that the video window and your child window are repainted at the same time. Otherwise, the child window may paint over the video window.
See Also