📄 jvqscheduledevents.pas
字号:
procedure TOpenWriter.WriteSet(SetType: Pointer; Value: Integer);
var
I: Integer;
BaseType: PTypeInfo;
begin
BaseType := GetTypeData(SetType)^.CompType^;
WriteValue(vaSet);
for I := 0 to SizeOf(TIntegerSet) * 8 - 1 do
if I in TIntegerSet(Value) then
WriteStr(GetEnumName(BaseType, I));
WriteStr('');
end;
//=== TJvCustomScheduledEvents ===============================================
constructor TJvCustomScheduledEvents.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FEvents := TJvEventCollection.Create(Self);
end;
destructor TJvCustomScheduledEvents.Destroy;
begin
if not (csDesigning in ComponentState) then
begin
ScheduleThread.RemoveEventComponent(Self);
if AutoSave then
SaveEventStates;
if FWnd <> nil then
DeallocateMessageObject(FWnd);
end;
FEvents.Free;
inherited Destroy;
end;
function TJvCustomScheduledEvents.GetAppStorage: TJvCustomAppStorage;
begin
Result := FAppStorage;
end;
procedure TJvCustomScheduledEvents.SetAppStorage(Value: TJvCustomAppStorage);
begin
FAppStorage := Value;
end;
procedure TJvCustomScheduledEvents.DoEndEvent(const Event: TJvEventCollectionItem);
begin
if Assigned(FOnEndEvent) then
FOnEndEvent(Event);
end;
procedure TJvCustomScheduledEvents.DoStartEvent(const Event: TJvEventCollectionItem);
begin
if Assigned(FOnStartEvent) then
FOnStartEvent(Event);
end;
function TJvCustomScheduledEvents.GetEvents: TJvEventCollection;
begin
Result := FEvents;
end;
procedure TJvCustomScheduledEvents.InitEvents;
var
I: Integer;
begin
for I := 0 to FEvents.Count - 1 do
if FEvents[I].State = sesNotInitialized then
FEvents[I].Start;
end;
procedure TJvCustomScheduledEvents.Loaded;
begin
if not (csDesigning in ComponentState) then
begin
FWnd := QWidgetH(AllocateMessageObject(Self));
if AutoSave then
LoadEventStates;
InitEvents;
ScheduleThread.AddEventComponent(Self);
end;
end;
procedure TJvCustomScheduledEvents.LoadSingleEvent(Sender: TJvCustomAppStorage;
const Path: string; const List: TObject; const Index: Integer);
var
Stamp: TTimeStamp;
TriggerCount: Integer;
DayCount: Integer;
Snooze: TTimeStamp;
SnoozeInterval: TSystemTime;
EventName: string;
Event: TJvEventCollectionItem;
begin
EventName := Sender.ReadString(Sender.ConcatPaths([Path, 'Event '+inttostr(Index), 'Eventname']));
if EventName <> '' then
begin
Stamp.Date := Sender.ReadInteger(Sender.ConcatPaths([Path, 'Event '+inttostr(Index), 'Stamp.Date']));
Stamp.Time := Sender.ReadInteger(Sender.ConcatPaths([Path, 'Event '+inttostr(Index), 'Stamp.Time']));
TriggerCount := Sender.ReadInteger(Sender.ConcatPaths([Path, 'Event '+inttostr(Index), 'TriggerCount']));
DayCount := Sender.ReadInteger(Sender.ConcatPaths([Path, 'Event '+inttostr(Index), 'DayCount']));
Snooze.Date := Sender.ReadInteger(Sender.ConcatPaths([Path, 'Event '+inttostr(Index), 'Snooze.Date']));
Snooze.Time := Sender.ReadInteger(Sender.ConcatPaths([Path, 'Event '+inttostr(Index), 'Snooze.Time']));
SnoozeInterval.wYear := Sender.ReadInteger(Sender.ConcatPaths([Path, 'Event '+inttostr(Index), 'SnoozeInterval.wYear']));
SnoozeInterval.wMonth := Sender.ReadInteger(Sender.ConcatPaths([Path, 'Event '+inttostr(Index), 'SnoozeInterval.wMonth']));
SnoozeInterval.wDay := Sender.ReadInteger(Sender.ConcatPaths([Path, 'Event '+inttostr(Index), 'SnoozeInterval.wDay']));
SnoozeInterval.wHour := Sender.ReadInteger(Sender.ConcatPaths([Path, 'Event '+inttostr(Index), 'SnoozeInterval.wHour']));
SnoozeInterval.wMinute := Sender.ReadInteger(Sender.ConcatPaths([Path, 'Event '+inttostr(Index), 'SnoozeInterval.wMinute']));
SnoozeInterval.wSecond := Sender.ReadInteger(Sender.ConcatPaths([Path, 'Event '+inttostr(Index), 'SnoozeInterval.wSecond']));
SnoozeInterval.wMilliseconds := Sender.ReadInteger(Sender.ConcatPaths([Path, 'Event '+inttostr(Index), 'SnoozeInterval.wMilliseconds']));
Event := TJvEventCollection(List).Add;
Event.Name := EventName;
Event.LoadState(Stamp, TriggerCount, DayCount, Snooze, SnoozeInterval);
end;
end;
procedure TJvCustomScheduledEvents.LoadEventStates (const ClearBefore : Boolean = True);
begin
if ClearBefore then
FEvents.Clear;
if Assigned(AppStorage) then
if AppStorage.PathExists(AppStoragePath) then
AppStorage.ReadList(AppStoragePath, FEvents, LoadSingleEvent);
end;
procedure TJvCustomScheduledEvents.SaveSingleEvent(Sender: TJvCustomAppStorage;
const Path: string; const List: TObject; const Index: Integer);
var
Stamp: TTimeStamp;
TriggerCount: Integer;
DayCount: Integer;
StampDate: Integer;
StampTime: Integer;
SnoozeStamp: TTimeStamp;
SnoozeInterval: TSystemTime;
SnoozeDate: Integer;
SnoozeTime: Integer;
begin
TJvEventCollection(List)[Index].SaveState(Stamp, TriggerCount, DayCount, SnoozeStamp, SnoozeInterval);
StampDate := Stamp.Date;
StampTime := Stamp.Time;
SnoozeDate := SnoozeStamp.Date;
SnoozeTime := SnoozeStamp.Time;
AppStorage.WriteString(AppStorage.ConcatPaths([Path, 'Event '+inttostr(Index), 'Eventname']), FEvents[Index].Name);
AppStorage.WriteInteger(AppStorage.ConcatPaths([Path, 'Event '+inttostr(Index), 'Stamp.Date']), StampDate);
AppStorage.WriteInteger(AppStorage.ConcatPaths([Path, 'Event '+inttostr(Index), 'Stamp.Time']), StampTime);
AppStorage.WriteInteger(AppStorage.ConcatPaths([Path, 'Event '+inttostr(Index), 'TriggerCount']), TriggerCount);
AppStorage.WriteInteger(AppStorage.ConcatPaths([Path, 'Event '+inttostr(Index), 'DayCount']), DayCount);
AppStorage.WriteInteger(AppStorage.ConcatPaths([Path, 'Event '+inttostr(Index), 'Snooze.Date']), SnoozeDate);
AppStorage.WriteInteger(AppStorage.ConcatPaths([Path, 'Event '+inttostr(Index), 'Snooze.Time']), SnoozeTime);
AppStorage.WriteInteger(AppStorage.ConcatPaths([Path, 'Event '+inttostr(Index), 'SnoozeInterval.wYear']), SnoozeInterval.wYear);
AppStorage.WriteInteger(AppStorage.ConcatPaths([Path, 'Event '+inttostr(Index), 'SnoozeInterval.wMonth']), SnoozeInterval.wMonth);
AppStorage.WriteInteger(AppStorage.ConcatPaths([Path, 'Event '+inttostr(Index), 'SnoozeInterval.wDay']), SnoozeInterval.wDay);
AppStorage.WriteInteger(AppStorage.ConcatPaths([Path, 'Event '+inttostr(Index), 'SnoozeInterval.wHour']), SnoozeInterval.wHour);
AppStorage.WriteInteger(AppStorage.ConcatPaths([Path, 'Event '+inttostr(Index), 'SnoozeInterval.wMinute']), SnoozeInterval.wMinute);
AppStorage.WriteInteger(AppStorage.ConcatPaths([Path, 'Event '+inttostr(Index), 'SnoozeInterval.wSecond']), SnoozeInterval.wSecond);
AppStorage.WriteInteger(AppStorage.ConcatPaths([Path, 'Event '+inttostr(Index), 'SnoozeInterval.wMilliseconds']), SnoozeInterval.wMilliseconds);
end;
procedure TJvCustomScheduledEvents.DeleteSingleEvent(Sender: TJvCustomAppStorage; const Path: string;
const List: TObject; const First, Last: Integer);
var
I: Integer;
begin
for I := First to Last do
Sender.DeleteSubTree(Sender.ConcatPaths([Path, 'Event ' + IntToStr(I)]));
end;
procedure TJvCustomScheduledEvents.SaveEventStates;
begin
if Assigned(AppStorage) then
AppStorage.WriteList(AppStoragePath, FEvents, FEvents.Count, SaveSingleEvent, DeleteSingleEvent);
end;
procedure TJvCustomScheduledEvents.StartAll;
var
I: Integer;
begin
for I := 0 to FEvents.Count - 1 do
if FEvents[I].State in [sesPaused, sesNotInitialized] then
FEvents[I].Start;
end;
procedure TJvCustomScheduledEvents.StopAll;
var
I: Integer;
begin
for I := 0 to FEvents.Count - 1 do
FEvents[I].Stop;
end;
procedure TJvCustomScheduledEvents.PauseAll;
var
I: Integer;
begin
for I := 0 to FEvents.Count - 1 do
FEvents[I].Pause;
end;
procedure TJvCustomScheduledEvents.SetEvents(Value: TJvEventCollection);
begin
FEvents.Assign(Value);
end;
procedure TJvCustomScheduledEvents.CMExecEvent(var Msg: TMessage);
begin
with Msg do
try
DoStartEvent(TJvEventCollectionItem(WParam));
TJvEventCollectionItem(WParam).Execute;
DoEndEvent(TJvEventCollectionItem(WParam));
Result := 1;
except
if Assigned(ApplicationHandleException) then
ApplicationHandleException(Self);
end
end;
//=== TJvEventCollection =====================================================
function TJvEventCollection.GetItem(Index: Integer): TJvEventCollectionItem;
begin
Result := TJvEventCollectionItem(inherited Items[Index]);
end;
procedure TJvEventCollection.SetItem(Index: Integer; Value: TJvEventCollectionItem);
begin
inherited Items[Index] := Value;
end;
constructor TJvEventCollection.Create(AOwner: TPersistent);
begin
inherited Create(AOwner, TJvEventCollectionItem);
end;
function TJvEventCollection.Add: TJvEventCollectionItem;
begin
Result := TJvEventCollectionItem(inherited Add);
end;
function TJvEventCollection.Insert(Index: Integer): TJvEventCollectionItem;
begin
Result := TJvEventCollectionItem(inherited Insert(Index));
end;
//=== TJvEventCollectionItem =================================================
constructor TJvEventCollectionItem.Create(Collection: TCollection);
var
NewName: string;
I: Integer;
J: Integer;
function NewNameIsUnique: Boolean;
begin
with TJvEventCollection(Collection) do
begin
J := Count - 1;
while (J >= 0) and not AnsiSameText(Items[J].Name, NewName + IntToStr(I)) do
Dec(J);
Result := J < 0;
end;
end;
procedure CreateNewName;
begin
NewName := 'Event';
I := 0;
repeat
Inc(I);
until NewNameIsUnique;
end;
begin
ScheduleThread.Lock;
try
if csDesigning in TComponent(TJvEventCollection(Collection).GetOwner).ComponentState then
CreateNewName
else
NewName := '';
inherited Create(Collection);
FSchedule := CreateSchedule;
FSnoozeFire := NullStamp;
FScheduleFire := NullStamp;
if NewName <> '' then
Name := NewName + IntToStr(I);
finally
ScheduleThread.Unlock;
end;
end;
destructor TJvEventCollectionItem.Destroy;
begin
ScheduleThread.Lock;
try
inherited Destroy;
finally
ScheduleThread.Unlock;
end;
end;
procedure TJvEventCollectionItem.Triggered;
begin
FState := sesTriggered;
end;
procedure TJvEventCollectionItem.DefineProperties(Filer: TFiler);
var
SingleShot: Boolean;
DailySched: Boolean;
WeeklySched: Boolean;
MonthlySched: Boolean;
YearlySched: Boolean;
MIK: TScheduleIndexKind;
YIK: TScheduleIndexKind;
begin
// Determine settings to determine writing properties.
SingleShot := Schedule.RecurringType = srkOneShot;
DailySched := Schedule.RecurringType = srkDaily;
WeeklySched := Schedule.RecurringType = srkWeekly;
MonthlySched := Schedule.RecurringType = srkMonthly;
YearlySched := Schedule.RecurringType = srkYearly;
if MonthlySched then
MIK := (Schedule as IJclMonthlySchedule).IndexKind
else
MIK := sikNone;
if YearlySched then
YIK := (Schedule as IJclYearlySchedule).IndexKind
else
YIK := sikNone;
// Standard properties
Filer.DefineProperty('StartDate', PropStartDateRead, PropStartDateWrite, True);
Filer.DefineProperty('RecurringType', PropRecurringTypeRead, PropRecurringTypeWrite, not SingleShot);
Filer.DefineProperty('EndType', PropEndTypeRead, PropEndTypeWrite, not SingleShot);
Filer.DefineProperty('EndDate', PropEndDateRead, PropEndDateWrite, not SingleShot and
(Schedule.EndType = sekDate));
Filer.DefineProperty('EndCount', PropEndCountRead, PropEndCountWrite, not SingleShot and
(Schedule.EndType in [sekTriggerCount, sekDayCount]));
// Daily frequency properties
Filer.DefineProperty('Freq_StartTime', PropFreqStartTimeRead, PropFreqStartTimeWrite,
not SingleShot);
Filer.DefineProperty('Freq_EndTime', PropFreqEndTimeRead, PropFreqEndTimeWrite, not SingleShot);
Filer.DefineProperty('Freq_Interval', PropFreqIntervalRead, PropFreqIntervalWrite,
not SingleShot);
// Daily schedule properties
Filer.DefineProperty('Daily_EveryWeekDay', PropDailyEveryWeekDayRead, PropDailyEveryWeekDayWrite,
DailySched);
Filer.DefineProperty('Daily_Interval', PropDailyIntervalRead, PropDailyIntervalWrite,
DailySched and not (Schedule as IJclDailySchedule).EveryWeekDay);
// Weekly schedule properties
Filer.DefineProperty('Weekly_DaysOfWeek', PropWeeklyDaysOfWeekRead, PropWeeklyDaysOfWeekWrite,
WeeklySched);
Filer.DefineProperty('Weekly_Interval', PropWeeklyIntervalRead, PropWeeklyIntervalWrite,
WeeklySched);
// Monthly schedule properties
Filer.DefineProperty('Monthly_IndexKind', PropMonthlyIndexKindRead, PropMonthlyIndexKindWrite,
MonthlySched);
Filer.DefineProperty('Monthly_IndexValue', PropMonthlyIndexValueRead, PropMonthlyIndexValueWrite,
MonthlySched and (MIK in [sikDay..sikSunday]));
Filer.DefineProperty('Monthly_Day', PropMonthlyDayRead, PropMonthlyDayWrite, MonthlySched and
(MIK in [sikNone]));
Filer.DefineProperty('Monthly_Interval', PropMonthlyIntervalRead, PropMonthlyIntervalWrite,
MonthlySched);
// Yearly schedule properties
Filer.DefineProperty('Yearly_IndexKind', PropYearlyIndexKindRead, PropYearlyIndexKindWrite,
YearlySched);
Filer.DefineProperty('Yearly_IndexValue', PropYearlyIndexValueRead, PropYearlyIndexValueWrite,
YearlySched and (YIK in [sikDay..sikSunday]));
Filer.DefineProperty('Yearly_Day', PropYearlyDayRead, PropYearlyDayWrite, YearlySched and
(YIK in [sikNone, sikDay]));
Filer.DefineProperty('Yearly_Month', PropYearlyMonthRead, PropYearlyMonthWrite, YearlySched);
Filer.DefineProperty('Yearly_Interval', PropYearlyIntervalRead, PropYearlyIntervalWrite,
YearlySched);
end;
procedure TJvEventCollectionItem.DoExecute(const IsSnoozeFire: Boolean);
begin
if Assigned(FOnExecute) then
FOnExecute(Self, IsSnoozeFire);
end;
function TJvEventCollectionItem.GetDisplayName: string;
begin
Result := Name;
end;
function TJvEventCollectionItem.GetNextFire: TTimeStamp;
begin
if IsNullTimeStamp(FSnoozeFire) or (CompareTimeStamps(FSnoozeFire, FScheduleFire) > 0) then
Result := FScheduleFire
else
Result := FSnoozeFire;
end;
procedure TJvEventCollectionItem.Execute;
var
IsSnoozeFire: Boolean;
begin
if State <> sesTriggered then
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -