本次专门研究下 SetWaitableTimer 的第二个参数(起始时间).
它有正值、负值、0值三种情况, 前面已用过 0值.
先学习负值(相对时间), 也就是从当前算起隔多长时间开始执行.

这个相对时间是已 1/100 纳秒为单位的, 譬如赋值 3*10000000 相当于 3 秒.
 


  
 s(秒) = ,             ms(毫秒);
 s(秒) = ,,         µs(微妙);
 s(秒) = ,,,     ns(纳秒);
 s(秒) = ,,,, ps(皮秒);


本例效果图:

 



代码文件:



  
 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
  


当我们需要一个绝对时间时, 譬如 2009-2-18 13:10:5, 函数需要的 Int64 值应该是个 TFileTime 格式的时间.

先看三种相关时间类型(TFileTime、TSystemTime、TDateTime)的定义:



  
TFileTime(又名 FILETIME 或 _FILETIME)
_FILETIME = 
  dwLowDateTime: DWORD;
  dwHighDateTime: DWORD;
;

TSystemTime(又名 SYSTEMTIME 或 _SYSTEMTIME)
_SYSTEMTIME = 
  wYear: Word;
  wMonth: Word;
  wDayOfWeek: Word;
  wDay: Word;
  wHour: Word;
  wMinute: Word;
  wSecond: Word;
  wMilliseconds: Word;
;

TDateTime =  Double;

StrToDateTime -> DateTimeToSystemTime -> SystemTimeToFileTime -> LocalFileTimeToFileTime


下面程序指定在 2009年2月18号下午1点10分5秒时运行三个线程(窗体同上, 我已找了个合适的时间测试成功).



  
 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);

  strTime = ;

  ThreadID: DWORD;
  DueTime: Int64;
  st: TSystemTime;
  ft,UTC: TFileTime;
  dt: TDateTime;

  DateTimeToSystemTime(StrToDateTime(strTime), st); 
  SystemTimeToFileTime(st, ft);                     
  LocalFileTimeToFileTime(ft, UTC);                 
  DueTime := Int64(UTC);                            

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

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

 TForm1.FormDestroy(Sender: TObject);

  CloseHandle(hWaitableTimer);
;

.


接下来该是 WaitableTimer 对象的回调函数了.