【问题标题】:Delphi 6 cursor not changingDelphi 6光标没有改变
【发布时间】:2013-05-14 18:42:59
【问题描述】:

如果我有一个设置 Cursor := crHourglass, Application.ProcessMessages 的 ButtonClick 事件,然后使用 TOpenDialog 选择一个文件,然后执行一些 CPU 密集型操作,则光标的行为会有所不同,具体取决于它是否位于现有控件之上当打开对话框关闭时。如果光标在控件上方,则光标保持为沙漏;如果它完全在应用程序之外,然后在密集过程仍在进行时移入该区域,则光标将保持为箭头。一个人不能点击或做任何事情,所以让用户感到困惑的是得到一个箭头但不能用它做任何事情。

单步调试调试器显示光标在它应该在的任何地方都是-11。使用 Screen.Cursor 代替 Cursor 具有相同的效果。

有解决办法吗?

procedure TMyForm.LoadButtonClick(Sender: TObject);
begin
  Cursor := crHourglass;
  Application.ProcessMessages;
  if OpenDialog.Execute then begin
    // Do something intensive
    // Cursor = crHourglass here but what is displayed is different
  end;
  Cursor := crDefault;
end;

【问题讨论】:

  • 看在上帝的份上,当你的代码不能完全按照你的意愿运行时,你们什么时候停止调用 ProcessMessages!!!
  • 如果我遗漏了什么,请见谅,但是设置光标而不调用 ProcessMessages 会导致光标直到 密集工作之后才真正改变已经结束了。
  • 您似乎只是解决了一个问题。但是现在你遇到了另一个问题。如果在第一个事件处理程序运行之前单击按钮两次会发生什么?无论如何,你说的不是真的。在事件处理程序中,分配给Cursor 并调用Sleep,看看会发生什么。
  • 只发布相关代码的危险!可以禁用所有控件,但仍然无法解决问题。我唯一的猜测是当鼠标移入窗口时会触发一些事件,但当然它没有被处理,因为它忙于做其他事情大约一秒钟。这表明 Rob 将其传递给单独线程的想法将是解决方案。
  • 好吧,您似乎没有发布相关代码,因为我无法重现您所描述的内容。 Rob 在所有分数上都是正确的。不要打电话给ProcessMessages。显示文件对话框时不要更改光标。并且不要在 UI 线程上运行长时间的任务。

标签: windows delphi delphi-6


【解决方案1】:

首先,确保仅在 CPU 密集型操作处于活动状态时设置光标。选择文件时不要改变光标——毕竟你永远不会看到任何其他程序这样做。

其次,当您在代码中说Cursor 时,您指的是 form's 属性。您可能希望改用Screen.Cursor,以便整个程序显示相同的光标。

第三,无需拨打Application.ProcessMessages。无论如何,只要您显示一个对话框,消息就会被处理,此外,您不需要处理任何特定的消息。

最后,考虑使用 try-finally 块来保护游标更改,以便处理中的问题不会使游标处于错误状态:

if OpenDialog.Execute then begin
  Screen.Cursor := crHourglass;
  try
    // TODO: something intensive
  finally
    Screen.Cursor := crDefault;
  end;
end;

如果该操作确实占用了大量时间,请考虑将其移至另一个线程。这样您就不必担心 GUI 没有响应,因此您一开始就不必更改光标。

【讨论】:

  • 我将代码精简到最低限度,即 KISS 原则,因此没有检查/异常处理。正如我所说,我确实尝试过 Screen.Cursor 没有任何区别。嗯,但是您对使用 OpenDialog 处理消息是正确的,但它仍然不能解决问题 - 当 OpenDialog 返回光标时,如果光标仍在调用窗口内,则光标是沙漏;如果在窗口外并移动到窗口区域,则为箭头。我还要求在 if 语句中设置光标,没有任何区别。
  • 您也将其剥离到删除 CPU 密集型代码的地步吗?测试一下。也许程序太忙而无法处理鼠标移动消息,因此太忙而无法更改光标。
  • 好吧,我认为 CPU 密集型位无关紧要。也许是的。如果我发布它,那该死的,因为除了这个单元中的部分,还有其他几个单元要拉进来,如果我不发布,那该死的!无论如何,正如我刚才在我的 OP 评论中所说的那样,“太忙而无法更改光标”[移入窗口时] 似乎确实是问题。
  • @RobKennedy 您需要处理鼠标移动消息。事件处理程序中的简单Cursor := crHourglass; Sleep(999999); 会导致光标发生变化。 something intensive 很可能只是将光标变回来!
猜你喜欢
  • 2017-12-02
  • 2023-01-16
  • 1970-01-01
  • 2022-01-10
  • 1970-01-01
  • 2017-12-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多