移动光标慢慢地Delphi



美好的一天...我正在使用鼠标移动光标:

SetCursorPos (Source2 [1], source3 [1]); 

但是我需要慢慢移动...好像一个人正在将鼠标移动起来...因为我这样做的方式从一个点到另一个点到另一个点:

0: SetCursorPos (Source2 [1], source3 [1]); 
  1: SetCursorPos (Source2 [2], source3 [2]); 
  2: SetCursorPos (Source2 [3], source3 [3]); 
  3: SetCursorPos (Source2 [4], source3 [4]); 
  4: SetCursorPos (Source2 [5], source3 [5]); 
  5: SetCursorPos (Source2 [6], source3 [6]); 
  6: SetCursorPos (Source2 [7], source3 [7]); 
  7: SetCursorPos (Source2 [8], source3 [8]); 
  8: SetCursorPos (Source2 [9], source3 [9]); 
  9: SetCursorPos (Source2 [10], source3 [10]); 
  10: SetCursorPos (Source2 [11], source3 [11]); 
  11: SetCursorPos (Source2 [12], source3 [12]); 
  12: SetCursorPos (Source2 [13], source3 [13]); 
  13: SetCursorPos (Source2 [14], source3 [14]); 
  14: SetCursorPos (Source2 [15], source3 [15]); 
  15: SetCursorPos (Source2 [16], source3 [16]); 
  16: SetCursorPos (Source2 [17], source3 [17]); 
  17: SetCursorPos (Source2 [18], source3 [18]); 
  18: SetCursorPos (Source2 [19], source3 [19]); 
  19: SetCursorPos (Source2 [20], source3 [20]); 

您可以移动鼠标光标,好像它具有效果...一个从一个点慢慢移到另一点?

使用匿名线程。

这至少会避免使用Sleep()调用。

Uses
  SyncObjs;
procedure MoveSlow( const X,Y : TArray<Integer>);
var
  anonT : TThread;
  XX,YY : TArray<Integer>;
begin
  // Only local variables are captured
  XX := x;  
  YY := y;
  anonT := TThread.CreateAnonymousThread(
    procedure
    var
      w : TSimpleEvent;
      i : Integer;
    begin
      w := TSimpleEvent.Create(Nil,False,False,'');
      Try
        for i := Low(XX) to High(XX) do begin
          TThread.Synchronize(nil,
            procedure
            begin
              SetCursorPos(XX[i],YY[i]);
            end
          );
          w.WaitFor(10);
        end;
      Finally
        w.Free;
      end;
    end
  );
  anonT.Start;  // anonT will self terminate by default
end;
procedure TForm1.Button1Click(Sender: TObject);
var
  x,y : TArray<Integer>;
  i: Integer;
begin
  SetLength(x,100);
  SetLength(y,100);
  for i := Low(x) to High(x) do
    x[i] := Self.Left + i*(Self.Width div 100);
  for i := Low(y) to High(y) do
    y[i] := Self.Top + i*(Self.Height div 100);
  MoveSlow(x,y);
end;

光标的缓慢移动将由匿名线程处理,每10毫秒每10 ms都会向GUI发送同步的SetCursorPos()


事实证明,我根据计时器Tricky thing about pointers to animate something in Delphi编写了一个动画类。 NOTE 对于TTimer,最小的延迟约为10 ms。

uses AnimatePlatform;
var
  AnimateCursor: TAnimate; // Create and destroy outside scope of Button2Click
procedure TForm1.Button2Click(Sender: TObject);
var
  x,y : TArray<Integer>;
  i: Integer;
Const
  Points = 500;
begin
  SetLength(x,Points);
  SetLength(y,Points);
  for i := Low(x) to High(x) do
    x[i] := Self.Left + i*Self.Width div Points;
  for i := Low(y) to High(y) do
    y[i] := Self.Top + i*Self.Height div Points;
  AnimateCursor.Run(
    procedure(ix: Integer)
    begin
      SetCursorPos(x[ix],y[ix]);
    end,
    Low(x),High(x),10  // 10 ms is the smallest interval for a TTimer
  );
end;

使用匿名线程使用相同的方法(加上动画准备时的可选事件):

procedure AnimatedThread( aProc: TProc<Integer>;
                          FromValue, ToValue, AnimationDelay: Integer;
                          AReadyEvent : TNotifyEvent);
begin
  TThread.CreateAnonymousThread(
    procedure
    var
      i: Integer;
      w : TSimpleEvent;
    begin
      w := TSimpleEvent.Create(Nil,False,False,'');
      try
        for i := FromValue to ToValue do begin
          TThread.Synchronize(nil,
            procedure
            begin
              aProc(i);
            end
          );
          w.WaitFor(AnimationDelay);
        end;
      finally
        w.Free;
      end;
      if Assigned(AReadyEvent) then
        TThread.Synchronize(nil,
          procedure
          begin
            AReadyEvent(Nil);
          end
        );
    end
  ).Start;
end;
procedure TForm1.Button3Click(Sender: TObject);
var
  x,y : TArray<Integer>;
  i: Integer;
Const
  Points = 500;
begin
  SetLength(x,Points);
  SetLength(y,Points);
  for i := Low(x) to High(x) do
    x[i] := Self.Left + i*Self.Width div Points;
  for i := Low(y) to High(y) do
    y[i] := Self.Top + i*Self.Height div Points;
  AnimatedThread(
    procedure(ix: Integer)
    begin
      SetCursorPos(x[ix],y[ix]);
    end,
    Low(x),High(x),1,Nil // 1 ms delay
  );    
end;

NOTE ,基于线程的动画可以将动画延迟到1 ms。

最新更新