Condividi tramite


Uso della modalità finestra

[La funzionalità associata a questa pagina, DirectShow, è una funzionalità legacy. È stata sostituita da MediaPlayer, IMFMediaEngine e Audio/Video Capture in Media Foundation. Queste funzionalità sono state ottimizzate per Windows 10 e Windows 11. Microsoft consiglia vivamente che il nuovo codice usi MediaPlayer, IMFMediaEngine e Audio/Video Capture in Media Foundation invece di DirectShow, quando possibile. Microsoft suggerisce che il codice esistente che usa le API legacy venga riscritto per usare le nuove API, se possibile.

Nota

Il filtro del renderer video legacy usa sempre la modalità finestra. I filtri VMR-7 e VMR-9 usano la modalità finestra per impostazione predefinita, ma supportano anche la modalità senza finestra.

 

In modalità finestra, il renderer video crea la propria finestra in cui disegna i fotogrammi video. A meno che non si specifichi diversamente, questa finestra è una finestra di primo livello con bordi e barra del titolo. Nella maggior parte dei casi, tuttavia, si allegherà la finestra video a una finestra dell'applicazione, in modo che il video sia integrato nell'interfaccia utente dell'applicazione. La procedura da adottare è la seguente:

  1. Query per IVideoWindow.
  2. Impostare la finestra padre.
  3. Impostare nuovi stili di finestra.
  4. Posizionare la finestra video all'interno della finestra del proprietario.
  5. Notificare alla finestra video i messaggi di WM_MOVE.

Query per IVideoWindow

Prima di avviare la riproduzione, eseguire una query su Filter Graph Manager per l'interfaccia IVideoWindow :

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

Impostare la finestra padre

Per impostare la finestra padre, chiamare il metodo IVideoWindow::p ut_Owner con un handle per la finestra dell'applicazione. Questo metodo accetta una variabile di tipo OAHWND, quindi eseguire il cast dell'handle a questo tipo:

pVidWin->put_Owner((OAHWND)hwnd);

Imposta nuovi stili finestra

Modificare lo stile della finestra video chiamando il metodo IVideoWindow::p ut_WindowStyle :

pVidWin->put_WindowStyle(WS_CHILD | WS_CLIPSIBLINGS);

Il flag WS_CHILD imposta la finestra come finestra figlio e il flag di WS_CLIPSIBLINGS impedisce la creazione della finestra all'interno dell'area client di un'altra finestra figlio.

Posizionare la finestra video

Per impostare la posizione del video rispetto all'area client della finestra dell'applicazione, chiamare il metodo IVideoWindow::SetWindowPosition . Questo metodo accetta un rettangolo che specifica il bordo sinistro, il bordo superiore, la larghezza e l'altezza della finestra video. Ad esempio, il codice seguente estende la finestra video per adattarsi all'intera area client della finestra padre:

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

Per ottenere le dimensioni native del video, chiamare il metodo IBasicVideo::GetVideoSize in Filter Graph Manager. È possibile usare tali informazioni per ridimensionare il video e mantenere le proporzioni corrette.

Rispondere ai messaggi di WM_MOVE

Per ottenere prestazioni ottimali, è consigliabile inviare una notifica al renderer video ogni volta che la finestra viene spostata mentre il grafico viene sospeso. Chiamare il metodo IVideoWindow::NotifyOwnerMessage per inoltrare il messaggio WM_MOVE:

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

Se il renderer usa una sovrimpressione hardware, questa notifica fa sì che il renderer aggiorni la posizione di sovrapposizione. VmR-9 non usa sovrimpressioni, quindi non è necessario chiamare questo metodo se si usa VMR-9.

Eseguire la pulizia

Prima dell'uscita dall'applicazione, arrestare il grafico e reimpostare il proprietario della finestra video su NULL. In caso contrario, i messaggi della finestra potrebbero essere inviati alla finestra sbagliata, che è probabile che causi errori. Inoltre, nascondere la finestra del video oppure visualizzare un sfarfallio di un'immagine video sullo schermo momentaneamente:

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

Nota

Se l'elemento padre della finestra video è un elemento figlio della finestra principale dell'applicazione (in altre parole, se la finestra video è un elemento figlio di un elemento figlio), è necessario creare la finestra video usando CoCreateInstance e aggiungerla al grafo, invece di consentire a Filter Graph Manager di aggiungere il renderer video durante Intelligent Connect. In questo modo si garantisce che la finestra video e la finestra figlio vengano ridisegnate contemporaneamente. In caso contrario, la finestra figlio può disegnare sulla finestra del video.

 

Video Rendering