Partager via


Utilisation du mode fenêtré

[La fonctionnalité associée à cette page, DirectShow, est une fonctionnalité héritée. Il a été remplacé par MediaPlayer, IMFMediaEngine et Audio/Video Capture dans Media Foundation. Ces fonctionnalités ont été optimisées pour Windows 10 et Windows 11. Microsoft recommande vivement au nouveau code d’utiliser MediaPlayer, IMFMediaEngine et La capture audio/vidéo dans Media Foundation au lieu de DirectShow, lorsque cela est possible. Microsoft suggère que le code existant qui utilise les API héritées soit réécrit pour utiliser les nouvelles API si possible.]

Notes

Le filtre de convertisseur vidéo hérité utilise toujours le mode fenêtré. Les filtres VMR-7 et VMR-9 utilisent le mode fenêtré par défaut, mais prennent également en charge le mode sans fenêtre.

 

En mode fenêtré, le convertisseur vidéo crée sa propre fenêtre où il peint les images vidéo. Sauf indication contraire, cette fenêtre est une fenêtre de niveau supérieur avec ses propres bordures et sa barre de titre. Toutefois, la plupart du temps, vous attacherez la fenêtre vidéo à une fenêtre d’application, afin que la vidéo soit intégrée à l’interface utilisateur de votre application. Ce processus implique les étapes suivantes :

  1. Requête pour IVideoWindow.
  2. Définissez la fenêtre parente.
  3. Définissez de nouveaux styles de fenêtre.
  4. Positionnez la fenêtre vidéo à l’intérieur de la fenêtre propriétaire.
  5. Notifier la fenêtre vidéo de WM_MOVE messages.

Requête pour IVideoWindow

Avant de commencer la lecture, interrogez le Gestionnaire de graphes de filtre pour l’interface IVideoWindow :

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

Définir la fenêtre parente

Pour définir la fenêtre parente, appelez la méthode IVideoWindow::p ut_Owner avec un handle dans votre fenêtre d’application. Cette méthode prend une variable de type OAHWND. Par conséquent, castez le handle en ce type :

pVidWin->put_Owner((OAHWND)hwnd);

Définir de nouveaux styles de fenêtre

Modifiez le style de la fenêtre vidéo en appelant la méthode IVideoWindow::p ut_WindowStyle :

pVidWin->put_WindowStyle(WS_CHILD | WS_CLIPSIBLINGS);

L’indicateur WS_CHILD définit la fenêtre comme une fenêtre enfant, et l’indicateur WS_CLIPSIBLINGS empêche la fenêtre de dessiner à l’intérieur de la zone cliente d’une autre fenêtre enfant.

Positionner la fenêtre vidéo

Pour définir la position de la vidéo par rapport à la zone cliente de la fenêtre d’application, appelez la méthode IVideoWindow::SetWindowPosition . Cette méthode prend un rectangle qui spécifie le bord gauche, le bord supérieur, la largeur et la hauteur de la fenêtre vidéo. Par exemple, le code suivant étend la fenêtre vidéo pour qu’elle s’adapte à l’ensemble de la zone cliente de la fenêtre parente :

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

Pour obtenir la taille native de la vidéo, appelez la méthode IBasicVideo::GetVideoSize sur le Gestionnaire de graphes de filtre. Vous pouvez utiliser ces informations pour mettre à l’échelle la vidéo et conserver le bon rapport d’aspect.

Répondre aux messages WM_MOVE

Pour de meilleures performances, vous devez informer le convertisseur vidéo chaque fois que la fenêtre se déplace pendant que le graphique est suspendu. Appelez la méthode IVideoWindow::NotifyOwnerMessage pour transférer le message WM_MOVE :

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

Si le convertisseur utilise une superposition matérielle, cette notification oblige le convertisseur à mettre à jour la position de superposition. (Le VMR-9 n’utilise pas de superpositions. Vous n’avez donc pas besoin d’appeler cette méthode si vous utilisez VMR-9.)

Nettoyer

Avant la sortie de l’application, arrêtez le graphe et réinitialisez le propriétaire de la fenêtre vidéo sur NULL. Dans le cas contraire, les messages de fenêtre peuvent être envoyés à la mauvaise fenêtre, ce qui est susceptible de provoquer des erreurs. En outre, masquez la fenêtre vidéo, sinon vous pouvez voir une image vidéo scintiller sur l’écran momentanément :

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

Notes

Si le parent de la fenêtre vidéo est un enfant de votre fenêtre d’application main (en d’autres termes, si la fenêtre vidéo est l’enfant d’un enfant), vous devez créer la fenêtre vidéo à l’aide de CoCreateInstance et l’ajouter au graphe, au lieu de laisser le Gestionnaire de graphiques de filtre ajouter le convertisseur vidéo pendant la connexion intelligente. Cela garantit que la fenêtre vidéo et la fenêtre enfant sont repeintes en même temps. Sinon, la fenêtre enfant peut peindre sur la fenêtre vidéo.

 

Rendu vidéo