Schiebe-/Drehregler
und Scrollbars
Sehen wir uns in dieser Lektion ein paar weitere Controls an: den Schieberegler,
das Drehfeld sowie die Bildlaufleiste. Doch auch hier wieder zunächst einmal der
fertige Beispieldialog:

Die drei Controls links oben im Dialog (Statusanzeige, Bildlaufleiste und Schieberegler)
werden im Beispiel miteinander gekoppelt, d.h. sie laufen nachher immer synchron.
Werden Änderungen an der Bildlaufleiste oder dem Schieberegler vorgenommen, so folgen
die Anzeigen der beiden anderen Controls. Rechts von dieser 3er-Gruppe befindet
sich ein Animation-Control. In einem Animation-Control können kleine AVI-Dateien,
allerdings ohne Ton, wiedergegeben werden. Die Wiedergabe der AVI-Datei wird im
Beispiel gestartet wenn der darunter befindliche Button angeklickt wird. Unten im
Dialog ist nochmals eine Statusanzeige eingefügt. Diese Statusanzeige ist mit dem
Drehfeld verbunden. Die aktuelle Einstellung des Drehfeldes wird im links davon
stehenden Textfeld angezeigt.
 |
Erstellen Sie für das Beispiel wieder eine dialogbasierende
Anwendung und geben Sie ihr den Namen Slider. Nach dem der Anwendungs-Assistent
seine Arbeit beendet hat, modifizieren Sie den vorgegebenen Dialog IDD_SLIDER_DIALOG.
Fügen Sie die oben angegebenen Controls zum Dialog hinzu. Für die neuen Controls
werden folgende Symbole im Toolbar des Dialogeditors verwendet:

Belassen Sie alle Eigenschaften der Controls noch auf ihrem Vorgabewert.
Passen Sie lediglich die Beschriftung der drei Gruppenfelder wie angegeben an.
|
Wie für allen anderen bisherigen Controls stellt die MFC auch für diese neuen
Controls entsprechende C++ Klassen bereit. Wenn Sie diese Controls in Dialogen einsetzen,
so benötigen Sie entweder entsprechende Membervariable oder Sie müssen mittels der
Methode GetDlgItem(...) sich bei jedem Zugriff auf das Control ein entsprechendes
temporäres Objekt erstellen.
Aber fangen wir jetzt mit dem einfachsten Control im Dialog an, der Statusanzeige
(auch Progressbar genannt). Die Statusanzeige ist ein passives Control, d.h. der
Anwender kann nicht direkt mit ihr arbeiten sondern sie dient nur zur Ausgabe. Für
die Statusanzeige stellt die MFC die Klasse CProgressCtrl zu Verfügung.
Statusanzeigen besitzen einen einstellbaren Anzeigebereich. Um den Anzeigebereich
zu setzen wird die CProgressCtrl Methode SetRange32(...) aufgerufen.
Sie erhält den unteren und oberen Grenzwert des Anzeigebereichs als Parameter. Standardmäßig
besitzt eine Statusanzeige einen Anzeigebereich von 0 bis 100.
 |
Es gibt noch eine weitere Methode SetRange(...) zum Festlegen des
Anzeigebereichs. Obwohl die Parameter dieser Methode vom Typ short sind,
und damit auch negative Werte annehmen können, ist die Statusanzeige bei Verwendung
dieser Methode leider nicht in der Lage, negative Bereichsangaben bei der Anzeige
darzustellen. Bei Verwendung von SetRange32(...) besteht diese Einschränkung
nicht. |
Um die Statusanzeige auf einen bestimmten Wert zu setzen, rufen Sie die Methode
SetPos(...) auf. Liegt der hier angegebene Wert außerhalb des eingestellten
Anzeigebereichs, so wird entweder überhaupt nicht dargestellt oder die Anzeige zeigt
'Vollausschlag'.
 |
Passen wir die Statusanzeige links oben im Dialog nun an. Da
sie an die beiden darunter liegenden Controls nachher gekoppelt wird, fügen
Sie über den Klassen-Assistent zur Dialogklasse die zur Statusanzeige gehörende
Membervariable m_CProgress1 (Typ CProgressCtrl) hinzu.

Anschließend kann die Statusanzeige in der Methode OnInitDialog(...)
initialisiert werden.
BOOL CSliderDlg::OnInitDialog()
{
....
// ZU ERLEDIGEN: Hier zusätzliche Initialisierung einfügen
// Linke obere Statusanzeige
initialisieren
m_CProgress1.SetRange32(-100,100);
m_CProgress1.SetPos(0);
return TRUE; // Geben Sie TRUE zurück, außer ein
Steuerelement soll....
} |
|
 |
