Timer in c++
Tags:
Per utilizzare un timer in c++ su Windows bisogna invocare il metodo SetTimer(), definito in windows.h.
UINT_PTR SetTimer( // handle alla finestra associata al timer HWND hWnd, // ID che vogliamo associare al timer UINT_PTR nIDEvent, // tempo del timer in millisecondi UINT uElapse, // metodo da invocare allo scattare del timer TIMERPROC lpTimerFunc );
L’argomento hWnd è un handle alla finestra associata al timer: per semplicità inizialmente lo impostiamo a NULL.
La funzione ritorna sempre un uint che indica l’ID del timer creato. Se hWnd è NULL il secondo parametro verrà ignorato e non possiamo associare direttamente un ID al timer; l’ID ci verrà ritornato dalla funzione, e se questo è diverso da zero allora il timer è stato creato con successo. Se invece hWnd non è nullo, l’ID del timer verrà assegnato con il parametro nIDEvent.
Aggiungiamo quindi una variabile globale dove salviamo l’ID del timer creato:
uint m_timerID;
Definiamo la funzione da invocare quando “scatta” il timer:
void CALLBACK OnTimer(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime)
{
// Inserire qui il codice da eseguire nell'evento OnTimer
}
e infine inseriamo l’inizializzazione del timer dove ci serve:
m_timerID = SetTimer(NULL, 1, (UINT)2500, (TIMERPROC)OnTimer);
In questo caso ho creato un timer che verrà scatenato ogni 2,5 secondi.
Per terminare il timer basta invocare la funzione KillTimer():
KillTimer(NULL, m_timerID);
Un altro modo interessante di utilizzare il metodo SetTimer() è quello di passare NULL al quarto parametro, lpTimerFunc:
m_timerID = SetTimer(hWnd, TIMER_ID, (UINT)2000, (TIMERPROC)NULL);
Dove hWnd è l’handle della nostra finestra. In questo caso per intercettare l’evento del timer bisogna necessariamente aggiungere nel metodo che smista i messaggi (la window procedure) il codice:
case WM_TIMER:
switch (wParam)
{
case TIMER_ID:
// Inserire qui il codice da eseguire nell'evento OnTimer
return 0;
}
In questo caso dobbiamo ricordarci che nel metodo KillTimer() dobbiamo anche passare l’handle della finestra:
KillTimer(hWnd, m_timerID);
Non mi resta che augurarvi buona programmazione tra 2,5 secondi!!! :f2:
Nel post “Classe Timer in c++” si trova una classe che fa da wrapper a queste funzioni.
Se sei interessato a questo post, potresti anche provare a leggere:
-
No related posts
19 Feb 2007 dzamir
ciao,
ho provato ad attivare un timer, con il primo modo suggerito da te, in una dll scritta in visual c++ 6.0, ma non scatta mai la funzione di callback che dovrebbe essere invocata allo scadere del timer.
mi sai dire perchè?
Grazie.
Magari potresti incollarmi le parti più rilevanti del tuo codice. Nel mentre puoi provare a creare un nuovo progetto da zero e riscrivere una piccola funzioncina di test per vedere se funziona (magari c’è qualche problema di altro tipo).
Al più presto comunque pubblicherò un articolo con la classe Timer in c++, quindi se puoi aspettare in caso potresti utilizzare quella.. Potresti anche provare a scaricarti la classe dell’articolo Classe timer in c++.The following is probably the simplest way to create a timer calling back a function in your code. It is based on a “message window” used to process messaqges, thus you don’t have to manage WindowProc nor messages to a window though its handler.
A “seminal form” class to show how this can be implemented follows here. Static callbacks make handling of function pointers easier. A new timer object must be created within main program messaging loop.
Comments are welcome.
********************* API_Timer.h ****************************************
#include
static VOID CALLBACK CallTimedProc(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime);
static void (* Usr_TimedProc)(void);
class API_Timer
{
private:
HWND MsgWinHdlr;
UINT Timr;
public:
API_Timer();
~API_Timer();
void StartTimer(void (* TimedProc)(void), UINT Interval_ms);
void StopTimer();
};
********************* API_Timer.cpp ****************************************
#include “API_Timer.h”
#include
API_Timer::API_Timer()
{
MsgWinHdlr= CreateWindowEx(WS_EX_LEFT,
“Message”,
“ti_msgs”,
WS_CHILD,
1,
1,
1,
1,
HWND_MESSAGE,
(HMENU) NULL,
// get hInstance -> WINAPI WinMain(HINSTANCE hInstance,…..)
GetModuleHandle(NULL),
(LPVOID) NULL);
DWORD le = GetLastError();
};
API_Timer::~API_Timer()
{
DestroyWindow(MsgWinHdlr);
};
void API_Timer::StartTimer(void (* TimedProc)(void), UINT Interval_ms)
{
Timr = SetTimer( MsgWinHdlr, // handle to main window
(UINT_PTR)NULL, // timer identifier
Interval_ms,
(TIMERPROC) CallTimedProc);
DWORD le = GetLastError();
Usr_TimedProc = TimedProc;
};
void API_Timer::StopTimer()
{
Timr = KillTimer( MsgWinHdlr, // handle to window
Timr); // timer identifier
};
VOID CALLBACK CallTimedProc(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime)
{
Usr_TimedProc();
return;
};