pprogramowanie;

// blog o programowaniu i branży IT

rss

Używanie timerów

6 stycznia 2013, kategoria: C++
timer-1

Timer to kontrolka odpowiedzialna za wykonywanie określonego kodu, co określoną ilość sekund. Timery znane są przede wszystkim użytkownikom środowisk takich jak Delphi, C++ Bulider, Visual Basic oraz platformy .NET. W ich przypadku utworzenie kontrolki timera ogranicza się wyłącznie do przeciągnięcia go na formę i dodania odpowiedniego kodu. Timery są na tyle wygodne, że często są wręcz nadużywane.

Wstęp

W internecie można spotkać wiele przykładów kodów źródłowych gdzie timery użyte są po prostu z lenistwa, a problem można było rozwiązać w zwykłej pętli.

Programistom nie przyzwyczajonym do programowania w C++ często przeszkadza brak timerów. Spotkałem się z przykładami tworzenia pseudo timerów polegających na zapętlonej pętli while (true), opóźnianej funkcją sleep(). Jest to rozwiązanie w miarę skuteczne, jednak niepotrzebne i zużywające dużo zasobów. Na szczęście do timerów mamy dostęp zawsze, sięgając po WinAPI. Windows przygotował zestaw gotowych funkcji służących do tworzenia i usuwania timerów w programie.

Uruchomienie timera

Do obsługi timerów musimy znać kilka podstawowych rzeczy:

Timer tworzymy w dowolnym fragmencie kodu. Ja utworzę go podczas startu w funkcji main(). Oto procedura startowa:

UINT TimerId = SetTimer(NULL, 1, 3000, &TimerProc);

Utworzyliśmy Timer. Jego identyfikator to 1. Co 3 sekundy (3000 ms) będzie wykonywał funkcję TimerProc. W dowolnym miejscu w kodzie musimy dołączyć główną funkcję timera. Wygląda ona następująco:

void CALLBACK TimerProc(HWND hWnd, UINT nMsg, UINT nIDEvent, DWORD dwTime)
{
    cout << "Timer dziala" << endl;
}

Nie zapomnij zadeklarować funkcji TimerProc, jeżeli znajduje się ona za funkcją main. Naturalnie musimy dołączyć do programu nagłówek **.

Nasz timer w chwili obecnej działać nie będzie. Każda kontrolka w Windowsie wysyła komunikaty określonego typu. Jak napisałem wyżej, timer wysyła komunikaty WM_TIMER, te komunikaty muszą zostać odebrane przez funkcję GetMessage. Następnie wywołana zostaje funkcja DispatchMessage, która wyśle je do procedury okna. Całość wygląda tak:

while (1)
{
    GetMessage(&Msg, NULL, 0, 0);
    DispatchMessage(&Msg);
}

Jak widzimy obsługa komunikatów znajduje się w zapętlonej pętli. Z tego powodu umieszczamy ją na końcu funkcji main(). Obsługa komunikatów będzie Ci potrzebna w przyszłości do odbierania wszelkich wiadomości z innych kontrolek, takich jak Buttony, Textboxy i wiele innych. Bez obsługi komunikatów nie mogła by funkcjonować żadna aplikacja napisana w Windowsie. Ostatecznie kod naszego programu wygląda następująco:

#include <windows.h>
#include <iostream>
#include <cstdlib>

using namespace std;

void CALLBACK TimerProc(HWND hWnd, UINT nMsg, UINT nIDEvent, DWORD dwTime);

int main()
{
    UINT TimerId = SetTimer(NULL, 1, 3000, &TimerProc); //tworzenie timera
    MSG Msg;
    
    while (1)
    {
        GetMessage(&Msg, NULL, 0, 0);
        DispatchMessage(&Msg); //obsługa wiadomości
    }
    
    return 0;
}

void CALLBACK TimerProc(HWND hWnd, UINT nMsg, UINT nIDEvent, DWORD dwTime)
{
    cout << "Timer dziala" << endl; //procedura timera
}

Usunięcie timera

Po uruchomieniu programu, co 3 sekundy wyświetli się napis Timer działa. Uruchomiony timer jest niezależny od programu. Aby zakończyć jego działanie korzystamy z funkcji KillTimer():

KillTimer(NULL, 1);