Kommen Sie hier nicht in Versuchung die Statusanzeige aus der Methode
InitInstance(...) des Anwendungsobjektes heraus zu initialisieren!
Beim Aufruf der oben erwähnten Methoden SetRange32(...) und SetPos(...)
muss das Control bereits existieren. Da der Dialog, und die in ihm enthaltenen
Controls, aber erst mit dem Aufruf der CDialog Methode DoModal(...)
erstellt werden, würde der Aufruf der Methoden einen Fehler innerhalb der MFC
auslösen! |
Passen wir nun noch den Stil der Statusanzeige etwas an. Standardmäßig werden
Statusanzeigen mit einem unterbrochenem Balken angezeigt. Sie können jedoch auch
Statusanzeigen erstellen, deren Balken durchgängig ausgefüllt ist, ja sogar Statusanzeigen,
die vertikal verlaufen.
 |
Um das Erscheinungsbild einer Statusanzeige anzupassen, öffnen
Sie deren Eigenschaftsdialog. Wählen Sie dort den Tabulator Formate
aus und dann die Eigenschaft Glatt. Im Dialogeditor wird die Statusanzeige
daraufhin mit einem durchgängig ausgefüllten Balken dargestellt.

 |
Bei vielen kommerziellen Programmen enthält die Statusanzeige
innerhalb des Balken noch einen zusätzlichen Text wie z.B. eine Prozentangabe.
Wie Sie so etwas erreichen, das erfahren Sie bei den Tipps&Tricks zu diesem
Kapitel. |
Wenn Sie das Beispiel nun übersetzen und starten, so erhalten Sie eine bis
zur Hälfte ausgefüllte Statusanzeige im Dialog dargestellt.
|
Sehen wir uns als nächstes den Schieberegler in dieser 3er-Gruppe an. Schieberegler
werden durch die MFC Klasse CSliderCtrl repräsentiert. Sie verfügen ebenfalls
über einen einstellbaren Anzeigebereich. Dieser Bereich wird mit der Methode
SetRange(...) eingestellt.
 |
Die Klasse CSliderCtrl besitzt leider keine Methode SetRange32(...).
Aus diesem Grund kann ein Schieberegler nur positive Werte darstellen! |
Das Einstellen der aktuellen Position erfolgt wieder mit einer gleichnamigen
Methode SetPos(...) wie bei der Statusanzeige. Sie sehen, Schieberegler
und Statusanzeigen haben vieles gemeinsam. Zusätzlich können Schieberegler noch
einen Auswahlbereich darstellen, der über die entsprechende Eigenschaft Auswahl
aktivieren des Schieberegler aktiviert wird.

Dieser Auswahlbereich dient nur als optische Hervorhebung und hat sonst keinerlei
weitere Funktionalität.

Der Auswahlbereich wird über die CSliderCtrl Methode SetSelection(...)
gesetzt. Außerdem stehen für Schieberegler noch weitere Methoden zur Verfügung um
z.B. den Abstand der Tickmarks (das sind die kleinen Striche) einzustellen oder
auch die Schrittweite festzulegen.
Aber Schieberegler haben noch eine wesentliche Erweiterung gegenüber der vorherigen
Statusanzeige: sie lassen sich durch den Anwender beeinflussen. Verändert der Anwender
die Position eines Reglers, so sendet dieser eine Nachricht an sein übergeordnetes
Fenster. Je nach dem, ob es sich um einen horizontalen Regler, wie im Beispiel,
oder einen vertikalen Regler handelt, wird eine WM_HSCROLL bzw. WM_VSCROLL Nachricht
versandt. Diese Nachrichten werden durch die MFC Nachrichtenbearbeiter OnHScroll(...)
bzw. OnVScroll(...) verarbeitet. Im ersten Parameter der Nachrichtenbearbeiter
steht die Ursache für das Auslösen dieser Nachricht. Für die Ursache sind eine Reihe
von Konstanten definiert, die alle mit dem Präfix SB_xxx beginnen. Mehr dazu gleich
bei der Behandlung der Bildlaufleiste da der Auslösegrund dort eine wesentliche
Rolle spielt. Der nächste Parameter enthält die aktuelle Position des Reglers und
der letzte Parameter ist ein Zeiger auf das Control, das die Nachricht WM_HSCROLL
bzw WM_VSCROLL ausgelöst hat. Beachten Sie bitte, dass alle Regler, und auch die
nachher noch aufgeführten Bildlaufleisten, innerhalb eines Dialogs die gleiche Nachricht
versenden, so dass Sie im Nachrichtenbearbeiter in der Regel immer abfragen müssen,
von welchem Control die Nachricht stammt. Hierzu es notwendig, die ID des Controls
über dessen Methode GetDlgCtrlID(...) zu ermitteln.
 |
