vorheriges KapitelInhaltsverzeichnisStichwortverzeichnisFeedbacknächstes Kapitel


Woche 1

Tag 4

Timer

Oftmals ist eine Anwendung zu erstellen, die eine bestimmte Aktion in regelmäßigen Abständen wiederholen soll - beispielsweise die Uhrzeit in der Statusleiste anzeigen und jede Sekunde aktualisieren oder eine Sicherungsdatei alle fünf Minuten speichern. Derartige Aktionen finden Sie in vielen bekannten Anwendungen, mit denen Sie täglich zu tun haben. Zu den wiederkehrend auszuführenden Aufgaben gehören auch ständige Prüfungen auf Ressourcen, wie man sie von einem Ressourcenmonitor oder Leistungsbarometer her kennt. Diese Beispiele zeigen nur einen Ausschnitt der Situationen, in denen man auf die Timer - oder Zeitgeber - des Betriebssystems Windows zurückgreift.

Heute lernen Sie, wie ...

Funktionsweise von Windows-Timern

Windows-Timer stellen einen Mechanismus bereit, über den man einen oder mehrere Timer mit einer bestimmten Anzahl von Millisekunden auslösen kann. Wenn man einen Timer für ein Intervall von 1000 Millisekunden einrichtet, wird er jede Sekunde ausgelöst. Beim Auslösen eines Timers schickt Windows eine WM_TIMER-Nachricht an Ihre Anwendung. Mit dem Klassen-Assistenten können Sie eine Funktion in Ihre Anwendung einbauen, um diese Timer-Nachricht zu behandeln.

Timer-Ereignisse werden nur dann in die Nachrichtenwarteschlange gestellt, wenn die Warteschlange leer ist und die Anwendung im Leerlauf arbeitet. Sollte die Anwendung beschäftigt sein, stellt Windows keine Timer-Nachrichten in die Nachrichtenwarteschlange. Sollte Ihre Anwendung in diesem Fall mehrere Timer-Nachrichten verpaßt haben, stellt Windows nur eine einzige Timer-Nachricht in die Nachrichtenwarteschlange und sendet Ihrer Anwendung nicht alle Timer-Nachrichten, die aufgetreten sind, während die Anwendung beschäftigt war. Es spielt keine Rolle, wie viele Timer- Nachrichten Ihre Anwendung verpaßt hat - Windows stellt immer nur eine einzige Timer-Nachricht in Ihre Warteschlange.

Beim Starten oder Anhalten eines Timers geben Sie einen ganzzahligen Wert als Timer-ID an. Die Anwendung kann anhand der Timer-ID ermitteln, wann ein Timer ausgelöst hat, sowie Timer starten und stoppen. Eine bessere Vorstellung von dieser Arbeitsweise bekommen Sie, wenn Sie sich mit der heute zu erstellenden Anwendung beschäftigen.

Die Anwendung mit einer Uhr ausstatten

In der heutigen Beispielanwendung kommen zwei Timer zum Einsatz. Der erste Timer verwaltet eine Uhr im Fenster. Dieser Timer läuft immer, solange die Anwendung läuft. Der zweite Timer läßt sich über das Dialogfeld vom Benutzer für beliebige Intervalle konfigurieren. Der Benutzer kann den Timer je nach Bedarf starten und stoppen. Gehen wir also an die Arbeit.

Das Projekt und die Anwendung erstellen

Die heutige Beispielanwendung erstellen Sie in drei Phasen. Zuerst nehmen Sie die Steuerelemente auf, die für die gesamte Anwendung erforderlich sind. In der zweiten Phase fügen Sie den ersten der beiden Timer hinzu. Dieser Timer steuert die Uhr im Dialogfeld der Anwendung. In der dritten Phase kommt der zweite Timer hinzu, den der Benutzer entsprechend seinen Wünschen einstellen, starten und stoppen kann.

Führen Sie die folgenden Schritte aus, um die Anwendung zu erstellen:

1. Arbeiten Sie mit den gleichen Einstellungen des Anwendungs-Assistenten wie in den vergangenen drei Tagen, und erstellen Sie ein neues Projekt namens Timer. Legen Sie den Titel der Anwendung mit Timer fest.

2. Gestalten Sie das Dialogfeld entsprechend Abbildung 4.1 mit den Eigenschaften der Steuerelemente, die in Tabelle 4.1 aufgeführt sind. Denken Sie daran, daß Sie beim Plazieren eines Steuerelements im Fenster mit der rechten Maus klicken können, um das Dialogfeld für die Eigenschaften des Steuerelements über das Kontextmenü zu öffnen.

