CreateWaitableTimer(
  lpTimerAttributes: PSecurityAttributes; 
  bManualReset: BOOL;    
  lpTimerName: PWideChar 
): THandle; ;     

 SetWaitableTimer(
  hTimer: THandle;                         
   lpDueTime: TLargeInteger;            
  lPeriod: Longint;                        
  pfnCompletionRoutine: TFNTimerAPCRoutine;
  lpArgToCompletionRoutine: Pointer;       
  fResume: BOOL                            
): BOOL; ;                          


WaitableTimer 对象较复杂, 其基本的理念是让等候的线程在指定的时间运行.

像其他同类对象一样, 先要建立(CreateWaitableTimer), 建立函数的第二个参数决定是调度一个线程还是所有等候的线程; 这一点和信号对象(Semaphore) 有些类似, 不过 Semaphore 可以指定可驱动线程的具体数目.

和其他同类对象不同的是: 在 CreateWaitableTimer 以后, WaitableTimer 对象并没有马上开始工作;
再调用 SetWaitableTimer 函数后才能让它发挥作用. 这又有点像 Event 对象.

SetWaitableTimer 函数比较麻烦, 得慢慢来, 譬如这样使用:



  
  hWaitableTimer: THandle; 

 TForm1.Button1Click(Sender: TObject);

  DueTime: Int64;

  
  hWaitableTimer := CreateWaitableTimer(, True, ); 

  DueTime := ; 
  SetWaitableTimer(hWaitableTimer, 
                   DueTime,        
                   ,              
                   ,            
                   ,            
                   False 
                   );
;



第一个例子我们将尽量简单的使用它(但这样体现不出它的优势):
CreateWaitableTimer 时我们就决定让它可控制多个线程;
SetWaitableTimer 时先让它立即参与控制, 只执行一次, 也不使用回调函数.



本例效果图:
 



代码文件:



  
 Unit1;




  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;


  TForm1 = (TForm)
    Button1: TButton;
     Button1Click(Sender: TObject);
     FormDestroy(Sender: TObject);
  ;


  Form1: TForm1;






  f: Integer;
  hWaitableTimer: THandle; 

 MyThreadFun(p: Pointer): DWORD; ;

  i,y: Integer;

  Inc(f);
  y :=  * f;
   WaitForSingleObject(hWaitableTimer, INFINITE) = WAIT_OBJECT_0 
  
     i :=    
    
      Form1.Canvas.Lock;
      Form1.Canvas.TextOut(, y, IntToStr(i));
      Form1.Canvas.Unlock;
      Sleep();
    ;
  ;
  Result := ;
;

 TForm1.Button1Click(Sender: TObject);

  ThreadID: DWORD;
  DueTime: Int64;

  hWaitableTimer := CreateWaitableTimer(, True, );
  DueTime := ;
  SetWaitableTimer(hWaitableTimer, DueTime, , , , False);

  Repaint; f := ;
  CreateThread(, , @MyThreadFun, , , ThreadID);
  CreateThread(, , @MyThreadFun, , , ThreadID);
  CreateThread(, , @MyThreadFun, , , ThreadID);
;

 TForm1.FormDestroy(Sender: TObject);

  CloseHandle(hWaitableTimer);
;

.


窗体文件:



  
 Form1: TForm1
  Left = 
  Top = 
  Caption = 
  ClientHeight = 
  ClientWidth = 
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -
  Font.Name = 
  Font.Style = []
  OldCreateOrder = False
  OnDestroy = FormDestroy
  PixelsPerInch = 
  TextHeight = 
   Button1: TButton
    Left = 
    Top = 
    Width = 
    Height = 
    Caption = 
    TabOrder = 
    OnClick = Button1Click
  


下面是一个每隔半秒钟(500ms)执行一次的例子(窗体文件同上):



本例效果图:
 



代码文件:



  
 Unit1;




  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;


  TForm1 = (TForm)
    Button1: TButton;
     Button1Click(Sender: TObject);
     FormDestroy(Sender: TObject);
  ;


  Form1: TForm1;






  f: Integer;
  hWaitableTimer: THandle;

 MyThreadFun(p: Pointer): DWORD; ;

  i,y: Integer;

  Inc(f);
  y :=  * f;

  
   i :=    
  
     WaitForSingleObject(hWaitableTimer, INFINITE) = WAIT_OBJECT_0 
    
      Form1.Canvas.Lock;
      Form1.Canvas.TextOut(, y, IntToStr(i));
      Form1.Canvas.Unlock;
    ;
  ;
  Result := ;
;

 TForm1.Button1Click(Sender: TObject);

  ThreadID: DWORD;
  DueTime: Int64;

  hWaitableTimer := CreateWaitableTimer(, False, ); 
  DueTime := ;
  SetWaitableTimer(hWaitableTimer, DueTime, , , , False); 

  Repaint; f := ;
  CreateThread(, , @MyThreadFun, , , ThreadID);
  CreateThread(, , @MyThreadFun, , , ThreadID);
  CreateThread(, , @MyThreadFun, , , ThreadID);
;

 TForm1.FormDestroy(Sender: TObject);

  CloseHandle(hWaitableTimer);
;

.