Noch ein Hinweis zur OnXScroll(...) Methode. Sie sollten
am Ende der Methode immer die Basisklassen-Methode zusätzlich aufrufen, da sie
unter Umständen die Nachricht an das Control weiterleitet. |
 |
Versuchen Sie einmal wieder selbst, den Regler in der OnInitDialog(...)
Methode so zu konfigurieren, dass er einen Anzeigebereich von 0...200 besitzt,
der Auswahlbereich von 50...150 geht und die Tickmarks einen Abstand von 25
Einheiten besitzen. Wie Sie den Abstand der Tickmarks einstellen, dass sollen
Sie hier selbst mit Hilfe der Online-Hilfe herausbekommen. Hinweis: Sie müssen
selbstverständlich für den Regler wieder eine Membervariable vom Typ CSliderCtrl
zur Dialogklasse hinzufügen. Geben Sie dieser Membervariable den Namen m_CSlider.
 |
Aber wenn Sie wollen kann ich Ihnen auch meine Lösung anzeigen. |
Lösung zur Konfiguration des Reglers
BOOL CSliderDlg::OnInitDialog()
{
....
// Linke obere Statusanzeige initialisieren
....
// Schieberegeler
initialisieren
m_CSlider.SetRange(0,200);
m_CSlider.SetPos(100);
m_CSlider.SetSelection(50,150);
m_CSlider.SetTicFreq(25);
return TRUE; //
Geben Sie TRUE zurück, außer ein Steuerelement soll....
} |
Haben Sie beim Definieren der Membervariable auch daran gedacht, dass
diese vom Typ Control sein muss?
Ende der Lösung
|
Als nächstes wollen wir den Regler mit der Statusanzeige so koppeln, dass
beide synchron laufen. Hierzu müssen wir die Nachricht WM_HSCROLL bearbeiten.
Fügen Sie jetzt über die Klassenansicht (nicht über den Klassen-Assistent!)
den Nachrichtenbearbeiter für diese WINDOWS-Nachricht hinzu. Erweitern Sie die
eingefügte Methode wie folgt:
void CSliderDlg::OnHScroll(UINT
nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
// TODO: Code für die Behandlungsroutine für Nachrichten hier
einfügen....
// Falls Nachricht
vom Schieberegler
if (pScrollBar->GetDlgCtrlID()==IDC_SLIDER1)
HandleSlider();
CDialog::OnHScroll(nSBCode,
nPos, pScrollBar);
} |
Falls die Nachricht von unserem Regler stammt (ID des Reglers ist IDC_SLIDER1)
wird die Methode HandleSlider(...) aufgerufen. Diese Methode soll die
Statusanzeige mit dem Regler synchronisieren. Dazu wird innerhalb der Methode
zunächst die aktuelle Reglerposition ausgelesen und diese anschließend an die
Statusanzeige übergeben.
Fügen Sie zur Dialogklasse jetzt die void Methode HandleSlider(...)
hinzu. Die Methode benötigt keine weiteren Parameter. Erweitern Sie zum Schluss
die Methode wie nachfolgend angegeben:
void CSliderDlg::HandleSlider()
{
// Akt. Position des
Schiebereglers auslesen
int nActPos = m_CSlider.GetPos();
// und Statusanzeige synchronisieren
m_CProgress1.SetPos(nActPos-100);
} |
Beachten Sie bitte, dass die Statusanzeige einen Bereich von -100...100 besitzt
und der Regler dagegen einen Bereich von 0...200, da er keine negativen Daten
verarbeiten kann.
Wenn Sie das Programm jetzt starten und den Regler bewegen, so wird die Statusanzeige
diesem immer folgen.
|
Kommen wir nun zum letzten Element in dieser 3er-Gruppe, der Bildlaufleiste.
Sie wird durch die MFC Klasse CScrollBar gekapselt. Diese Klasse verwendet
zur Beeinflussung des Controls jedoch, wenigstens vom Namen her, andere Methoden
als die beiden vorherigen Controls. Um den Bereich einer Bildlaufleiste zu setzen
rufen Sie die Methode SetScrollRange(...) auf. Und damit es mal wieder
nicht ganz zu einfach wird: der Anzeigebereich darf hier, wie bei der Statusanzeige,
einen negativen Bereich besitzen. Außerdem besitzen Bildlaufleisten, im Gegensatz
zu den vorherigen Controls, keinen Standardbereich, d.h. Sie müssen immer
den Bereich explizit setzen. Um den Thumb, das ist das kleine Rechteck in der Bildlaufleiste,
auf eine bestimmte Position zusetzen, dient die Methode SetScrollPos(...).
Die aktuelle Position des Thumb erhalten Sie dementsprechend durch die Methode
GetScrollPos(...) geliefert.
Werden nun Bildlaufleisten durch den Anwender verändert, so senden diese genauso
wie Regler Nachrichten an die Anwendung. Unglücklicherweise verwenden Bildlaufleisten
die gleichen Nachrichten wie Regler, d.h. eine horizontale Bildlaufleiste sendet
ebenfalls eine WM_HSCROLL Nachricht und eine vertikale Bildlaufleiste eine WM_VSCROLL
Nachricht. Haben Sie mehrere Bildlaufleisten und/oder Regler im Dialog, so müssen
Sie innerhalb der Nachrichtenbearbeiter OnHScroll(...) bzw. OnVScroll(...)
zuerst den Auslöser der Nachricht feststellen. Dies erfolgt durch den Aufruf der
vorhin beschriebenen Methode GetDlgCtrlID(...). Und jetzt noch ein ganz
wichtiger Hinweis, damit Sie sich wieder eine etwas länger dauernde Fehlersuche
sparen können:
 |