Tabelle 4.1: Einstellungen der Steuerelementeigenschaften

Objekt

Eigenschaft

Einstellung

Text

ID

Titel

IDC_STATIC

Timer-&Intervall:

Eingabefeld

ID

IDC_INTERVAL

Schaltfläche

ID

Titel

IDC_STARTTIME

Timer &starten

Schaltfläche

ID

Titel

Deaktiviert

IDC_STOPTIMER

Timer &anhalten

eingeschaltet

Text

ID

Titel

IDC_STATIC

Zeit:

Text

ID

Titel

IDC_STATICTIME

Aktuelle Zeit

Text

ID

Titel

IDC_STATIC

Zähler:

Text

ID

Titel

IDC_STATICCOUNT

0

Schaltfläche

ID

Titel

IDC_EXIT

&Beenden

Abbildung 4.1:
Layout des Dialogfelds für die Timer-Anwendung

3. Legen Sie die Tabulator-Reihenfolge fest, wie Sie es am Tag 2 gelernt haben.

4. Fügen Sie für die Schaltfläche Beenden den Code zum Schließen der Anwendung wie am Tag 2 hinzu.

Die Timer-IDs hinzufügen

Da in dieser Anwendung zwei Timer zum Einsatz kommen, nehmen Sie auch zwei IDs in Ihre Anwendung auf, um die beiden Timer zu identifizieren. Führen Sie dazu die folgenden Schritte aus:

1. Klicken Sie im Arbeitsbereich auf der Registerkarte Ressourcen mit der rechten Maustaste über dem Ordner Timer Ressourcen am Beginn des Ressourcenbaumes. Wählen Sie Ressourcensymbole aus dem Kontextmenü, wie es Abbildung 4.2 zeigt.

Abbildung 4.2:
Das Kontextmenü Ressourcen

2. Im Dialogfeld Ressourcensymbole klicken Sie auf die Schaltfläche Neu.

3. Im Dialogfeld Neues Symbol geben Sie ID_CLOCK_TIMER als Symbolname und 1 als Wert ein, wie es Abbildung 4.3 zeigt.

Abbildung 4.3:
Ein neues Ressourcensymbol hinzufügen

4. Wiederholen Sie die Schritte 2 und 3, wobei Sie ID_COUNT_TIMER als Symbolname und 2 als Wert spezifizieren.

5. Klicken Sie auf die Schaltfläche Schliessen, um das Dialogfeld Ressourcensymbole zu schließen. Die beiden Timer-IDs gehören nun zu Ihrer Anwendung und warten auf ihren Einsatz.

Den Uhren-Timer starten

Um den Timer für die Uhr zu starten, bearbeiten Sie die Funktion OnInitDialog, wie Sie es in den vergangenen beiden Tagen getan haben. Nehmen Sie den neuen Code aus Listing 4.1 in die Funktion auf.

Listing 4.1: Die Funktion OnInitDialog

1: BOOL CTimerDlg::OnInitDialog()
2: {
3: CDialog::OnInitDialog();
4: .
5: .
6: .
7: // ZU ERLEDIGEN: Hier zusätzliche Initialisierung einfügen
8:
9: ///////////////////////
10: // EIGENER CODE, ANFANG
11: ///////////////////////
12:
13: // Timer für Uhr starten
14: SetTimer(ID_CLOCK_TIMER, 1000, NULL);
15:
16: ///////////////////////
17: // EIGENER CODE, ENDE
18: ///////////////////////
19:
20: return TRUE; // Geben Sie TRUE zurück, außer ein Steuerelement soll den ÂFokus erhalten
21: }

Der Code in diesem Listing startet den Uhren-Timer mit der Funktion SetTimer. Das erste an die Funktion SetTimer übergebene Argument ist die ID für den Uhren-Timer. Das zweite Argument gibt an, wie oft Sie das Ereignis auslösen möchten. Im vorliegenden Fall wird das Timer-Ereignis alle 1000 Millisekunden, d.h. jede Sekunde, ausgelöst. Im dritten Argument wird die Adresse einer optionalen Callback-Funktion übergeben, die Sie festlegen können, um das Ereignis WM_TIMER zu umgehen. Wenn Sie für dieses Argument den Wert NULL übergeben, stellt Windows das Ereignis WM_TIMER in die Nachrichtenwarteschlange der Anwendung.

