轻轻移动光标delphi

时间:2014-02-01 21:05:54

标签: delphi delphi-xe5

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

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]); 

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

1 个答案:

答案 0 :(得分:3)

使用匿名线程。

这至少可以避免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毫秒将向GUI发送一个同步的SetCursorPos()


原来我写了一个基于计时器Tricky thing about pointers to animate something in Delphi的动画类。 注意对于TTimer,最小延迟约为10毫秒。

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;

注意基于线程的动画可以将动画延迟降至1毫秒。