Während bei Regler das Einstellelement automatisch positioniert wird, müssen
Sie bei Bildlaufleisten den Thumb immer selber positionieren. D.h. innerhalb
des Nachrichtenbearbeiters OnHScroll(...) bzw. OnVScroll(...)
werden Sie in der Regel die Methode SetScrollPos(...) aufrufen müssen.
Vergessen Sie dies einmal, so springt der Thumb immer wieder auf seine Ausgangsposition
wieder zurück. |
Sehen wir uns (bevor wir das Beispiel erweitern) noch kurz den ersten Parameter
nSBCode der OnXScroll(...) Methoden an. Dieser Parameter teilt
der Anwendung mit, wie der Thumb verschoben wurde. Möglich sind hierbei die folgenden
Werte:
|
Wert
|
Auslöser
|
durchzuführende Aktion
|
| SB_LEFT |
Taste <POS1> |
Thumb ganz ans linke Ende schieben |
| SB_LINELEFT |
Bildlauf-Pfeil links oder Taste <CUR-HOCH> |
Thumb um eine Einheit nach links |
| SB_PAGELEFT |
klicken in Bildleiste links vom Thumb oder Taste <BIILD-HOCH> |
Thumb um mehrere Einheiten nach links |
| SB_RIGHT |
Taste <ENDE> |
Thumb ganz ans rechte Ende schieben |
| SB_LINERIGHT |
Bildlauf-Pfeil rechts oder Taste <CUR-RUNTER> |
Thumb um eine Einheit nach rechts schieben |
| SB_PAGERIGHT |
klicken in Bildleiste rechts vom Thumb oder Taste <BIILD-RUNTER> |
Thumb um mehrere Einheiten nach rechts |
| SB_THUMBTRACK |
Der Thumb wir im Augenblick gezogen. nPos enthält dann
die aktuelle Position |
keine |
| SB_THUMBPOSITION |
Der gezogen Thumb wird losgelassen. nPos enthält die
Endposition |
Thumb-Position auf nPos setzen |
Bauen wir die Behandlung der Bildlaufleiste ins Beispiel ein. Die Bildlaufleiste
soll wieder synchron zu den beiden anderen Controls laufen. Im Unterschied zum Regler
soll jedoch die Position der Bildlaufleiste erst dann ausgewertet werden, wenn der
Thumb nicht mehr gezogen wird, d.h. während der Thumb bewegt wird bleiben die anderen
Controls unverändert.
 |