Unter einer Callback-Funktion versteht man eine vom Programmierer erstellte Funktion, die das Betriebssystem Windows direkt aufruft. Callback-Funktionen weisen spezielle Definitionen für die Argumente auf, je nachdem, welches Subsystem die Funktion aufruft und aus welchen Gründen. Im Anschluß an die Funktionsdefinition haben Sie aber wieder freie Hand, wie Sie die Funktion gestalten möchten oder müssen.

Die Funktionsweise einer Callback-Funktion beruht darauf, daß man die Adresse der Funktion als Argument an eine Windows-Funktion, die Callback- Funktionen als Argumente akzeptiert, übergibt. Nachdem Sie die Funktionsadresse an Windows übergeben haben, wird die Funktion jedesmal direkt aufgerufen, wenn Windows aufgrund der entsprechenden Bedingungen die Callback-Funktion aufrufen muß.

Das Timer-Ereignis der Uhr behandeln

Nachdem Sie nun einen Timer gestartet haben, müssen Sie noch den Code aufnehmen, der die Timer-Nachrichten behandelt. Dazu führen Sie folgende Schritte aus:

1. Nehmen Sie mit Hilfe des Klassen-Assistenten eine Variable für das Steuerelement IDC_STATICTIME vom Typ CString mit dem Namen m_sTime auf.

2. Fügen Sie mit dem Klassen-Assistenten eine Funktion für die Nachricht WM_TIMER für das Objekt CTimerDlg hinzu.

3. Übernehmen Sie den Code aus Listing 4.2 in die Funktion OnTimer.

Listing 4.2: Die Funktion OnTimer

1: void CTimerDlg::OnTimer(UINT nIDEvent)
2: {
3: // TODO: Code für die Behandlungsroutine für Nachrichten hier einfügen Âund/oder Standard aufrufen
4:
5: ///////////////////////
6: // EIGENER CODE, ANFANG
7: ///////////////////////
8:
9: // Aktuelle Zeit holen
10: CTime curTime = CTime::GetCurrentTime();
11:
12: // Aktuelle Zeit anzeigen
13: m_sTime.Format("%d:%d:%d", curTime.GetHour(),
14: curTime.GetMinute(),
15: curTime.GetSecond());
16:
17: // Dialogfeld aktualisieren
18: UpdateData(FALSE);
19:
20: ///////////////////////
21: // EIGENER CODE, ENDE
22: ///////////////////////
23:
24: CDialog::OnTimer(nIDEvent);
25: }

Der Code in diesem Listing deklariert eine Instanz der Klasse CTime und initialisiert sie mit der aktuellen Systemzeit. Als nächstes setzt die Funktion den String m_sTime auf die aktuelle Uhrzeit und verwendet dabei die Methode Format, um die Zeit in der üblichen Form mit Stunden, Minuten und Sekunden (HH:MM:SS) zu formatieren. Schließlich wird das Dialogfeld mit der aktuellen Uhrzeit aktualisiert. Wenn Sie die Anwendung jetzt kompilieren und ausführen, sollte eine laufende Uhr in der Mitte des Dialogfelds zu sehen sein, wie es Abbildung 4.4 zeigt.

Abbildung 4.4:
Im Dialogfeld der Anwendung ist eine laufende Uhr zu sehen.

Einen zweiten Timer in die Anwendung aufnehmen

Wie Sie sich überzeugen konnten, läßt sich ein einzelner Timer ziemlich leicht in eine Anwendung einbauen. Man braucht dazu nur die Funktion SetTimer aufzurufen und dann den Timer-Code in die Funktion OnTimer zu schreiben. Manchmal benötigt man aber mehrere Timer, die gleichzeitig in ein und derselben Anwendung laufen. In diesem Fall ist die Sache ein wenig komplizierter.

Die Variablen der Anwendung hinzufügen

Bevor Sie den zweiten Timer in die Anwendung einbauen, sind den Steuerelementen ein paar Variablen zuzuordnen. Für den Uhren-Timer war nur eine einzelne Variable erforderlich, um die Zeitanzeige zu aktualisieren. Jetzt brauchen wir zusätzliche Variablen für die anderen Steuerelemente. In Tabelle 4.2 sind diese Variablen zusammengefaßt.

Tabelle 4.2: Variablen für die Steuerelemente

