⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 jvqtimerlist.pas

📁 East make Tray Icon in delphi
💻 PAS
📖 第 1 页 / 共 2 页
字号:
procedure TJvTimerList.UpdateTimer;
var
  TimerInterval: Cardinal;
begin
  if not (csDesigning in ComponentState) then
  begin
    if Events.FInterval <= MaxTimerInterval then
      TimerInterval := Events.FInterval
    else
    if (Events.FInterval - Events.FStartInterval) <= MaxTimerInterval then
    begin
      TimerInterval := Cardinal(Events.FInterval - Events.FStartInterval);
      Events.FStartInterval := 0;
    end
    else
    begin
      TimerInterval := MaxTimerInterval;
      Events.FStartInterval := Events.FStartInterval + MaxTimerInterval;
    end;
    if not (csDesigning in ComponentState) and (FWndHandle <> INVALID_HANDLE_VALUE) then
    begin
      KillTimer(FWndHandle, 1);
      if Events.EnabledCount = 0 then
        Events.Deactivate
      else
      if Events.FInterval > 0 then
        if SetTimer(FWndHandle, 1, TimerInterval, nil) = 0 then
        begin
          Events.Deactivate;
          raise EOutOfResources.CreateRes(@SNoTimers);
        end;
    end;
  end;
end;

procedure TJvTimerList.SetEvents(const Value: TJvTimerEvents);
begin
  FEvents.Assign(Value);
end;

procedure TJvTimerList.SetActive(Value: Boolean);
var
  StartTicks: Longint;
begin
  if FActive <> Value then
  begin
    if not (csDesigning in ComponentState) then
    begin
      if Value then
      begin
        FWndHandle := AllocateHWndEx(TimerWndProc);
        StartTicks := GetTickCount;
        Events.UpdateEvents(StartTicks);
        Events.CalculateInterval(StartTicks);
        if Sorted then
          Events.Sort;
        UpdateTimer;
      end
      else
      begin
        KillTimer(FWndHandle, 1);
        DeallocateHWndEx(FWndHandle);
        FWndHandle := INVALID_HANDLE_VALUE;
        if Assigned(FOnFinish) then
          FOnFinish(Self);
      end;
      Events.FStartInterval := 0;
    end;
    FActive := Value;
  end;
end;

procedure TJvTimerList.DoTimer(Event: TJvTimerEvent);
begin
  with Event do
    if Assigned(FOnTimer) then
      FOnTimer(Event);
  if Assigned(FOnTimers) then
    FOnTimers(Self, Event.Handle);
end;

//===TJvTimerEvents ==========================================================

constructor TJvTimerEvents.Create(AOwner: TPersistent);
begin
  if not (AOwner is TJvTimerList) then
    raise EJVCLException.CreateRes(@RsEOwnerMustBeTJvTimerList);
  inherited Create(AOwner, TJvTimerEvent);
  FParent := TJvTimerList(AOwner);
end;



procedure TJvTimerEvents.Activate;
begin
  FParent.Active := True;
end;

function TJvTimerEvents.Add: TJvTimerEvent;
begin
  Result := TJvTimerEvent(inherited Add); 
end;

procedure TJvTimerEvents.Assign(Source: TPersistent);
var
  I: Integer;
begin
  if Source is TJvTimerEvents then
  begin
    Clear;
    for I := 0 to TJvTimerEvents(Source).Count - 1 do
      Add.Assign(TJvTimerEvents(Source).Items[I]);
  end
  else
    inherited Assign(Source);
end;

procedure TJvTimerEvents.CalculateInterval(StartTicks: Integer);
var
  I: Integer;
  ExitLoop: Boolean;
begin
  if not (csDesigning in (Owner as TJvTimerList).ComponentState) then
  begin
    if Count = 0 then
      FInterval := 0
    else
    begin
      FStartInterval := 0;
      FInterval := MaxLongint;
      for I := 0 to Count - 1 do
        with Items[I] do
          if Enabled and (Interval > 0) then
          begin
            if Interval < Self.FInterval then
              Self.FInterval := Interval;
            if Self.FInterval > (Interval - (StartTicks - FLastExecute)) then
              Self.FInterval := (Interval - (StartTicks - FLastExecute));
          end;
      if FInterval < MinInterval then
        FInterval := MinInterval;
      if FInterval = MaxLongint then
        FInterval := 0
      else
      begin
        repeat
          ExitLoop := True;
          for I := 0 to Count - 1 do
            with Items[I] do
              if (Interval mod Self.FInterval) <> 0 then
              begin
                Dec(Self.FInterval, Interval mod Self.FInterval);
                ExitLoop := False;
                Break;
              end;
        until ExitLoop or (FInterval <= MinInterval);
        if FInterval < MinInterval then
          FInterval := MinInterval;
      end;
    end;
  end;
end;

procedure TJvTimerEvents.Deactivate;
begin
  if not (csLoading in FParent.ComponentState) then
    FParent.Active := False;
