美好的一天......我正在用鼠标移动光标:
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]);
你可以移动鼠标光标,好像它有效果......从一个点慢慢移动到另一个点?
答案 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毫秒。