Objekt

Name

Kategorie

Typ

IDC_STATICCOUNT

m_sCount

Wert

CString

IDC_INTERVAL

m_iInterval

Wert

int

IDC_STARTTIME

m_cStartTime

Control

CButton

IDC_STOPTIMER

m_cStopTime

Control

CButton

Nachdem Sie alle Variablen mit dem Klassen-Assistenten hinzugefügt haben, führen Sie die folgenden Schritte aus:

1. Markieren Sie im Klassen-Assistenten die Variable m_iInterval. Tragen Sie in die Eingabefelder unter der Variablenliste als kleinsten Wert 1 und als größten Wert 100000 ein, wie es Abbildung 4.5 zeigt.

Abbildung 4.5:
Den zu prüfenden Bereich für eine Variable festlegen

2. Über die Registerkarte Klassen des Arbeitsbereichs nehmen Sie eine Member- Variable in die Klasse CTimerDlg auf, wie Sie es gestern gelernt haben. Legen Sie den Variablentyp mit int, den Namen als m_iCount und den Zugriff als Privat fest.

3. Mit dem Klassen-Assistenten fügen Sie eine Funktion für die Nachricht EN_CHANGE für die Objekt-ID IDC_INTERVAL (das Eingabefeld) hinzu. In diese Funktion übernehmen Sie den Code aus Listing 4.3.

Listing 4.3: Die Funktion OnChangeInterval

1: void CTimerDlg::OnChangeInterval()
2: {
3: // TODO: Wenn dies ein RICHEDIT-Steuerelement ist, sendet das ÂSteuerelement diese
4: // Benachrichtigung nicht, bevor Sie nicht die Funktion ÂCDialog::OnInitDialog()
5: // überschreiben und CRichEditCrtl().SetEventMask() aufrufen, wobei
6: // eine ODER-Operation mit dem Attribut ENM_CHANGE und der Maske erfolgt.
7:
8: // TODO: Fügen Sie hier Ihren Code für die ÂBenachrichtigungsbehandlungsroutine des Steuerelements hinzu
9:
10: ///////////////////////
11: // EIGENER CODE, ANFANG
12: ///////////////////////
13:
14: // Variablen aktualisieren
15: UpdateData(TRUE);
16:
17: ///////////////////////
18: // EIGENER CODE, ENDE
19: ///////////////////////
20: }

Wenn Sie für die Intervall-Variable des Timers einen Wertebereich festlegen und der Benutzer einen Wert außerhalb des spezifizierten Bereichs eingibt, fordert Visual C++ den Benutzer automatisch zur Eingabe eines Wertes im zulässigen Bereich auf. Diese Aufforderung wird durch den Aufruf der Funktion UpdateData in der Funktion OnChangeInterval ausgelöst. Die als letztes über den Arbeitsbereich hinzugefügte Variable dient als eigentlicher Zähler, der mit jedem Timer-Ereignis inkrementiert wird.

Den Timer für den Zähler starten und stoppen

Damit der zweite Timer funktionsfähig wird, müssen Sie ...

Diese zusätzliche Funktionalität realisieren Sie in folgenden Schritten:

1. Bearbeiten Sie die Funktion OnInitDialog entsprechend dem Code von Listing 4.4.

Listing 4.4: Die aktualisierte Funktion OnInitDialog

1: BOOL CTimerDlg::OnInitDialog()
2: {
3: CDialog::OnInitDialog();
4: .
5: .
6: .
7: // ZU ERLEDIGEN: Hier zusätzliche Initialisierung einfügen
8:
9: ///////////////////////
10: // EIGENER CODE, ANFANG
11: ///////////////////////
12:
13: // Zählerintervall initialisieren
14: m_iInterval = 100;
15:
16: // Dialogfeld aktualisieren
17: UpdateData(FALSE);
18:
19: // Timer für Uhr starten
20: SetTimer(ID_CLOCK_TIMER, 1000, NULL);
21:
22: ///////////////////////
23: // EIGENER CODE, ENDE
24: ///////////////////////
25:
26: return TRUE; // Geben Sie TRUE zurück, außer ein Steuerelement soll den ÂFokus erhalten
27: }

2. Nehmen Sie mit dem Klassen-Assistenten eine Funktion für die Nachricht BN_CLICKED für die Schaltfläche IDC_STARTTIME auf, und fügen Sie den Code gemäß Listing 4.5 in die Funktion OnStarttime ein.