Fügen Sie zunächst zur Dialogklasse über den Klassen-Assistent
die mit der Bildlaufleiste verbundene Membervariable m_CScroll (Typ
CScrollBar) hinzu. Anschließend müssen in der OnInitDialog(...)
Methode die Parameter der Bildlaufleiste festgelegt werden. Erweitern Sie hierfür
die OnInitDialog(...) Methode wie folgt:
BOOL CSliderDlg::OnInitDialog()
{
....
// Schieberegeler initialisieren
....
// Bildlaufleiste initialisieren
m_CScroll.SetScrollRange(-100,100);
m_CScroll.SetScrollPos(0);
return TRUE; // Geben
Sie TRUE zurück, außer ein Steuerelement soll....
} |
Starten Sie das Beispiel.
|
Nach dem Starten des Programms wird der Thumb in der Bildlaufleiste mittig positioniert.
Wenn Sie nun Änderungen an der Bildlaufleiste vornehmen, so wird der Thumb danach
immer wieder in diese Ausgangsposition zurückspringen. Dies liegt daran, dass Sie
den Thumb, wie bereits erwähnt, immer selbst positionieren müssen.
 |
Erweitern wir die Methode OnHScroll(...) um die Behandlung
der Bildlaufleisten-Nachricht. Wird die Methode als Reaktion auf eine Veränderung
der Bildlaufleiste aufgerufen, so soll die im Anschluss definierte Methode
HandleScrollbar(...) aufgerufen werden.
void CSliderDlg::OnHScroll(UINT
nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
// TODO: Code für die Behandlungsroutine für Nachrichten hier
einfügen ....
if (pScrollBar->GetDlgCtrlID()==IDC_SLIDER1)
HandleSlider();
else
if (pScrollBar->GetDlgCtrlID()==IDC_SCROLLBAR1)
HandleScrollbar(nSBCode,
nPos);
CDialog::OnHScroll(nSBCode,
nPos, pScrollBar);
} |
Fügen Sie anschließend die Methode HandleScrollbar(...) mit dem
unten angegebenen Prototyping zur Bearbeitung der WM_HSCROLL Nachricht zur Dialogklasse
hinzu. Erweitern Sie die Methode um folgenden, doch etwas umfangreicheren, Code:
void CSliderDlg::HandleScrollbar(UINT
nSBCode, UINT nPos)
{
int nScrollMin, nScrollMax, nActScrollPos;
// Aktuelle Position des
Thumbs auslesen
nActScrollPos = m_CScroll.GetScrollPos();
// Scrollbereich auslesen
m_CScroll.GetScrollRange(&nScrollMin,
&nScrollMax);
// Scroll-Code auswerten
switch(nSBCode)
{
case SB_LEFT:
nActScrollPos = nScrollMin;
break;
case SB_LINELEFT:
if (nActScrollPos != nScrollMin)
nActScrollPos--;
break;
case SB_LINERIGHT:
if (nActScrollPos != nScrollMax)
nActScrollPos++;
break;
case SB_PAGELEFT:
nActScrollPos -= 10;
if (nActScrollPos < nScrollMin)
nActScrollPos
= nScrollMin;
break;
case SB_PAGERIGHT:
nActScrollPos += 10;
if (nActScrollPos > nScrollMax)
nActScrollPos
= nScrollMax;
break;
case SB_RIGHT:
nActScrollPos = nScrollMax;
break;
case SB_THUMBPOSITION:
nActScrollPos = nPos;
break;
case SB_THUMBTRACK:
nActScrollPos = nPos;
break;
default:
return;
// nothing more to do!!
}
// Positions des Thumbs
neu setzen
m_CScroll.SetScrollPos(nActScrollPos);
// Falls Thumb nicht gezogen
wurde, Progressbar und
// Slider synchronisieren
if (nSBCode != SB_THUMBTRACK)
{
m_CProgress1.SetPos(nActScrollPos);
m_CSlider.SetPos(nActScrollPos+100);
}
} |
Damit auch die Bildlaufleiste mit dem Regler synchron läuft, muss die Methode
HandleSlider(...) zum Schluss etwas angepasst werden.
void CSliderDlg::HandleSlider()
{
// Akt. Position des Schiebereglers auslesen
int nActPos = m_CSlider.GetPos();
// und Statusanzeige synchronisieren
m_CProgress1.SetPos(nActPos-100);
// und Bildlaufleiste
auch noch
m_CScroll.SetScrollPos(nActPos-100);
} |
Starten Sie das Programm nun und die Controls in der 3er-Gruppe werden immer
synchron laufen.
|
Kommen wir jetzt zur Darstellung einer Animation innerhalb eines Dialogs. Sicher
kennen Sie die kleine Animation mit der über einen Rechner kreisenden Lupe wenn
Sie z.B. im Explorer nach Dateien suchen. Quasi als kleines Bonbon werden wir uns
nun zunächst ansehen, wie Sie an diese Animation kommen und damit auch in ihren
Anwendungen einsetzen können. Dazu gibt es verschiedene Wege, wir werden uns den
einfachsten ansehen und die entsprechende AVI-Datei einfach aus der entsprechenden
System-DLL extrahieren. Viele der Animationen liegen in der DLL SHELL32.DLL,
die Sie im WINDOWS Systemverzeichnis finden. Ressourcen in EXE- und DLL-Dateien
lassen sich mit dem Ressourcen-Editor öffnen. Wurde die Datei einmal geöffnet, können
mittels des Ressourcen-Editors Ressourcen aus ihr extrahiert werden.
 |
