为什么在D2010中鼠标未移动时OnMouseMove会反复触发?

8
我正在将一个 Delphi 5 应用程序移植到 D2010,但遇到了一些问题。在一个表单上有一个 TImage 组件,它有一个 OnMouseMove 事件,当鼠标移动到图像上时应该更新标签。在原始应用程序中这个功能可以正常工作,但现在无论鼠标是否移动,只要在图像上方,OnMouseMove 事件就会不断触发,导致标签闪烁不停。
有没有人知道是什么原因导致的,以及如何解决?

4
这可能与 http://blogs.msdn.com/oldnewthing/archive/2003/10/01/55108.aspx 和 http://blogs.msdn.com/oldnewthing/archive/2009/06/17/9763416.aspx 有关。 - Joey
有趣的东西,但我没有运行任何“鼠标增强”程序。 - Mason Wheeler
@Mason,我在我的Vista机器上使用Delphi 2010(没有更新)执行了类似于Ken测试的操作,并且结果符合预期。换句话说 - 我无法重现您描述的行为。 - Wodzu
那么也许是我的鼠标驱动程序?真是太糟糕了... - Mason Wheeler
我已经见过这个确切的问题,并且正在关注此问题以查看您发现了什么。创建新的Delphi 2010应用程序,在Vista上创建Image,设置Picture属性(加载16x16 bmp),向Image1组件添加MouseMove事件处理程序,在事件处理程序中输出Debug字符串(IntToStr(FX));在类的private部分声明字段FX:Integer。运行应用程序,我会得到无尽的鼠标移动消息。 - Warren P
显示剩余3条评论
3个回答

6
我的心理调试感觉告诉我,您正在使用Windows系统,标签是一个工具提示窗口,并且您在每次鼠标移动时都在更新。
说真的,当我们切换到Vista时,我曾经看到过这种与工具提示窗口完全相同的情况。似乎更近期的Windows版本的工具提示窗口在更新时会生成WM_MOUSEMOVE消息。我找到的唯一解决方法是仅在文本实际更改时才更新标签。
因此,如果您不是在Windows上,请忽略我。但是如果您正在使用Windows系统,请尝试仅在文本实际更改时更新标签文本。

非常无聊的心理调试,因为Delphi 2010仅支持Win32。 :-) - Ken White
应该包括:TLabel 是一个标准的 Windows 标签控件,而不是一个工具提示窗口。 <g> - Ken White
啊,那就不行了。一定是其他问题。我应该删除这个评论吗? - John Knoeller
不要删掉它。对于其他遇到同样问题的人可能会有用。我只是抓住了机会而已。:-) 你会注意到我确保包含了笑容。 - Ken White
2
@John: 谢谢您没有删除它。我谷歌搜索了“Windows 7 鼠标重复移动”并找到了这个结果。我正在使用 .net 进行编程,最近在 Windows 7 下遇到了这个问题,解决方法是仅在文本更改时刷新工具提示。 - Mathieu Pagé

5

由于我无法添加评论,因此我使用答案部分来确认这种行为变化。 我有一个在Delphi 2007中开发的项目,在该项目中,只有当鼠标位置发生更改时才会调用OnMouseMove事件。 但是我发现在XE中,OnMouseMove对于相同的代码不断被调用。 我不知道为什么,因为它们都是由WM_MOUSEMOVE触发的。

在我找到原因之前,我正在比较以前的XY坐标,并在没有更改时退出:

if ( x = ZoomRect.Right ) and ( y = ZoomRect.Bottom ) then exit ;

区别在于XE中VCL创建了许多类,如TScrollbarStyleHook与WMMouseMove方法,我认为它们存在是为了支持2010年新增的Touch和Gestures。我不确定该怎么办。 - Mitch

1

Mason,我无法在 Windows XP SP2 上的新 D2010(更新4和5)VCL表单应用程序中重现这个问题。 我所做的如下:

  • 文件| 新建| VCL表单应用程序
  • 在表单上放置了一个TImage和TLabel
  • 从默认图像文件夹中选择了一个随机图像(GreenBar.bmp)作为TImage.Picture
  • 在对象检查器中双击TImage.OnMouseMove事件,并添加以下代码:
    procedure TForm1.Image1MouseMove(Sender: TObject; Shift: TShiftState; X,
      Y: Integer);
    begin
      Label1.Caption := Format('X: %d Y: %d', [X, Y]);
    end;
  • 运行应用程序(F9)。

标签一开始显示“Label1”(当然是默认标题)。 直到我第一次将鼠标移动到图像上,它才正确更新以显示X和Y坐标。 一旦我将鼠标指针移出图像,标签就停止更新。

这似乎是你特定代码或使用的Windows版本中的某些内容,而不是Delphi 2010本身的问题。


这是在Vista中,如果有帮助的话。 - Mason Wheeler
@Ken 我认为在Mason的例子中,即使他没有移动鼠标,鼠标位置也会更新。因此,您应该通过例如每次事件被触发时递增某些变量来进行测试,因为在快速图形卡上,闪烁可能对于相同的标题值不可见。 - Wodzu
@Ken 是的,但是如果鼠标没有移动,事件仍然被触发怎么办?在快速的机器上,您可能注意不到标签的刷新,而标题将保持不变。 - Wodzu
这种情况在这里发生,而且非常容易复现,在我创建的一个非常简单的演示应用程序中只用了大约10秒钟。如果有人需要,我会上传这个演示。 - Warren P
Warren,你能发布一下你使用的代码以及产生问题的确切步骤吗? - Ken White
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接