Listing 4.5: Die Funktion OnStarttime

1: void CTimerDlg::OnStarttime()
2: {
3: // TODO: Code für die Behandlungsroutine der Steuerelement- ÂBenachrichtigung hier einfügen
4:
5: ///////////////////////
6: // EIGENER CODE, ANFANG
7: ///////////////////////
8:
9: // Variablen aktualisieren
10: UpdateData(TRUE);
11:
12: // Zähler initialisieren
13: m_iCount = 0;
14: // Zähler für Anzeige formatieren
15: m_sCount.Format("%d", m_iCount);
16:
17: // Dialogfeld aktualisieren
18: UpdateData(FALSE);
19: // Timer starten
20: SetTimer(ID_COUNT_TIMER, m_iInterval, NULL);
21:
22: ///////////////////////
23: // EIGENER CODE, ENDE
24: ///////////////////////
25: }

3. Fügen Sie mit dem Klassen-Assistenten eine Funktion für die Nachricht BN_CLICKED für die Schaltfläche IDC_STOPTIMER hinzu, und übernehmen Sie in die Funktion OnStoptimer den Code entsprechend Listing 4.6.

Listing 4.6: Die Funktion OnStoptimer

1: void CTimerDlg::OnStoptimer()
2: {
3: // TODO: Code für die Behandlungsroutine der Steuerelement- ÂBenachrichtigung hier einfügen
4:
5: ///////////////////////
6: // EIGENER CODE, ANFANG
7: ///////////////////////
8:
9: // Timer anhalten
10: KillTimer(ID_COUNT_TIMER);
11:
12: ///////////////////////
13: // EIGENER CODE, ENDE
14: ///////////////////////
15: }

4. Aktualisieren Sie die Funktion OnTimer mit dem Code gemäß Listing 4.7.

Listing 4.7: Die aktualisierte Funktion OnTimer

1: void CTimerDlg::OnTimer(UINT nIDEvent)
2: {
3: // TODO: Code für die Behandlungsroutine für Nachrichten hier einfügen Âund/oder Standard aufrufen
4:
5: ///////////////////////
6: // EIGENER CODE, ANFANG
7: ///////////////////////
8:
9: // Aktuelle Zeit holen
10: CTime curTime = CTime::GetCurrentTime();
11:
12: // Welcher Timer hat dieses Ereignis ausgelöst?
13: switch (nIDEvent)
14: {
15: // Der Uhren-Timer?
16: case ID_CLOCK_TIMER:
17: // Aktuelle Uhrzeit anzeigen
18: m_sTime.Format("%d:%d:%d", curTime.GetHour(),
19: curTime.GetMinute(),
20: curTime.GetSecond());
21: break;
22: // Der Zähler-Timer?
23: case ID_COUNT_TIMER:
24: // Zähler inkrementieren
25: m_iCount++;
26: // Zähler formatieren und anzeigen
27: m_sCount.Format("%d", m_iCount);
28: break;
29: }
30:
31: // Dialogfeld aktualisieren
32: UpdateData(FALSE);
33:
34: ///////////////////////
35: // EIGENER CODE, ENDE
36: ///////////////////////
37:
38: CDialog::OnTimer(nIDEvent);
39: }

Die Funktion OnInitDialog initialisiert jetzt die Variable m_iInterval mit einem Anfangswert von 100. Um diese Initialisierung im Dialogfenster widerzuspiegeln, wird die Funktion UpdateData aufgerufen.

Die Funktion OnStarttime synchronisiert zuerst die Variablen mit den Werten der Steuerelemente. Damit läßt sich die aktuelle Einstellung der Variablen m_iInterval ermitteln. Als nächstes initialisiert die Funktion die Variable m_iCount mit dem Anfangswert 0 und formatiert dann der Wert in der CString-Variablen m_sCount. Diese Variable wird im Dialogfenster aktualisiert. Als letztes ist der Timer zu starten, wobei man die ID ID_COUNT_TIMER und das Intervall aus der Variablen m_iInterval spezifiziert.

In der Funktion OnStoptimer muß man lediglich den Timer anhalten. Dazu ruft man die Funktion KillTimer auf und übergibt ihr die Timer-ID als einziges Argument.

