Timers in a console program
I am writing C++ code using the Windows API.
If I w开发者_StackOverflowant to use SetTimer
and its friends inside a program that does not present a GUI, I know that I can use SetTimer(NULL, 1, 2000, Timerflow)
, with NULL
being the hWnd
argument.
How do I write the code for handling, starting and killing the timer?
Have a look at CreateWaitableTimer()
, SetWaitableTimer()
and WaitForSingleObject()
. No callbacks or message handling needed. See MSDN's example.
You can use the SetTimer()
function directly using the Win32 API, and without the use of any wrapper classes (MFC, etc.).
Keep in mind that that windows timers work with the GUI event loop. If you don't process events using the GetMessage()
or PeekMessage()
functions, you won't get notified when the timer elapses. You'll also need to create a window to which the timer will be attached (the WM_TIMER
message will be reported in that window's window procedure.
Check out the documentation for GetMessage()
to learn how to write an event loop. Also take a look at the "Creating a Timer" to learn how to handle the WM_TIMER
message.
Edit: Overview of steps to take
- Write a window procedure: See below for an example.
- Register a window class: define the window class and set the window procedure to the above function. Use the
RegisterClass()
function to register the structure. - Create a window: Use the
CreateWindow()
function to create a window of the class you just registered. - Run the event loop: Use the
GetMessage()
function to process messages. TheDispatchMessage()
call in that loop will forwardWM_TIMER
events to your window procedure and you can handle the message from there.
Steps 1, 2, and 3 should be part of your WinMain()
function. Here is an overview of the key steps (intentionally incomplete, check documentation to know how to handle errors and cleanup):
LRESULT __stdcall MyWindowProcedure
( HWND window, UINT message, WPARAM wparam, LPARAM lparam )
{
if (message == WM_TIMER) {
// timer elapsed.
}
return DefWindowProc(window, message, wparam, lparam);
}
int __stdcall WinMain ( HINSTANCE application, HINSTANCE, LPSTR, int )
{
::WNDCLASS klass;
// ...
klass.lpfnWndProc = &MyWindowProcedure;
RegisterClass(&klass);
// ...
HWND window = CreateWindow(klass.lpszClassName, ...);
// ...
const DWORD SECOND = 1000;
const DWORD MINUTE = 60 * SECOND;
UINT_PTR timer = SetTimer(window, 0, 2*MINUTE, 0);
// ...
MSG message;
while (GetMessage(&message, window, 0, 0) > 0)
{
TranslateMessage(&message);
DispatchMessage(&message);
}
// ...
}
精彩评论