Schließen Sie nun (sicherheitshalber) das aktuelle Projekt;
wir werden es später wieder öffnen. Anschließend kopieren Sie die Datei
SHELL32.DLL aus dem WINDOWS Systemverzeichnis in ein temporäres Verzeichnis.
Wählen Sie dann im Visual Studio das Menü Datei und dort den Menüpunkt
Öffnen... aus. Wechseln Sie ins temporäre Verzeichnis. Stellen Sie
im Öffnen-Dialog als Dateityp Ausführbare Dateien und in der
Listbox Öffnen als den Typ Ressourcen ein. Öffnen Sie die
kopierte Datei SHELL32.DLL.

Nach dem Laden der DLL werden Ihnen zunächst die vorhandenen Ressource-Typen
angezeigt. Wir wollen uns eine AVI-Datei aus der Ressource 'ausleihen'. Öffnen
Sie nun diesen Ressource-Typ und klicken dann die Ressource 152 mit
der rechten Maustaste an. Im daraufhin eingeblendeten Kontextmenü wählen Sie
den Eintrag Exportieren... aus und speichern die AVI-Ressource
jetzt in die Datei 152.avi ab. Beachten Sie bitte, dass im Export-Dialog
als Dateierweiterung standardmäßig jedoch bin vorgegeben wird. Schließen
Sie jetzt die DLL wieder. Zum Schluss kopieren Sie die extrahierte AVI-Datei
in Ihr Arbeitsverzeichnis und löschen die Dateien im temporären Verzeichnis.
So einfach geht's, wenn man es weiß.
|
Um jetzt AVI-Dateien (aber ohne Ton!) innerhalb eines Dialog wiederzugeben, wird
im Dialog ein Animation-Control eingesetzt. Damit das Control von der Anwendung
aus gesteuert werden kann, muss innerhalb des Dialogs wieder eine entsprechende
Membervariable angelegt werden. Die MFC stellt zur Unterstützung von Animation-Controls
die Klasse CAnimateCtrl zur Verfügung. Die Verknüpfung zwischen der darzustellenden
AVI-Datei und dem Control erfolgt über die CAnimateCtrl Methode Open(...).
Die Methode erhält als Parameter den Namen der nachher im Control abzuspielenden
AVI-Datei. Als Returnwert liefert die Methode im Fehlerfall den Wert 0.
 |
Sie sollten den Returnwert immer abfragen, da sich in einem Animation-Control
nur AVI-Dateien ohne Tonspur abspielen lassen. Zudem müssen die AVI-Dateien
noch in einer bestimmten Kodierung vorliegen. |
Nach dem erfolgreichen Laden einer AVI-Datei kann diese dann anschließend mittels
der CAnimateCtrl Methode Play(...) wiedergegeben werden. Sie können
dieser Methode als Parameter einen Start- und Endframe sowie einen Wiederholungszähler
mitgeben. Hierdurch lassen sich z.B. nur bestimmte Sequenzen innerhalb einer AVI-Datei
wiedergeben. Den Abspielvorgang können Sie jederzeit mittels Stop(...)
unterbrechen.
Erweitern wir jetzt unser Beispiel um die Darstellung der Animation.
 |
Stellen Sie zunächst sicher, dass sich die im vorherigen Schritt
extrahierte Datei 152.avi im aktuellen Arbeitsverzeichnis befindet.
Öffnen Sie dann wieder das vorhin geschlossene Projekt Slider. Und
jetzt dürfen Sie wieder rann. Versuchen Sie einmal die AVI-Datei 152.avi
im Animation-Control abzuspielen wenn der darunter liegende Button angeklickt
wird. Geben Sie dem Button die ID IDC_SANIMATE und die Beschriftung Start.
 |
