美好的一天...我正在使用鼠标移动光标:
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。