Jump to content

PMGuide - Window Timers: Difference between revisions

From EDM2
No edit summary
mNo edit summary
Line 1: Line 1:
{{IBM-Reprint}}
{{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.  


Line 68: Line 70:
                 return 0;
                 return 0;
         }
         }
{{IBM-Reprint}}
{{PMGuide}}


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:
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:

Revision as of 15:11, 4 November 2023

Reprint Courtesy of International Business Machines Corporation, © International Business Machines Corporation

Presentation Manager Programming Guide and Reference
  1. How to Use this Book
  2. Device Functions
  3. Direct Manipulation Functions
  4. Dynamic Data Formatting Functions
  5. Hooks and Procedures
  6. Profile Functions
  7. Spooler Functions
  8. Window Functions
  9. Message Processing
  10. Data Types
  11. Errors
  12. Atom Tables
  13. Button Controls
  14. Clipboards
  15. Combination Box
  16. Container Controls
  17. Control Windows
  18. Cursors
  19. Dialog Windows
  20. Direct Manipulation
  21. Drawing in Windows
  22. Dynamic Data Exchange
  23. Entry-Field Controls
  24. File Dialog Controls
  25. Font Dialog Controls
  26. Frame Windows
  27. Hooks
  28. Initialization Files
  29. Keyboard Accelerators
  30. List-Box Controls
  31. Menus
  32. Messages and Message Queues
  33. Multiple-Line Entry Field Controls
  34. Mouse and Keyboard Input
  35. Mouse Pointers and Icons
  36. Notebook Controls
  37. Painting and Drawing
  38. Presentation Parameters
  39. Resource Files
  40. Scroll-Bar Controls
  41. Slider Controls
  42. Spin Button Controls
  43. Static Controls
  44. Title-Bar Controls
  45. Value Set Controls
  46. Windows
  47. Window Classes
  48. Window Procedures
  49. Window Timers
  50. Appendices
  51. Notices
  52. Glossary

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 */