Aber wenn Sie wollen kann ich Ihnen auch meine Lösung anzeigen. |
Lösung zur Anzeige der Animation
Fügen Sie über den Klassen-Assistent die zum Animation-Control
gehörende Membervariable m_CAnimate (Typ CAnimateCtrl)
hinzu. Anschließend verbinden Sie die AVI-Datei 152.avi in der
OnInitDialog(...) Methode mit dem Control.
BOOL CSliderDlg::OnInitDialog()
{
....
// Schieberegeler
initialisieren
....
// Animation-Control
initialisieren
BOOL bRetCode = m_CAnimate.Open("152.avi");
ASSERT (bRetCode);
return TRUE; //
Geben Sie TRUE zurück, außer ein Steuerelement soll ....
} |
Zum Schluss fehlt nur das Abspielen der geladenen AVI-Datei. Dazu wird
über den Klassen-Assistenten der Nachrichtenbearbeiter für die BN_CLICKED
Nachricht des Buttons IDC_SANIMATE zum Dialog hinzugefügt und dessen Code
wie folgt erweitert:
void CSliderDlg::OnSanimate()
{
// TODO: Code für die Behandlungsroutine der Steuerelement-....
m_CAnimate.Play(0,-1,1);
} |
Ende der Lösung
|
Starten Sie das Programm dann.
|
Nach dem Starten des Programms wird im Animation-Control der erste Frame der
AVI-Datei angezeigt. Das AVI wird standardmäßig oben links im Control platziert.
Was im Augenblick vielleicht noch etwas störend wirkt ist die Hintergrundfarbe der
AVI-Datei. Dies wollen wir nun über die Eigenschaften des Animation-Controls korrigieren.
 |
Setzen Sie dazu einfach, wie unten angegeben, im Eigenschaftsdialog
des Animation-Controls die Eigenschaften Zentriert und Transparent.

Wenn Sie nun das Programm starten, so wird der farbige Hintergrund ausgeblendet
und die AVI-Datei mittig im Control positioniert.
|
Damit beenden wir die Behandlung des Animation-Controls und kommen zur letzten
Gruppe in Dialog. Diese Gruppe besteht ebenfalls aus drei Controls: einer Statusanzeige,
einem Textfeld und einem Drehfeld. Richten wir unser Augenmerk zunächst auf das
Drehfeld. Das Drehfeld, oft auch als Spin-Button bezeichnet, wird hauptsächlich
dann eingesetzt, wenn nummerische Werte eingestellt werden sollen. Das Drehfeld
selbst besteht nur aus den beiden Pfeilen. In der Praxis ist dem Drehfeld aber meistens
ein Text- oder Editfeld zugeordnet um den aktuellen Wert des Drehfeldes darzustellen.
Dieses zugeordnete Feld wird auch als Buddy-Control bezeichnet. Mehr dazu gleich.
Wird ein Drehfeld in einem Dialog (oder Fenster) verwendet, so wird in der Regel
in der entsprechenden Klasse ein mit ihm verbundenes Objekt der Klasse CSpinButtonCtrl
instantiiert. Und auch Drehfelder besitzen einen Bereich, in dem die Werte durchlaufen
werden. Dieser Bereich wird mit der Methode SetRange32(...), jetzt jedoch
der Klasse CSpinButtonCtrl zugehörig, einstellt. Die Parameter der Methode
entsprechen denen der gleichnamigen Methode der Klasse CProgressBar (siehe
weiter oben).
 |
Obwohl Drehfelder standardmäßig den Bereich 0 bis 100 besitzen sollten Sie
trotzdem immer die Methode SetRange32(...) aufrufen. Ohne den Aufruf
dieser Methode wird über den oberen Pfeil-Button der Wert des Drehfeldes dekrementiert
und über den unteren Button inkrementiert. Wird die Methode SetRange32(...)
aufgerufen, so dreht sich dieses Verhalten um, d.h. über den oberen Pfeil-Button
wird dann der Wert inkrementiert und über den unteren dekrementiert. |
Um die Position (Wert) eines Drehfeldes zu setzen oder auszulesen, werden auch
hier die Methoden SetPos(...) und GetPos(...) aufgerufen.
Aber sehen wir uns noch einige der Eigenschaften des Drehfeldes an.

