我的应用程序在未使用时位于系统托盘中。
用户可以将事件配置为按特定计划发生。例如,他们可能会在下午5点或每个星期三下午3点或每个月的16日上午10点执行任务。
假设我的delphi程序一直在运行,它会在启动时启动,这是delphi支持触发这些预定事件的最佳方式。
显然,TTimer可用于根据已用时间安排事件,但它们似乎不适合此问题。
干杯
答案 0 :(得分:17)
您可以使用我的CRON合规Cromis Scheduler。它甚至支持一些cron没有的东西。例如,基于时间间隔的事件和从/到时间帧。我在很多软件中使用它并证明它本身非常有用。它是免费的,非常轻巧,适用于线程并经过生产测试。如果您需要任何进一步的帮助,请发邮件给我。
其他方式是:
答案 1 :(得分:8)
我会使用Microsoft Task Scheduler API:
http://msdn.microsoft.com/en-us/library/aa383614(VS.85).aspx
如果您不想做“肮脏的工作”,可以使用Delphi Wrappers,但我不知道是否有免费的。您可以查看
如果您不想使用Microsoft Scheduler,可以使用CronJob组件:http://www.appcontrols.com/components.html。它也是共享软件,但很容易实现(只是一个onAlert事件)。
答案 2 :(得分:1)
您需要一个计划组件。有many available,但我似乎无法找到任何免费的。您可以根据TTimer自行构建一个,或尝试访问Task Scheduling API.
然而,让计时器每分钟执行一项任务以检查任务是否到期,太多更简单。
答案 3 :(得分:1)
您可以在程序中实现某种进程间通信,并通过ipc通过Windows调度服务调用的程序触发这些事件。这种方法的优点是您不需要编写用户界面来设置计划,而且ipc可能在其他方面证明是有用的。
答案 4 :(得分:0)
由于您的应用程序正在运行,您可以使用idle事件查看是否已经过预设日期/时间,如果已经过,则执行您的计时。这种方法的唯一副作用是,如果应用程序繁忙,您的事件将不会触发,但是定时器(用于处理消息队列的TTimer需要处理,或者应用程序需要“空闲”)也不会触发除非你使用线程计时器)。
uses
...,DateUtils; // contains IncMinute
type
TForm1 = Class(TForm)
:
procedure FormCreate(Sender: TObject);
private
fTargetDate : tDateTime;
procedure AppIdle(Sender: TObject; var Done: Boolean);
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
fTargetDate := 0.0;
Application.OnIdle := AppIdle;
fTargetDate := IncMinute(Now,2);
end;
procedure TForm1.AppIdle(Sender: TObject; var Done: Boolean);
begin
if (fTargetDate <> 0.0) and (Now >= fTargetDate) then
begin
fTargetDate := 0.0;
ShowMessage('started');
end;
end;
编辑如果您有多次需要运行某些内容,请按日期/时间放置在有序列表中,然后仅跟踪将运行的NEXT时间。当某些内容运行时,它将被删除以供列表使用(或重新安排回列表并重新排序列表)。
答案 5 :(得分:0)
另一种选择是创建一个执行计时器管理的TThread:
type
TestThreadMsg = class(tThread)
private
fTargetDate : tDateTime;
fMsg : Cardinal;
protected
procedure Execute; override;
procedure NotifyApp;
public
constructor Create( TargetDate : TDateTime; Msg:Cardinal);
end;
实现:
constructor TestThreadMsg.Create(TargetDate: TDateTime; Msg: Cardinal);
begin
inherited Create(True);
FreeOnTerminate := true;
fTargetDate := TargetDate;
fMsg := Msg;
Suspended := false;
end;
procedure TestThreadMsg.Execute;
begin
Repeat
if Terminated then exit;
if Now >= fTargetDate then
begin
Synchronize(NotifyApp);
exit;
end;
Sleep(1000); // sleep for 1 second, resoultion = seconds
Until false;
end;
procedure TestThreadMsg.NotifyApp;
begin
SendMessage(Application.MainForm.Handle,fMsg,0,0);
end;
然后可以将其连接到主要表单:
const
WM_TestTime = WM_USER + 1;
TForm1 = Class(TForm)
:
procedure FormCreate(Sender: TObject);
procedure WMTestTime(var Msg:tMessage); message WM_TestTime;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
TestThreadMsg.Create(IncSecond(Now,5),WM_TestTime);
end;
procedure TForm1.WMTestTime(var Msg: tMessage);
begin
ShowMessage('Event from Thread');
end;