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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
Damit der zweite Timer funktionsfähig wird, müssen Sie ...
m_iInterval
initialisieren,
IDC_STARTTIME
klickt,
m_iCount
inkrementieren und das Dialogfeld
aktualisieren,
IDC_STOPTIMER
klickt.
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 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
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.
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.
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?
Ü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.