Wie bereits vorher erwähnt besteht ein Drehfeld nur aus den Pfeil-Buttons. Um
die aktuelle Position (Wert) des Drehfeldes auszugeben, wird in der Regel ein Text-
oder Editfeld eingesetzt. Dieses Feld muss in der Tab-Reihenfolge unmittelbar
vor dem Drehfeld stehen. Wird nun die Eigenschaft Auto Buddy und
Buddy-Ganzzahl setzen gesetzt, so wird die aktuelle Position in diesem
Feld ausgegeben, ohne dass Sie dafür eine Zeile Code schreiben müssen. Über die
Eigenschaft Umbruch kann zusätzlich noch eingestellt werden, ob der der
Wert beim Überschreiten einer der Bereichsgrenze ans anderen 'Ende' springt.
 |
Die nicht in der Online-Hilfe aufgeführte Eigenschaft Hot Track
verändert die Farbe der Pfeiltasten wenn der Cursor über ihnen positioniert
wird. |
Soweit zur generellen Handhabung des Drehfeldes. Fehlt uns nur noch die 'nachrichtendienstliche'
Bearbeitung des Controls. Drehfelder senden ebenfalls WM_HSCROLL bzw. WM_VSCROLL
Nachrichten (abhängig von der eingestellten Ausrichtung, siehe Bild oben) wenn ihre
Position (Wert) verändert wird. Wie diese Nachrichten zu behandeln sind haben Sie
in dieser Lektion bereits erfahren. Da im Beispiel ein Drehfeld mit vertikalen Pfeilen
eingesetzt wird, empfängt der Dialog entsprechende WM_VSCROLL Nachrichten.
Im Beispiel soll der über das Drehfeld eingestellte Wert in dem rechts von ihm
befindlichen Textfeld ausgegeben und zusätzlich in der darüber liegenden Statusanzeige
angezeigt werden. Erweitern wir dazu das Beispiel ein letztes Mal.
 |
Passen wir zuerst den Dialog an. Stellen Sie die Eigenschaften
des Drehfeldes wie oben angegeben ein. Damit wird dem Drehfeld automatisch ein
Feld zur Anzeige der aktuellen Position zugeordnet. Um das Feld zur Ausgabe
des Wertes zu bestimmen, muss dieses in der Tab-Reihenfolge unmittelbar
vor dem Drehfeld stehen. Dabei ist es nicht relevant, ob die Tabstopp
Eigenschaft des Feldes gesetzt ist oder nicht, wichtig ist alleine die Tab-Reihenfolge
(siehe nachfolgendes Bild).

Als nächstes fügen Sie über den Klassen-Assistenten die mit der Statusanzeige
verbundene Membervariable m_CProgress2 (Typ CProgressCtrl)
und die mit dem Drehfeld verbundene Membervariable m_CSpin (Typ
CSpinButtonCtrl) hinzu. Initialisieren die Controls in der Methode
OnInitDialog(...) wie folgt:
BOOL CSliderDlg::OnInitDialog()
{
// Animation-Control initialisieren
BOOL bRetCode =
m_CAnimate.Open("152.avi");
ASSERT(bRetCode);
// Spin-Button und
2. Statusanzeige initialisieren
m_CSpin.SetRange(0, 100);
m_CSpin.SetPos(25);
m_CProgress2.SetRange(0,100);
m_CProgress2.SetPos(25);
return TRUE; // Geben Sie TRUE zurück, außer ein Steuerelement
soll ....
} |
Bleibt jetzt nur noch die Kopplung des Drehfeldes mit der Statusanzeige übrig.
Dazu muss der Nachrichtenbearbeiter OnVScroll(...) zum Dialog hinzugefügt
werden. Die Vorgehensweise hierzu ist die gleiche wie weiter oben beim Hinzufügen
der OnHScroll(...) Methode. Nachdem Sie die OnVScroll(...)
Methode hinzugefügt haben, passen Sie deren Code noch wie folgt an:
void CSliderDlg::OnVScroll(UINT
nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
// TODO: Code für die Behandlungsroutine für Nachrichten hier
einfügen ....
m_CProgress2.SetPos(nPos);
CDialog::OnVScroll(nSBCode,
nPos, pScrollBar);
} |
Wenn Sie das Programm starten, so wird die aktuelle Position des Drehfeldes
im links davon befindlichen Textfeld und in der Statusanzeige ausgegeben.
Das fertige Beispiel finden Sie auch 08Dialoge.
|
Damit ist dieses Kapitel im Prinzip beendet. Zum Schluss können Sie sich nun
noch einige Tipps&Tricks zum Thema Dialoge ansehen.
|