Delphi - 应用程序主表单被错误地聚焦

时间:2017-11-09 11:09:21

标签: windows forms delphi printing fastreport

在我的应用程序的两个部分中,主要表单集中在错误的时刻:

错误1.点击'确定'从特定的打印机表格。

  1. 我打开FastReports PDF预览 - 这是第一个弹出窗口。弹出窗口没有单独显示在任务栏中。这种形式是模态的。
  2. 然后我点击打印,
  3. 打开另一个带有标准打印选项的窗口。
  4. 然后我点击属性 - 打开驱动程序的特定形式。我改变了双面打印设置。
  5. 当我点击“确定”时,应该关注预览表单(1),但将主表单放在前面。由于预览表单仍然是模态的,因此很难返回预览表单。只有随机点击,预览表格才会再次聚焦。
  6. clicking through

    错误2.单击或拖动此特定滚动条会聚焦主窗体

    1. 此窗口处于活动状态。这是Windows任务栏中的一个独立窗口,不是模态的。这张表格上有一个gnostice pdf查看器。
    2. 当我点击scrollbox开始拖动时,主窗体会显示在前面。当我继续拖动时,pdf表单的滚动仍在继续。此外,鼠标附近的工具提示指示当前显示的页面。
    3. Bug 2

      我想解决这个奇怪的行为。所以,我的问题是:

        

      导致这些聚焦错误的原因是什么?

      关于申请:

      • 我已经注意到:弹出窗体看起来有点太大了,你可以在这里看到: form seems to large
      • 参见编辑
      • 有些表格是MDI孩子。
      • 我在代码中搜索了所有鼠标事件并将断点放在那里。但是这个代码在两个错误的时刻没有被执行。
      • VCLskin已被使用。
      • 快速报告版本5.6.1和5.6.8发生了
      • 错误1
      • Windows 10。
      • Delphi XE 10.2。

      修改

      • 正确设置了应用程序主窗体。在启动时,首先显示登录表单。登录后,将创建数据模块,创建一些没有所有者的表单(它们在应用程序端释放)。

      所有其他表单,也是主要表单是由应用程序拥有而不是登录表单。确实不是作为父母,而是作为所有者,像@ uwe-raabe所说的那样。

      然后创建主窗体。这是通过登录表单创建的:

      Frm_DatabaseLogin.CreateForm(TFrm_MainMenu, Frm_MainMenu);
      

      那叫:

      procedure TFrm_DataBaseLogin.CreateForm(InstanceClass: TComponentClass;
        var Reference);
      begin
        Updateprogress(InstanceClass.ClassName);
        Application.CreateForm(InstanceClass,Reference);
      end;
      

      在UpdateProgress中没有什么特别的事情发生。

      之后,其他表单也会被创建,由应用程序拥有。最后,登录表单隐藏,因此显示主窗体。

1 个答案:

答案 0 :(得分:0)

我在你的启动代码上做了一些假设。

"主要表格"可能是一个令人困惑的术语。从TApplication的角度来看,Application.MainForm始终是使用Application.CreateForm创建的第一个表单。

由于您的登录表单会创建您的应用程序的主要表单然后隐藏自己,因此登录表单仍然是" main"形成。

您的屏幕截图在任务栏上显示了两个图标。我假设您正在调整CreateParams或调用SetWindowLong来实现这一点。

我有一个与#34; main"相似的设置。登录表单然后隐藏。

在我的应用程序中,我为应该是独立的表单重写CreateParams并具有任务栏图标:

procedure TMgrMain.CreateParams(var Params: TCreateParams);
begin
  inherited CreateParams(Params);
  Params.ExStyle := Params.ExStyle or WS_EX_APPWINDOW;
  Params.WndParent := 0;
end;

然后在显示弹出窗口时,我使用所有者(可能不需要)创建表单,然后设置PopupMode和PopupParent。自从我开始这个以来,我不再拥有流行的形式。

procedure ShowAbout(Owner: TForm);
var
  LocalForm: TAbout;
begin
  LocalForm := TAbout.Create(Owner);
  try
    LocalForm.PopupMode := pmExplicit;
    LocalForm.PopupParent := Owner;
    LocalForm.ShowModal;
  finally
    FreeAndNil(LocalForm);
  end;
end;

来自PopupParent help

  

如果PopupMode属性设置为pmExplicit且PopupParent为nil,   然后将Application.MainForm隐式用作PopupParent。   如果没有分配Application.MainForm,则Application.Handle为   用作PopupParent。

     

如果PopupMode属性设置为pmAuto,则使用Screen.ActiveForm   作为PopupParent属性。

我采取步骤的部分原因来自于newsgroup post以下的老彼得。这也是现在的老建议,并且在添加PopupParent / PopupMode

之前
  

新闻组:borland.public.delphi.winapi
    来自:" Peter Below(TeamB)" < 100113.1 ... @ compuXXserve.com>
    日期:2000/11/30
    主题:回复:无模式窗口就像.exe

     

..剪切..
  请注意,这可能会导致   从次要形式显示的模态形式的一些问题。如果是用户   在模态表单启动然后返回时,远离应用程序   表明模态形式的形式可能隐藏在形式下面。它   可以通过确保模态形式来处理这个问题   显示它的表格的父级(使用params.WndParent如上)   但是使用Dialogs的标准对话框是不可能的   单位和例外,需要更多努力才能使它们正常工作   (基本上处理Application.OnActivate,寻找模态形式   通过GetLastActivepopup将应用程序作为应用程序的主要内容并将其引入   通过SetWindowPos的Z顺序的顶部。)     ..剪切..

最后这里有一个blog post,讨论为什么对PopupMode和PopupParent进行了更改。