end;

procedure TJvTimerEvents.DeleteByHandle(AHandle: THandle);
var
  I: Integer;
begin
  I := ItemIndexByHandle(AHandle);
  if I >= 0 then
    Delete(I);
  if FParent.Active then
  begin
    CalculateInterval(GetTickCount);
    FParent.UpdateTimer;
  end;
end;

function TJvTimerEvents.GetEnabledCount: Integer;
var
  I: Integer;
begin
  Result := 0;
  for I := 0 to Count - 1 do
    if Items[I].Enabled then
      Inc(Result);
end;

function TJvTimerEvents.GetItem(Index: Integer): TJvTimerEvent;
begin
  Result := TJvTimerEvent(inherited Items[Index]);
end;

function TJvTimerEvents.ItemByHandle(AHandle: THandle): TJvTimerEvent;
var
  I: Integer;
begin
  I := ItemIndexByHandle(AHandle);
  if I >= 0 then
    Result := Items[I]
  else
    Result := nil;
end;

function TJvTimerEvents.ItemIndexByHandle(AHandle: THandle): Integer;
begin
  for Result := 0 to Count - 1 do
    if Items[Result].Handle = AHandle then
      Exit;
  Result := -1;
end;

function TJvTimerEvents.NextHandle: THandle;
begin
  Inc(FSequence);
  Result := FSequence;
end;

procedure TJvTimerEvents.Notify(Item: TCollectionItem;
  Action: TCollectionNotification);
begin 
  inherited Notify(Item, Action); 
  if Action = cnAdded then
    with TJvTimerEvent(Item) do
    begin
      FParentList := FParent;
      FHandle := NextHandle;
      FParentList := Self.FParent;
      CalculateInterval(GetTickCount);
      if FParent.Sorted then
        Sort;
      FParent.UpdateTimer;
    end;
end;

function TJvTimerEvents.ProcessEvents: Boolean;
var
  I: Integer;
  Item: TJvTimerEvent;
  StartTicks: Longint;
begin
  Result := False;
  if not (csDesigning in (Owner as TJvTimerList).ComponentState) then
  begin
    StartTicks := GetTickCount;
    for I := Count - 1 downto 0 do
    begin
      Item := Items[I];
      if (Item <> nil) and Item.Enabled then
        with Item do
          if (StartTicks - FLastExecute) >= (Interval - (MinInterval div 2)) then
          begin
            FLastExecute := StartTicks;
            Inc(FExecCount);
            Enabled := not ((not Cycled) and (FExecCount >= RepeatCount));
            if not Enabled then
              Result := True;
            FParent.DoTimer(Item);
          end;
    end;
  end;
end;

procedure TJvTimerEvents.SetItem(Index: Integer; const Value: TJvTimerEvent);
begin
  inherited Items[Index] := Value;
end;

procedure TJvTimerEvents.Sort;
var
  I: Integer;
  ExitLoop: Boolean;
begin
  if not (csDesigning in (Owner as TJvTimerList).ComponentState) then
    repeat
      ExitLoop := True;
      for I := 0 to Count - 2 do
      begin
        if Items[I].Interval > Items[I + 1].Interval then
        begin
          Items[I].Index := I + 1;
//          Items[I+1].Index := I;
          ExitLoop := False;
        end;
      end;
    until ExitLoop;
end;

procedure TJvTimerEvents.UpdateEvents(StartTicks: Integer);
var
  I: Integer;
begin
  for I := 0 to Count - 1 do
    if Items[I].Enabled then
      Items[I].FLastExecute := StartTicks;
end;

function TJvTimerEvent.GetDisplayName: String;
begin
  Result := Name;
  if Result = '' then
    Result := inherited GetDisplayName;
end;

function TJvTimerEvents.IndexOfName(const AName: string): Integer;
begin
  for Result := 0 to Count - 1 do
    if AnsiSameText(AName, Items[Result].Name) then
      Exit;
  Result := -1;
end;

function TJvTimerEvents.ItemByName(const AName: string): TJvTimerEvent;
var
  I: Integer;
begin
  I := IndexOfName(AName);
  if I >= 0 then
    Result := Items[I]
  else
    Result := nil;
end;

procedure TJvTimerList.SetSorted(const Value: Boolean);
begin
  if FSorted <> Value then
  begin
    FSorted := Value;
    if FSorted then Events.Sort;
  end;
end;

{$IFDEF UNITVERSIONING}
const
  UnitVersioning: TUnitVersionInfo = (
    RCSfile: '$RCSfile: JvQTimerList.pas,v $';
    Revision: '$Revision: 1.19 $';
    Date: '$Date: 2004/11/06 22:08:20 $';
    LogPath: 'JVCL\run'
  );

initialization
  RegisterUnitVersion(HInstance, UnitVersioning);

finalization
  UnregisterUnitVersion(HInstance);
{$ENDIF UNITVERSIONING}

end.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -