下面这段程序是我自己写的系统定时且延时关机代码,可是有点问题,谁帮我看一下
var
  Form1: TForm1;
  connectflag:boolean;
  str:string;
  hookHandle: THandle;
  dialogHandle: THandle;
  second: Integer;implementation{$R *.dfm}
//倒计时函数
function CBTHookCallback(nCode: Integer;
  wParam: WPARAM;
  lParam: LPARAM
  ): Integer; stdcall;
begin
  case nCode of
    HCBT_ACTIVATE:
      begin
        dialogHandle := wParam;
        second := 30;
        UnhookWindowsHookEx(hookHandle);
      end;
  end;
  Result := CallNextHookEx(hookHandle, nCode, wParam, lParam);
end;//定时关机函数
procedure guanji();
var
hToken:THandle;
tkp : TOKEN_PRIVILEGES;
ReturnLength : DWord;
begin
if (not OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES or TOKEN_ALL_ACCESS or TOKEN_QUERY, hToken))then
begin
application.Terminate;
end;LookupPrivilegeValue(nil,'SeShutdownPrivilege',tkp.Privileges[0].Luid);
tkp.PrivilegeCount := 1;
tkp.Privileges[0].Attributes :=SE_PRIVILEGE_ENABLED;
ReturnLength :=0;
AdjustTokenPrivileges(hToken, FALSE, tkp, 0,nil,ReturnLength);
if (GetLastError() <> ERROR_SUCCESS) then
begin
application.Terminate;
end;
if (not ExitWindowsEx(EWX_POWEROFF, 0)) then
begin
application.Terminate;
end;
end;
//操作函数:关机、重启、注销。
procedure operatecomputer(statue:longword);
var
hToken:THandle;
tkp : TOKEN_PRIVILEGES;
ReturnLength : DWord;
begin
if (not OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES or TOKEN_ALL_ACCESS or TOKEN_QUERY, hToken))then
begin
application.Terminate;
end;
LookupPrivilegeValue(nil,'SeShutdownPrivilege',tkp.Privileges[0].Luid);
tkp.PrivilegeCount := 1;
tkp.Privileges[0].Attributes :=SE_PRIVILEGE_ENABLED;
ReturnLength :=0;
AdjustTokenPrivileges(hToken, FALSE, tkp, 0,nil,ReturnLength);
if (GetLastError() <> ERROR_SUCCESS) then
begin
application.Terminate;
end;
if (not ExitWindowsEx(statue, 0)) then
begin
application.Terminate;
end;
end;
procedure TForm1.Button3Click(Sender: TObject);
begin
  timer3.Enabled:=false;
  button1.Enabled:=true;
  button3.Enabled:=false;
end;procedure TForm1.Timer2Timer(Sender: TObject);
begin
   Label4.Caption:='现在是:  '+formatdatetime('yy/mm/dd',now)+'  ';
   label3.Caption:=formatdatetime('hh:mm:ss',now);
end;
//问题就出现在这里,我不知道该如何把延时完成后在触发guanji()函数procedure TForm1.Timer3Timer(Sender: TObject);
begin
//倒计时处理
    Dec(second);
    if second <= 0 then
    begin
      PostMessage(dialogHandle, WM_CLOSE, 0, 0);
     // TTimer(Sender).Enabled := False;
    end;
      SetWindowText(dialogHandle, PChar(Format('倒计时(%d)', [second])));
if timetostr(now)=edit1.Text then
  begin      hookHandle := SetWindowsHookEx(WH_CBT, CBTHookCallback, HInstance, 0);
      MessageBox(Handle, '系统正在关机', '倒计时(30)', 0);
      guanji();
  end;

end;
procedure TForm1.FormCreate(Sender: TObject);
var myinifile:tinifile;
path,ipaddress:string;
begin
timer2.Enabled:=true;
path:=extractfilepath(paramstr(0))+'config.ini';
  myinifile:=tinifile.Create(path);
  ipaddress:=myinifile.ReadString ('server','ip','');
  if ipaddress='' then
    begin
   application.MessageBox('ini文件丢失或损坏!','提示',mb_iconwarning);
  application.Terminate;
    end
  else
   clientsocket1.Host:=ipaddress; 
end;procedure TForm1.ClientSocket1Connect(Sender: TObject;
  Socket: TCustomWinSocket);
begin
connectflag:=true;
timer1.Enabled:=false;
end;
procedure TForm1.ClientSocket1Error(Sender: TObject;
  Socket: TCustomWinSocket; ErrorEvent: TErrorEvent;
  var ErrorCode: Integer);
begin
connectflag:=false;
timer1.Enabled:=true;
errorcode:=0;
end;procedure TForm1.ClientSocket1Disconnect(Sender: TObject;
  Socket: TCustomWinSocket);
begin
connectflag:=false;
timer1.Enabled:=true;
end;procedure TForm1.Timer1Timer(Sender: TObject);
begin
if  connectflag= false then
   begin
   clientsocket1.Active:=true;
   timer1.Enabled:=false;
   end
   else
   timer1.Enabled:=false;
end; 
procedure TForm1.ClientSocket1Read(Sender: TObject;
  Socket: TCustomWinSocket);
var b:string;
begin
b:=socket.ReceiveText;
case strtoint(b) of
1: begin
     if win32platform =ver_platform_win32_windows then
     exitwindowsex(ewx_force+ewx_shutdown+ewx_poweroff,32);
     if win32platform =ver_platform_win32_NT then
     operatecomputer(ewx_poweroff);   //ewx_logoff 为关机
     end;
2:   begin
     if win32platform =ver_platform_win32_windows then
     exitwindowsex(ewx_force+ewx_shutdown+ewx_poweroff,32);
     if win32platform =ver_platform_win32_NT then
     operatecomputer(ewx_reboot);   //ewx_reboot 为重启
     end;
3:   begin
     if win32platform =ver_platform_win32_windows then
     exitwindowsex(ewx_force+ewx_shutdown+ewx_poweroff,32);
     if win32platform =ver_platform_win32_NT then
     operatecomputer(ewx_logoff);   //ewx_logoff 为注销
     end;
    end;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
if edit1.Text='' then
  showmessage('请输入正确格式的时间!')
else
  begin
    timer3.Enabled:=true;
    button1.Enabled:=false;
    button3.Enabled:=true;
end;
end;
end.

解决方案 »

  1.   

    简单处理办法:是在弹出这个对话框MessageBox(Handle, '系统正在关机', '倒计时(30)', 0)之后,起一个TTimer来执行guji函数。
      

  2.   

    有笔误,是在MessageBox(Handle, '系统正在关机', '倒计时(30)', 0)之前起一个TTimer来执行。
      

  3.   

    分少没有关系,我可以另起一个在给你们加分,只要能回答一下就可以
    SQLDebug_Fan我问你一下,在起一个TTimer是什么 意思,没有太明白
      

  4.   

    可以创建TTimer,然后设置TTimer的Interval,然后再编写TTimer的事件就可以了,具体参考:unit Unit1;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, ExtCtrls, StdCtrls;type
      TForm1 = class(TForm)
        btn1: TButton;
        tmr1: TTimer;
        procedure btn1Click(Sender: TObject);
        procedure tmr1Timer(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }
      end;var
      Form1: TForm1;implementation{$R *.dfm}procedure TForm1.btn1Click(Sender: TObject);
    begin
      tmr1.Interval := 30 *1000;
      tmr1.Enabled := True;
      MessageBox(Handle, '系统正在关机', '倒计时', 0);
    end;procedure TForm1.tmr1Timer(Sender: TObject);
    begin
      tmr1.Enabled := False;
      //执行关机
    end;end.
      

  5.   


    var
      Form1:TForm;
      TimeOut:integer=30;//定义一个全局变量procedure TForm1.Timer1Timer(Sender: TObject);
    begin
    //刷新时间的过程……
    //如果时间到了
    TimeOut:=30;//定好30
    Timer3.Enabled := True;//开启定时器,每1秒跳一次。跳30次正好30秒。
    end;procedure TForm1.Timer1Timer(Sender: TObject);
    begin
    TimeOut:=TimeOut-1;   //每一秒减1
    if TimeOut <= 0 then  //减30次,这个变量就为0了。或小于0都是符合条件的
    guanji();           //符合条件了就关机。
    end;就是这个样子,至于你有取消或什么的,直接把TimeOut:=30;然后再Timer3.Enabled := False;//关了定时器。就可以取消了