表单在屏幕上可见时触发的事件

3
我有一个表单需要一些时间来创建,我想向用户展示正在发生的事情,并在调用显示表单的函数时使用沙漏光标。但我的问题是,我无法获得

Screen.Cursor := crDefault;

当表单实际显示在屏幕上时首先执行的操作。

我尝试了所有有点合理的事件,但没有成功。沙漏在表单可见之前就消失了。

下一步我可以尝试什么来使它工作。

如果需要更多信息,请告诉我,我会找到它。

我在调用创建表单的函数之前在主窗体中设置了沙漏,然后像下面一样显示我的表单。

procedure TfrmJsCv.FormShow(Sender: TObject);
begin
  fReportFile := Folders.DirDatabase + 'jobsearch_print.mdb';
  btnPrint.Visible := FileExists(fReportFile);
  try
    SetupMain;
    SetupCertificates;
    SetupContacts;
    SetupCourse;
    SetupJobs;
    SetupLanguage;
    SetupLanguageLevels;
    SetupItKnowledge;
    SetupKnowledgeLevels;
    SetupKnowledgeTypes;
    SetupOther;
    SetupReferences;
    SetupSchool;
    SetupYears;
  except
    on E: exception do
      Logfile.Error('F_JsCv.FormShow: ' + E.Message);
  end;
  PagCurriculumVitae.ActivePageIndex := 0;
end;

我尝试在OnActivate、OnCreate、OnShow、OnResize和OnPaint事件中放置Screen.Cursor := crDefault;,但是沙漏光标会在窗体准备好/在屏幕上可见之前被重置

所有Setupxxxxx过程都是为窗体准备数据的过程,这些数据相当复杂 - 它从12个不同的表中收集数据。


“展示给我们” - 这不会容易。但是已经尝试了OnActivate、OnCreate、OnShow、OnResize、OnPaint,但没有成功。 - undefined
1
是的,这很简单。在你的集成开发环境(IDE)中选择代码,复制它,粘贴到问题中,然后点击保存编辑即可。 - undefined
2
为什么不在开始长时间操作时设置沙漏,然后在操作完成后恢复原样呢? - undefined
你的异常处理程序也是一团糟。 - undefined
如果一个任务需要超过10毫秒才能完成,将该任务在一个线程中执行。 - undefined
显示剩余10条评论
1个回答

9
你是否以模态的形式显示表单?如果是这种情况,crHourGlass 设置将被 ShowModal 调用取消,并且会调用 Screen.Cursor:=crDefault;。请参考 Vcl.Forms 单元下的 function TCustomForm.ShowModal: Integer; 的 7139 行 (XE7 源代码)。
解决办法是在所有 SetupXXX 调用和 TfrmJsCv.FormShow() 前调用 Screen.Cursor := crHourGlass;,并在之后调用 Screen.Cursor := crDefault;
既然 OP 确认表单是以模态的形式显示的,我认为对未来的读者来说可能需要更多的解释。
OP 说:

"在表单可见之前就消失了沙漏"
  "我在调用创建表单的函数之前在主窗体中设置了沙漏..."

因此,他的主窗体类似于以下形式:
  Screen.Cursor := crHourGlass;
  frmJsCv.ShowModal

最终进入 Vcl.Forms.TCustomForm.ShowModal

...
SaveCursor := Screen.Cursor;
Screen.Cursor := crDefault;
SaveCount := Screen.CursorCount;
...
try
  Show;  // 
  try
    // message loop
  finally
    Hide;
  end;
finally
  if Screen.CursorCount = SaveCount then
    Screen.Cursor := SaveCursor
  else Screen.Cursor := crDefault;
  ...
end;

显然,目的是让模态对话框根据需要操作光标,然后将光标恢复到调用ShowModal之前的状态。至少从Delphi 7开始,情况一直如此。

请注意,普通的Show不会进行上述练习。

在调用ShowModal之前设置crHourGlass,并且在之后不设置crDefault,另一个影响将是当显示表单时光标仍不会显示为沙漏状态,但在立即退出后会显示为沙漏状态。这可能与本说明一样令人困惑 :)


我们正在讨论应用程序的主窗体。据我所知,在问题的背景下,该窗体没有ShowModal方法。 - undefined
@先生,我们正在讨论他从主窗体中打开的一个次要窗体。确实,他没有提到模态对话框,所以我才问的。虽然没有明确说明,但这解释了症状,所以我相当有信心(除非另有说明)。 - undefined
1
表单以模态方式显示,正如您所猜测的那样 - 这就是问题所在。我将调用hourglass移动到OnShow中,现在它正确显示。谢谢。 - undefined
@OZ8HP 欢迎您。既然您确认了我的怀疑,我现在会添加一些解释。 - undefined

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