在 Delphi 7 中的 OnMouseMove 事件中移动组件时如何减少 CPU 使用率?
-
22-08-2019 - |
题
在 Delphi 7 应用程序中,我想跟随鼠标移动组件。我正在做这样的事情:
procedure MyComponent.MouseMove(Sender: TObject;Shift: TShiftState; X, Y: Integer);
begin
AnotherComponent.Top := X;
AnotherComponent.Left := Y;
end;
当我移动鼠标时,在最近的 PC 上,主核心的 CPU 使用率会达到 100%。
在这种情况下有什么想法或标记可以减少 CPU 使用率吗?
解决方案 3
最后,我已经改变我的代码为这一个:
procedure MyComponent.MouseMove(Sender: TObject;Shift: TShiftState; X, Y: Integer);
begin
if GetTickCount-LastMoveTick>50 then begin
AnotherComponent.Top := Y;
AnotherComponent.Left := X;
LastMoveTick := GetTickCount;
end;
end;
真的容易实现(2行加),没有计时器,可以很好地用于我...
其他提示
您可以创建一个TTimer该轮询当前鼠标位置每隔0.10秒左右,那么位置“AnotherComponent”根据当前鼠标位置。
然后你就不会解雇你的事件老鼠的每一个像素的运动 - 您将不再需要你的控制组件都任何的OnMouseMove事件。
在我的电脑上,这基本上不影响性能的。
procedure TForm1.Timer1Timer(Sender: TObject);
var
pt: TPoint;
begin
//Is the cursor inside the controlling component? if so, position some
//other control based on that mouse position.
GetCursorPos(pt);
if MouseWithin(pt.x,pt.y,MyComponent,Form1.Left,Form1.Top) then begin
//replace with whatever real positioning logic you want
AnotherComponent.Top := pt.y;
AnotherComponent.Left := pt.x;
end;
end;
function TForm1.MouseWithin(mouseX, mouseY: integer;
const comp: TWinControl; const ParentWindowLeft: integer;
const ParentWindowTop: integer): boolean;
var
absoluteCtrlX, absoluteCtrlY: integer;
begin
//take a control, and the current mouse position.
//tell me whether the cursor is inside the control.
//i could infer the parent window left & top by using ParentwindowHandle
//but I'll just ask the caller to pass them in, instead.
//get the absolute X & Y positions of the control on the screen
//needed for easy comparison to mouse position, which will be absolute
absoluteCtrlX := comp.Left + ParentWindowLeft;
absoluteCtrlY := comp.Top + ParentWindowTop +
GetSystemMetrics(SM_CYCAPTION);
Result := (mouseX >= absoluteCtrlX)
and (mouseX < absoluteCtrlX + comp.Width)
and (mouseY >= absoluteCtrlY)
and (mouseY <= absoluteCtrlY + comp.Height);
end;
- 它与鼠标移动本身无关。
- 除非这是您想要的,否则您将 X、Y 与顶部、左侧不匹配。顶部是 Y 坐标,左侧是 X 坐标。
- 问题是 AnotherComponent 的实际移动。
为了尝试并理解它,我建议您编写一个 TestMove 例程,以可调整的重复/延迟自动移动 AnotherComponent 来监视 CPU。
我敢打赌它会触发代价高昂的重绘或其他一些 CPU 密集型计算。
因此,首先仔细检查该组件上是否有任何事件处理程序,然后继续继承的行为......
也许,而不是移动的组件本身您移动一个“影子”,只有当用户让mousebutton去移动的组件。有点像拖放。
这不可能是一个需要如此多的CPU功率的举动本身,最有可能的举动将导致组件以某种方式重绘自身。
你能避免AnotherComponent
重绘每个举动?它不应该是必要的,除非它是一个电影的容器中。
绑在鼠标移动事件任何将小鼠是高分辨率输入装置被非常频繁地调用。因为你只处理得到基于系统的繁忙程度解雇尽可能快,我就不会担心CPU使用率虽然。换言之,这只是麻杏的CPU,因为没有别的。
从MSDN:
鼠标产生的输入事件 当用户移动鼠标时,或 按下或释放鼠标按钮。 该系统转换鼠标输入事件 成消息,并将它们发布到 适当的线程的消息队列。 当鼠标消息张贴快 不是一个线程可以处理它们时, 系统丢弃所有,但最 最近鼠标消息。
现在可能有一些例外。你可以做一些测试,以确保通过运行一些其他的处理密集的活动,看看有多少鼠标移动的东西影响它。