Die eigentlich interessanten Dinge passieren in der Funktion OnTimer. Hier steht momentan nur der Code zur Behandlung des Timer-Ereignisses für die Uhr. Um die Funktionalität für den Zähler-Timer hinzuzufügen, ist zu ermitteln, welcher Timer diese Funktion ausgelöst hat. Das einzige Argument an die Funktion OnTimer ist aber gerade die Timer-ID. Diese ID läßt sich in einer switch-Anweisung testen, um den Timer herauszufinden, der diese Funktion aufgerufen hat, und um zu steuern, welcher Code daraufhin auszuführen ist. Der Code für den Uhren-Timer bleibt gemäß Listing 4.2 erhalten. Der Code für den Zähler-Timer wird an der entsprechenden Stelle in der switch-Anweisung untergebracht. Er inkrementiert den Zähler und aktualisiert dann die Variable m_sCount auf den neuen Wert.

Wenn Sie die Anwendung jetzt kompilieren und ausführen, können Sie ein Timer-Intervall festlegen und den Timer starten, wie es Abbildung 4.6 zeigt.

Abbildung 4.6:
Im Dialogfeld der Anwendung ist ein laufender Zähler zu sehen.

Die Schaltfläche Anhalten aktivieren

Die Anwendung läuft zwar schon ganz gut, weist aber noch ein kleines Problem auf. Nachdem Sie den zweiten Timer gestartet haben, können Sie ihn nicht mehr anhalten. Beim Festlegen der Eigenschaften für die Steuerelemente haben Sie die Schaltfläche Timer anhalten deaktiviert. Um den Timer anhalten zu können, müssen Sie diese Schaltfläche aktivieren.

Es ist sinnvoll, nach dem Start des Timers die Schaltfläche Anhalten zu aktivieren und die Schaltfläche Starten zu deaktivieren. Sobald der Benutzer den Timer angehalten hat, kehren Sie das Ganze um. Das läßt sich auf die gleiche Weise erreichen, wie Sie die Steuerelemente am Tag 2 aktiviert und deaktiviert haben. Diese Lösung kann man auch ein wenig modifizieren.

Beim Hinzufügen der Variablen für die Steuerelemente haben Sie auch Variablen für die Schaltflächen Starten und Anhalten aufgenommen. Es handelt sich hierbei nicht um normale Variablen, sondern Steuerelementvariablen. Statt nun einen Zeiger auf die Steuerelemente über deren IDs zu ermitteln, können Sie direkt mit den Steuerelementvariablen arbeiten. Überarbeiten Sie dazu die Funktionen OnStarttime und OnStoptimer gemäß Listing 4.8.

Listing 4.8: Die überarbeiteten Funktionen OnStarttime und OnStoptimer

1: void CTimerDlg::OnStarttime()
2: {
3: // TODO: Code für die Behandlungsroutine der Steuerelement- ÂBenachrichtigung hier einfügen
4:
5: ///////////////////////
6: // EIGENER CODE, ANFANG
7: ///////////////////////
8:
9: // Variablen aktualisieren
10: UpdateData(TRUE);
11:
12: // Zähler initialisieren
13: m_iCount = 0;
14: // Zähler für Anzeige formatieren
15: m_sCount.Format("%d", m_iCount);
16:
17: // Dialogfeld aktualisieren
18: UpdateData(FALSE);
19: // Timer starten
20: SetTimer(ID_COUNT_TIMER, m_iInterval, NULL);
21:
22: // Schaltfläche Timer anhalten aktivieren
23: m_cStopTime.EnableWindow(TRUE);
24: // Schaltfläche Timer starten deaktivieren
25: m_cStartTime.EnableWindow(FALSE);
26:
27: ///////////////////////
28: // EIGENER CODE, ENDE
29: ///////////////////////
30: }
31:
32: void CTimerDlg::OnStoptimer()
33: {
34: // TODO: Code für die Behandlungsroutine der Steuerelement- ÂBenachrichtigung hier einfügen
35:
36: ///////////////////////
37: // EIGENER CODE, ANFANG
38: ///////////////////////
39:
40: // Timer anhalten
41: KillTimer(ID_COUNT_TIMER);
42:
43: // Schaltfläche Timer anhalten deaktivieren
44: m_cStopTime.EnableWindow(FALSE);
45: // Schaltfläche Timer starten aktivieren
46: m_cStartTime.EnableWindow(TRUE);
47:
48: ///////////////////////
49: // EIGENER CODE, ENDE
50: ///////////////////////
51: }

