Microsoft Windows CE 3.0  

Using Event Notification

Important:
This is retired content. This content is outdated and is no longer being maintained. It is provided as a courtesy for individuals who are still using these technologies. This content may contain URLs that were valid when originally published, but now link to sites or pages that no longer exist.

The sample application handles events from within the main window message loop. It works by having the filter graph manager post a message when a new event occurs. The application responds by retrieving the event and taking the appropriate action.

To handle events from the main window message loop, define the message that will be sent to the application window when a new event occurs. Applications can use message numbers in the range from WM_APP through 0xBFFF as private messages, as shown in the following example.

#define WM_GRAPHNOTIFY WM_APP + 1

Next, set the filter graph manager to deliver this message to the application's main window.

pEvent->SetNotifyWindow((OAHWND)g_hwnd,
WM_GRAPHNOTIFY, 0);

The IMediaEventEx::SetNotifyWindowmethod designates the specified window (g_hwnd) as the recipient of the message. Call this method after you create the filter graph and specify the owner window, but before running the graph. For details, see Sample Code. The IMediaEventExinterface is exposed by the filter graph manager.

When the application receives the WM_GRAPHNOTIFY message, the message's lParamparameter is equal to the third parameter passed to SetNotifyWindow. This parameter enables you to send instance data with the message. The sample code does not use this data, so it passes a value of zero. The message's wParamparameter is always zero.

In the window's WindowProcfunction, add a case statement for the WM_GRAPHNOTIFY message.

case WM_GRAPHNOTIFY: HandleEvent(); break;

WM_GRAPHNOTIFY is an ordinary Windows message, and is posted separately from the DirectShow event notification queue. The sequence of events is as follows:

  1. A filter sends an event notification to the filter graph manager.
  2. If the filter graph manager does not handle the event, it places the event in the event queue.
  3. The filter graph manager posts a WM_GRAPHNOTIFY message to the application window.
  4. The application responds to the message from within the window's message loop.
  5. The application retrieves the event notification from the queue.

    In the event handler function, call the IMediaEvent::GetEventmethod to retrieve events from the queue.

    long evCode, param1, param2; HRESULT hr; while
    (hr = pEvent->GetEvent(&evCode, &param1, &param2,
    0), SUCCEEDED(hr)) { hr = pEvent->FreeEventParams(evCode,
    param1, param2); if ((EC_COMPLETE == evCode) || (EC_USERABORT ==
    evCode)) { CleanUp(); break; } }

    The GetEventmethod retrieves the event code and the two event parameters. The last parameter to GetEventspecifies how long the method will wait for an event. Because the application calls this method in response to a WM_GRAPHNOTIFY message, the event is already queued, so use a time-out value of zero.

    Because event notification and the message loop are both asynchronous, the queue might hold more than one event by the time your application responds to the message. Also, the filter graph manager can clear events from the queue, if they become invalid. Therefore, call GetEventuntil it returns a failure code, indicating that the queue is empty.

    If the sample program receives an EC_COMPLETE or EC_USERABORT event, it invokes the application-defined CleanUp function, which causes the application to quit gracefully. It ignores the two event parameters (param1 and param2). After you retrieve an event, call IMediaEvent::FreeEventParamsto free resources associated with the event parameters. For example, the parameter may be a BSTR, whose memory was allocated by the filter graph manager.

    When an EC_COMPLETE event occurs, the filter graph does not automatically switch to a stopped state. The application must stop or pause the graph. When the graph stops, filters release any resources they hold. When it pauses, they continue to hold resources. Also, when a video renderer pauses, it displays a static image of the most recent frame. The sample program stops the graph. Stopping the graph is not instantaneous, however, and the IMediaControl::Stopmethod might return before the process finishes. It is a good practice to wait for the state to change before releasing interfaces or posting a quit message. Use the IMediaEvent::WaitForCompletionmethod to wait for the operation to complete, as shown in the following example.

    pMediaControl->Stop(); long evCode;
    pEvent->WaitForCompletion(INFINITE, &evCode);


     Last updated on Tuesday, May 18, 2004

    © 2004 Microsoft Corporation. All rights reserved.