Programmieren mit C++

Code-Beispiele & Lösungen

Klassen für allgemeine Aufgaben

AVI-Videos in 3D-Boxen abspielen

Die Klasse TAviDialog verfügt über die Fähigkeit, ein AVI-Video als Dialog-Element in einem 3D-Dialogfenster abzuspielen. Das Fenster enthält eine Laufleiste, so daß die aktuelle Abspielposition geändert werden kann. Start-, Stop- und Wiederhol-Schaltflächen sind ebenfalls vorhanden.

Wenn das Dialogfenster geöffnet wird, findet eine automatische Abstimmung der Größen statt. Dabei wird das Dialogfenster bezüglich seiner Größe so angepaßt, daß es groß genug ist, um das Video komplett anzeigen zu können.

Automatische Größenanpassung

Um die Klasse TAviDialog in ein Projekt einzubinden, müssen die Dateien AVIDLG.CPP und AVIDLG.RC in die Projektdatei aufgenommen und avidlg.h als Includedatei in der Anwendung eingebunden werden.

Zusätzlich benötigt die Klasse die Headerdatei DIGITALV.H, die Bestandteil von Video für Windows ist. Die Datei kann jedoch auch aus anderen Quellen bezogen werden; u. a. aus dem Microsoft-Forum WINMM in CompuServe.

Erforderliche Dateien

TAviDialog::TAviDialog(
     TWindow* parent, 
     const char far* filename,
     const char far* title, 
     BOOL autoplay, 
     BOOL autoclose,
     TModule* module)

Der Konstruktor erfordert einen Zeiger auf das Elternfenster und den Dateinamen, der das abzuspielende AVI-Video enthält. Zusätzlich kann eine Titelzeile für das Fenster angegeben werden. Fehlt dieser Text, wird statt dessen der Dateiname als Fenstertitel verwendet.

Konstruktor

Der Parameter autoplay steuert, ob das Video unmittelbar nach Erzeugen des Dialogs gestartet werden soll. TRUE führt das Abspielen sofort aus, während FALSE eine explizite Betätigung der Start-Schaltfläche erfordert.

Parameter autoplay

Analog zu autoplay steuert autoclose, ob der Dialog nach dem Beenden des Abspielens automatisch geschlossen werden soll (TRUE) oder nicht (FALSE).

Parameter autoclose

Der 3D-Effekt wird immer eingestellt, auch dann, wenn die Anwendung keinen 3D-Effekt benutzt. Der entsprechende Status kann im Konstruktor wie folgt bestimmt werden:

 ctl3dEnabled = GetApplication()->Ctl3dEnabled();
 if (!ctl3dEnabled) GetApplication()->EnableCtl3d(TRUE);

3D-Effekt

TAviDialog::~TAviDialog()

Der Destruktor schließt die Videodatei und setzt den 3D-Effekt wieder zurück, wenn die Hauptanwendung keinen 3D-Effekt verwendet.

Realisierung der Klasse

Zur Ausgabe des AVI-Videos verwendet die Klasse intern MCI-Kommandos.

Damit der Rahmen um das Video korrekt gezeichnet wird, wenn das Video anhält, wird ein entsprechender Event gesetzt:

Destruktor

void TAviDialog::EvPaint()
{
 TDialog::EvPaint();
 
 if (GetAviStatus(MCI_STATUS_MODE) == 
     MCI_MODE_STOP) PaintAvi();
}

Die aufgerufene Methode PaintAvi() benutzt MCI_UPDATE, um das Video-Fenster neu zu zeichnen. Dazu wird der Ausgabekontext des statischen Fensterelements genutzt, auf dem das Video ausgegeben wird:

Methode EvPaint()

void TAviDialog::PaintAvi()
{
 MCI_DGV_UPDATE_PARMS Parms;
 
 Parms.hDC = GetDC(playbackWindow);
 Parms.rc = Where(MCI_WAIT |                       MCI_DGV_WHERE_VIDEO);
 mciSendCommand(deviceID, MCI_UPDATE, 
                MCI_DGV_UPDATE_HDC, 
               (DWORD)(LPVOID)&Parms);
 ReleaseDC(playbackWindow, Parms.hDC);
}

Der Ausgabekontext wird hier mit der API-Funktion GetDC() ermittelt, da dies schneller geht und der Kontext nur für eine Ausgabe benötigt wird.

Als Reaktion auf Veränderungen der Laufleiste setzt die Klasse eine neue Ausgabeposition für das AVI-Video. Dazu wird zunächst ein Ereignis ausgewertet:

void TAviDialog::EvHScroll(UINT scrollCode, 
                           UINT thumbPos, 
                           HWND hWndCtl)
{
 TDialog::EvHScroll(scrollCode, 
                    thumbPos, hWndCtl);
 
 SetAviPosition(Slider->GetPosition());
}

Der Positionswechsel selbst wird über SetAviPosition realisiert. Diese Methode verwendet das Kommando MCI_SEEK, um den gewünschten Frame zu setzen.

Scroll-Event

Ausgabeposition setzen

Void TAviDialog::SetAviPosition(DWORD to)
{
  DWORD flags = MCI_SEEK_TO_START;
  if (to) flags = MCI_TO | MCI_WAIT;
  MCI_SEEK_PARMS Seek;
  Seek.dwCallback = MAKELONG(HWindow, 0);      // not used at present
  Seek.dwTo = to;
  mciSendCommand(deviceID, MCI_SEEK, flags,         (DWORD)(LPVOID) &Seek);
}

Wichtig ist schließlich noch, wie das Ausgabefenster festgelegt wird. Dazu unterstützt das MCI ein Kommando, das das Zielfenster in Form von Fensterkoordinaten spezifiziert. Die Methode SetDestinationRect() verwendet dieses Kommando, um die Ausgabefläche des Videos auf den Clientbereich des statischen Elements zu mappen, über dem das Video abgespielt werden soll. Aufgerufen wird diese Methode aus SetupWindow(), von wo aus auch die korrekten Parameter bezüglich des Clientbereichs übergeben werden.

DWORD TAviDialog::SetDestinationRect(int x, int y, int w, int h, 
                          DWORD flags)
{
  flags |= MCI_DGV_PUT_DESTINATION | MCI_DGV_RECT;
  RECT rect;
  rect.left = x;
  rect.top = y;
  rect.right = x + w;
  rect.bottom = y + h;
  MCI_DGV_PUT_PARMS Parms;
  if ( flags |= MCI_NOTIFY ) 
     Parms.dwCallback = MAKELONG(HWindow,     0);
  Parms.rc = rect;
  return mciSendCommand(deviceID, MCI_PUT, flags, 
                         (DWORD)(LPVOID) &Parms);
}




Sachgebiet


© 2009-2012 by Alojado Publishing. Alle Rechte vorbehalten. Ausgewiesene Marken gehören ihren jeweiligen Eigentümern.
Mit der Benutzung dieser Seite erkennen Sie die Nutzungsbedingungen und die Datenschutzerklärung an. Der Betreiber übernimmt keine Haftung für den Inhalt verlinkter externer Internetseiten.
Seite erzeugt 2012-05-20 01:14:49 von textarchiv.alojado.de