Verwenden des Fenstermodus

[Das dieser Seite zugeordnete Feature DirectShow ist ein Legacyfeature. Es wurde von MediaPlayer, IMFMediaEngine und Audio/Video Capture in Media Foundation abgelöst. Diese Features wurden für Windows 10 und Windows 11 optimiert. Microsoft empfiehlt dringend, dass neuer Code mediaPlayer, IMFMediaEngine und Audio/Video Capture in Media Foundation anstelle von DirectShow verwendet, wenn möglich. Microsoft schlägt vor, dass vorhandener Code, der die Legacy-APIs verwendet, so umgeschrieben wird, dass nach Möglichkeit die neuen APIs verwendet werden.]

Hinweis

Der Legacy-Videorendererfilter verwendet immer den Fenstermodus. Die Filter VMR-7 und VMR-9 verwenden standardmäßig den Fenstermodus, unterstützen aber auch den fensterlosen Modus.

 

Im Fenstermodus erstellt der Videorenderer ein eigenes Fenster, in dem die Videoframes gezeichnet werden. Sofern Sie nichts anderes angeben, handelt es sich bei diesem Fenster um ein Fenster auf oberster Ebene mit eigenen Rahmen und eigener Titelleiste. In den meisten Fällen fügen Sie das Videofenster jedoch an ein Anwendungsfenster an, sodass das Video in die Benutzeroberfläche Ihrer Anwendung integriert ist. Gehen Sie dazu folgendermaßen vor:

  1. Abfrage für IVideoWindow.
  2. Legen Sie das übergeordnete Fenster fest.
  3. Legen Sie neue Fensterstile fest.
  4. Positionieren Sie das Videofenster im Besitzerfenster.
  5. Benachrichtigen Sie das Videofenster über WM_MOVE Nachrichten.

Abfrage für IVideoWindow

Bevor Sie mit der Wiedergabe beginnen, fragen Sie den Filter Graph-Manager für die IVideoWindow-Schnittstelle ab:

IVideoWindow *pVidWin = NULL;
pGraph->QueryInterface(IID_IVideoWindow, (void **)&pVidWin);

Festlegen des übergeordneten Fensters

Um das übergeordnete Fenster festzulegen, rufen Sie die IVideoWindow::p ut_Owner-Methode mit einem Handle für Ihr Anwendungsfenster auf. Diese Methode akzeptiert eine Variable vom Typ OAHWND, daher wandeln Sie das Handle in diesen Typ um:

pVidWin->put_Owner((OAHWND)hwnd);

Neue Fensterformatvorlagen festlegen

Ändern Sie den Stil des Videofensters, indem Sie die IVideoWindow::p ut_WindowStyle-Methode aufrufen:

pVidWin->put_WindowStyle(WS_CHILD | WS_CLIPSIBLINGS);

Das WS_CHILD-Flag legt das Fenster als untergeordnetes Fenster fest, und das WS_CLIPSIBLINGS-Flag verhindert, dass das Fenster innerhalb des Clientbereichs eines anderen untergeordneten Fensters gezeichnet wird.

Positionieren des Videofensters

Um die Position des Videos relativ zum Clientbereich des Anwendungsfensters festzulegen, rufen Sie die IVideoWindow::SetWindowPosition-Methode auf. Diese Methode verwendet ein Rechteck, das den linken Rand, den oberen Rand, die Breite und die Höhe des Videofensters angibt. Mit dem folgenden Code wird das Videofenster beispielsweise so gestreckt, dass es dem gesamten Clientbereich des übergeordneten Fensters entspricht:

RECT rc;
GetClientRect(hwnd, &rc);
pVidWin->SetWindowPosition(0, 0, rc.right, rc.bottom);

Um die native Größe des Videos abzurufen, rufen Sie die IBasicVideo::GetVideoSize-Methode im Filter Graph-Manager auf. Sie können diese Informationen verwenden, um das Video zu skalieren und das richtige Seitenverhältnis beizubehalten.

Reagieren auf WM_MOVE Nachrichten

Um eine optimale Leistung zu erzielen, sollten Sie den Videorenderer benachrichtigen, wenn sich das Fenster bewegt, während das Diagramm angehalten wird. Rufen Sie die IVideoWindow::NotifyOwnerMessage-Methode auf, um die WM_MOVE Nachricht weiterzuleiten:

// (Inside your WindowProc)
case WM_MOVE:
    pVidWin->NotifyOwnerMessage((OAHWND)hWnd, msg, wParam, lParam);
    break;

Wenn der Renderer eine Hardwareüberlagerung verwendet, bewirkt diese Benachrichtigung, dass der Renderer die Überlagerungsposition aktualisiert. (VmR-9 verwendet keine Überlagerungen, sodass Sie diese Methode nicht aufrufen müssen, wenn Sie VMR-9 verwenden.)

Bereinigen

Bevor die Anwendung beendet wird, beenden Sie das Diagramm, und setzen Sie den Besitzer des Videofensters auf NULL zurück. Andernfalls werden Fenstermeldungen möglicherweise an das falsche Fenster gesendet, was wahrscheinlich zu Fehlern führt. Blenden Sie außerdem das Videofenster aus, oder es kann vorkommen, dass auf dem Bildschirm vorübergehend ein Videobild flackert:

pControl->Stop(); 
pVidWin->put_Visible(OAFALSE);
pVidWin->put_Owner(NULL);  

Hinweis

Wenn das übergeordnete Videofenster ein untergeordnetes Element Ihres Standard Anwendungsfensters ist (d. h., wenn das Videofenster ein untergeordnetes Element ist), sollten Sie das Videofenster mithilfe von CoCreateInstance erstellen und dem Diagramm hinzufügen, anstatt den Videorenderer während Intelligent Connect vom Filter Graph-Manager hinzufügen zu lassen. Dadurch wird sichergestellt, dass das Videofenster und das Kinderfenster gleichzeitig neu gezeichnet werden. Andernfalls kann das untergeordnete Fenster das Videofenster übermalen.

 

Videorendering