Wenn Sie jetzt die Anwendung kompilieren und ausführen, können Sie den Zähler- Timer starten und anhalten, wie es Abbildung 4.7 zeigt. Damit kann der Benutzer mit dem Timer-Intervall experimentieren - verschiedene Intervalle ausprobieren und die Unterschiede beobachten, wobei die Uhr zum Vergleich weiterläuft.

Abbildung 4.7:
Die fertiggestellte Anwendung

Zusammenfassung

Die heutige Lektion hat sich mit dem Einsatz von Timern im Betriebssystem Windows beschäftigt. Timer erlauben es, bestimmte Funktionen in einer Anwendung zeitgesteuert auszulösen. Es wurde gezeigt, wie man mehrere Timer in derselben Anwendung einsetzt, sie gleichzeitig laufen läßt und dabei unterschiedliche Aktionen auslöst.

In den folgenden Tagen gehen wir darauf ein, wie man zusätzliche Dialogfelder einbindet, um Rückmeldungen vom Benutzer zu erhalten. Die Eingaben des Benutzers kann man auswerten und damit das Verhalten der Anwendung kontrollieren. Im Anschluß daran lernen Sie, wie sich Menüs in einer Anwendung realisieren lassen. Anschließend steht die Arbeit mit Text und Schriften auf der Tagesordnung.

Fragen und Antworten

Frage:
Wie groß ist der Bereich, den ich für das Timer-Intervall in meinen Anwendungen festlegen kann?

Antwort:
Der verfügbare Bereich beginnt bei 55 Millisekunden und reicht bis 232 - 1 Millisekunden, d.h. knapp 50 Tage.

Frage:
Wie viele Timer kann man in einer Anwendung gleichzeitig laufen lassen?

Antwort:
Diese Frage läßt sich nicht allgemeingültig beantworten. Allen Anwendungen steht im Betriebssystem Windows eine begrenzte Anzahl von Timern zur Verfügung. Obwohl diese Zahl mehr als ausreichend sein dürfte, wenn alle Anwendungen zusammen nicht mehr als eine Handvoll Timer verwenden, können diese Ressourcen dennoch knapp werden, wenn eine Anwendung eine größere Anzahl Timer für sich in Anspruch nimmt. Als Faustregel gilt, daß man nicht mehr als etwa zwei oder drei Timer gleichzeitig betreiben sollte. Falls die Anwendung eine größere Zahl erfordert, empfiehlt es sich, den Entwurf der Anwendung noch einmal kritisch unter die Lupe zu nehmen und so umzubauen, daß sie mit weniger Timern auskommt.

Frage:
Gibt es eine Möglichkeit, eine Aktion in der Anwendung auszulösen, wenn sich die Anwendung im Leerlauf befindet, statt einen Timer einzusetzen und die Aktion zu starten, wenn man meint, daß die Anwendung im Leerlauf arbeitet?

Antwort:
Ja, die gibt es. Alle Windows-Anwendungen verfügen über eine OnIdle-Funktion, mit der man eine Verarbeitung während der Leerlaufphase auslösen kann. Die Funktion OnIdle kommt am Tag 18 zur Sprache, wenn es um Multitasking geht.

Workshop

Kontrollfragen

1. Auf welche Weise haben Sie die beiden Timer-IDs zu den Ressourcensymbolen hinzugefügt?

2. Welche andere Möglichkeit gibt es, um diese beiden IDs in die Anwendung aufzunehmen?

3. Wie kann man zwei Timer in der Funktion OnTimer auseinanderhalten?

4. Wie viele Timer-Ereignisse empfängt Ihre Anwendung, wenn der Timer für das Intervall von 1 Sekunde eingerichtet wird, die Anwendung 1 Minute beschäftigt ist und somit den Empfang von Timer-Nachrichten unterbindet?

Übung

Überarbeiten Sie Ihre Anwendung dahingehend, daß der Uhren-Timer beim Starten des Zähler-Timers auf das gleiche Intervall wie der Zähler-Timer gesetzt wird. Hält der Benutzer den Zähler-Timer an, soll der Uhren-Timer wieder mit einem Intervall von 1 Sekunde laufen.



vorheriges KapitelInhaltsverzeichnisStichwortverzeichnisFeedbackKapitelanfangnächstes Kapitel


Ein Imprint des Markt&Technik Buch- und Software-Verlag GmbH.
Elektronische Fassung des Titels: Visual C++ 6 in 21 Tagen, ISBN: 3-8272-2035-1