PMGuide - Window Timers: Difference between revisions
mNo edit summary |
mNo edit summary |
||
(2 intermediate revisions by one other user not shown) | |||
Line 1: | Line 1: | ||
{{IBM-Reprint}} | {{IBM-Reprint}} | ||
{{PMGuide}} | {{PMGuide}} | ||
A window timer enables an application to post timer messages at specified intervals. This chapter describes how to use window timers in PM applications. | A window timer enables an application to post timer messages at specified intervals. This chapter describes how to use window timers in PM applications. | ||
==About Window Timers== | ==About Window Timers== | ||
A window timer causes the system to post WM_TIMER messages to a message queue at specified time intervals called timeout values. A timeout value is expressed in milliseconds. | A window timer causes the system to post WM_TIMER messages to a message queue at specified time intervals called timeout values. A timeout value is expressed in milliseconds. | ||
Line 18: | Line 17: | ||
Every timer has a unique timer identifier. An application can request that a timer be created with a particular identifier or have the system choose a unique value. When a WM_TIMER message is received, the timer identifier is contained in the first message parameter. Timer identifiers enable an application to determine the source of the WM_TIMER message. Three timer identifiers are reserved by and for the system and cannot be used by applications; these system timer identifiers and their symbolic constants are shown in the following table: | Every timer has a unique timer identifier. An application can request that a timer be created with a particular identifier or have the system choose a unique value. When a WM_TIMER message is received, the timer identifier is contained in the first message parameter. Timer identifiers enable an application to determine the source of the WM_TIMER message. Three timer identifiers are reserved by and for the system and cannot be used by applications; these system timer identifiers and their symbolic constants are shown in the following table: | ||
{|class="wikitable" | |||
!Value||Meaning | |||
|- | |||
|TID_CURSOR||Identifies the timer that controls cursor blinking. Its timeout value is stored in the os2.ini file under the CursorBlinkRate keyname in the PM_ControlPanel section. | |||
|- | |||
|TID_FLASHWINDOW||Identifies the window-flashing timer. | |||
|- | |||
|TID_SCROLL||Identifies the scroll-bar repetition timer that controls scroll-bar response when the mouse button or a key is held down. Its timeout value is specified by the system value SV_SCROLLRATE. | |||
|} | |||
WM_TIMER messages, like WM_PAINT and semaphore messages, are not actually posted to a message queue. Instead, when the time elapses, the system sets a record in the queue indicating which timer message was posted. The system builds the WM_TIMER message when the application retrieves the message from the queue. | WM_TIMER messages, like WM_PAINT and semaphore messages, are not actually posted to a message queue. Instead, when the time elapses, the system sets a record in the queue indicating which timer message was posted. The system builds the WM_TIMER message when the application retrieves the message from the queue. | ||
Although a timer message may be in the queue, if there are any messages with higher priority in the queue, the application retrieves those messages first. If the time elapses again before the message is retrieved, the system does not create a separate record for this timer, meaning that the application should not depend on the timer messages being processed at precise intervals. To check the accuracy of the message, an application can retrieve the actual system time by using the WinGetCurrentTime function. Comparing the actual time with the time of the previous timer message is useful in determining what action to take for the timer. | Although a timer message may be in the queue, if there are any messages with higher priority in the queue, the application retrieves those messages first. If the time elapses again before the message is retrieved, the system does not create a separate record for this timer, meaning that the application should not depend on the timer messages being processed at precise intervals. To check the accuracy of the message, an application can retrieve the actual system time by using the WinGetCurrentTime function. Comparing the actual time with the time of the previous timer message is useful in determining what action to take for the timer. | ||
==Using Window Timers== | ==Using Window Timers== | ||
There are two methods of using window timers. In the first method, you start the timer by using the WinStartTimer function, supplying the window handle and timer identifier. The function associates the timer with the specified window. The following code fragment starts two timers: the first timer is set for every half second (500 milliseconds); the second, for every two seconds (2000 milliseconds). | There are two methods of using window timers. In the first method, you start the timer by using the WinStartTimer function, supplying the window handle and timer identifier. The function associates the timer with the specified window. The following code fragment starts two timers: the first timer is set for every half second (500 milliseconds); the second, for every two seconds (2000 milliseconds). | ||
Line 90: | Line 79: | ||
You can use the WinStopTimer function at any time to stop a timer. The following code fragment demonstrates how to stop a timer: | You can use the WinStopTimer function at any time to stop a timer. The following code fragment demonstrates how to stop a timer: | ||
WinStopTimer(hab, hwnd, ID_TIMER1); /* Stops first timer */ | |||
[[Category:PM Guide]] | |||
[[Category: |
Latest revision as of 21:34, 6 November 2023
Reprint Courtesy of International Business Machines Corporation, © International Business Machines Corporation
A window timer enables an application to post timer messages at specified intervals. This chapter describes how to use window timers in PM applications.
About Window Timers
A window timer causes the system to post WM_TIMER messages to a message queue at specified time intervals called timeout values. A timeout value is expressed in milliseconds.
An application starts the timer for a given window, specifying the timeout value. The system counts down approximately that number of milliseconds and posts a WM_TIMER message to the message queue for the corresponding window. The system repeats the countdown-post cycle continuously until the application stops the timer.
The timeout value can be any value in the range from 0 through 4,294,967,295 (full magnitude of ULONG) for OS/2 Version 3; for previous versions, the maximum value is 65535. However, the operating system cannot guarantee that all values are accurate. The actual timeout depends on how often the application retrieves messages from the queue and the system clock rate. In many computers, the operating system clock ticks about every 50 milliseconds, but this can vary widely from computer to computer. In general, a timer message cannot be posted more frequently than every system clock tick. To make the system post a timer message as often as possible, an application can set the timeout value to 0.
An application starts a timer by using the WinStartTimer function. If a window handle is given, the timer is created for that window. In such case, the WinDispatchMsg function dispatches the WM_TIMER message to the given window when the message is retrieved from the message queue. If a NULL window handle is given, it is up to the application to check the message queue for WM_TIMER messages and dispatch them to the appropriate window.
A new timer starts counting down as soon as it is created. An application can reset or change a timer's timeout value in subsequent calls to the WinStartTimer function. To stop a timer, an application can use the WinStopTimer function.
The system contains a limited number of timers that must be shared among all PM applications; each application should use as few timers as possible. An application can determine how many timers currently are available by checking the SV_CTIMERS system value.
Every timer has a unique timer identifier. An application can request that a timer be created with a particular identifier or have the system choose a unique value. When a WM_TIMER message is received, the timer identifier is contained in the first message parameter. Timer identifiers enable an application to determine the source of the WM_TIMER message. Three timer identifiers are reserved by and for the system and cannot be used by applications; these system timer identifiers and their symbolic constants are shown in the following table:
Value | Meaning |
---|---|
TID_CURSOR | Identifies the timer that controls cursor blinking. Its timeout value is stored in the os2.ini file under the CursorBlinkRate keyname in the PM_ControlPanel section. |
TID_FLASHWINDOW | Identifies the window-flashing timer. |
TID_SCROLL | Identifies the scroll-bar repetition timer that controls scroll-bar response when the mouse button or a key is held down. Its timeout value is specified by the system value SV_SCROLLRATE. |
WM_TIMER messages, like WM_PAINT and semaphore messages, are not actually posted to a message queue. Instead, when the time elapses, the system sets a record in the queue indicating which timer message was posted. The system builds the WM_TIMER message when the application retrieves the message from the queue.
Although a timer message may be in the queue, if there are any messages with higher priority in the queue, the application retrieves those messages first. If the time elapses again before the message is retrieved, the system does not create a separate record for this timer, meaning that the application should not depend on the timer messages being processed at precise intervals. To check the accuracy of the message, an application can retrieve the actual system time by using the WinGetCurrentTime function. Comparing the actual time with the time of the previous timer message is useful in determining what action to take for the timer.
Using Window Timers
There are two methods of using window timers. In the first method, you start the timer by using the WinStartTimer function, supplying the window handle and timer identifier. The function associates the timer with the specified window. The following code fragment starts two timers: the first timer is set for every half second (500 milliseconds); the second, for every two seconds (2000 milliseconds).
WinStartTimer(hab, /* Anchor-block handle */ hwnd, /* Window handle */ ID_TIMER1, /* Timer identifier */ 500); /* 500 milliseconds */ WinStartTimer(hab, /* Anchor-block handle */ hwnd, /* Window handle */ ID_TIMER2, /* Timer identifier */ 2000); /* 2000 milliseconds */
Once these timers are started, the WinDispatchMsg function dispatches WM_TIMER messages to the appropriate window. To process these messages, add a WM_TIMER case to the window procedure for the given window. By checking the first parameter of the WM_TIMER message, you can identify a particular timer, then carry out the actions related to it. The following code fragment shows how to process WM_TIMER messages:
case WM_TIMER: switch (SHORT1FROMMP(mp1)) { /* Obtains timer identifier */ case ID_TIMER1: . . /* Carry out timer-related tasks. */ . return 0; case ID_TIMER2: . . /* Carry out timer-related tasks. */ . return 0; }
In the second method of using a timer, you specify NULL as the hwnd parameter of the WinStartTimer call. The system starts a timer that has no associated window and assigns an arbitrary timer identifier. The following code fragment starts two window timers using this method:
ULONG idTimer1, idTimer2; idTimer1 = WinStartTimer(hab, (HWND) NULL, 0, 500); idTimer2 = WinStartTimer(hab, (HWND) NULL, 0, 2000);
These timers have no associated window, so the application must check the message queue for WM_TIMER messages and dispatch them to the appropriate window procedure. The following code fragment shows a message loop that handles the window timers:
HWND hwndTimerHandler; /* Handle of window for timer messages */ QMSG qmsg; /* Queue-message structure */ while (WinGetMsg(hab, &qmsg, (HWND) NULL, 0, 0)) { if (qmsg.msg == WM_TIMER) qmsg.hwnd = hwndTimerHandler; WinDispatchMsg(hab, &qmsg); }
You can use the WinStopTimer function at any time to stop a timer. The following code fragment demonstrates how to stop a timer:
WinStopTimer(hab, hwnd, ID_TIMER1); /* Stops first timer */