FindComponent找不到在运行时创建的组件

时间:2016-10-17 02:02:04

标签: delphi delphi-7

我使用Delphi 7和许多第三方组件。我的主存根应用程序加载了许多DLL,这些DLL是各种模块,如债权人,债务人,采购订单等。

FindComponent()存在问题。 99%的时间,它的工作方式应该如何。但不适用于下面的代码。

我正在尝试创建表单报告,在表格中保留报告选择条件的所有详细信息,然后即时创建条件。从理论上讲,它应该可以完美地工作,但由于某些原因,在创建组件后,FindComponent()无法找到它们。

try
  for i := gbSelectionCriteria.ComponentCount - 1 downto 0 do begin
    ShowMessage(gbSelectionCriteria.Components[i].Name);
    gbSelectionCriteria.Components[i].Free;
  end;

  // The above loop to remove the components from the groupbox works fine

  // Creating the components works

  fSysData.tbSelectionCriteria.First;
  while not fSysData.tbSelectionCriteria.EOF do begin
    case fSysData.tbSelectionCriteriaComponentType.AsInteger of
      1 : begin  // TMyAdvEdit
        with TMyAdvEdit.Create(gbSelectionCriteria) do begin
          Visible := False;
          Parent := gbSelectionCriteria;
          Name := fSysData.tbSelectionCriteriaName.AsString;
          Left := fSysData.tbSelectionCriteriaLeft.AsInteger;
          Top := fSysData.tbSelectionCriteriaTop.AsInteger;
          Width := fSysData.tbSelectionCriteriaWidth.AsInteger;
          LabelCaption := fSysData.tbSelectionCriteriaCaption.AsString;
          LabelPosition := AdvEdit.lpLeftCenter;
          LabelAlwaysEnabled := True;
          LabelTransparent := True;
          EditType :=  MyEditType[fSysData.tbSelectionCriteriaDataType.AsInteger];
          Text := '';

          OnClick := GetClickEvent(fSysData.tbSelectionCriteriaOnClickEvent.AsString);
          OnDblClick := GetClickEvent(fSysData.tbSelectionCriteriaOnDblClickEvent.AsString);
          OnKeyPress := GetKeyPressEvent(fSysData.tbSelectionCriteriaOnKeyPressEvent.AsString);

          Visible := True;

          // at this point findComponent finds nothing

          if FindComponent(Name) <> nil then
            ShowMessage(Name+' Created');
        end;

        edEdit.OnClick := GetClickEvent(fSysData.tbSelectionCriteriaOnClickEvent.AsString);
        edEdit.OnDblClick := GetClickEvent(fSysData.tbSelectionCriteriaOnDblClickEvent.AsString);
        edEdit.OnKeyPress := GetKeyPressEvent(fSysData.tbSelectionCriteriaOnKeyPressEvent.AsString);
        edEdit.Visible := True;

        if FindComponent(edEdit.Name) <> nil then
          ShowMessage(edEdit.Name+' Created');

      end;

      2 : begin
      end;

      3 : begin
      end;

      4 : begin
      end;

      5 : begin
      end;

      6 : begin
      end;

      7 : begin
      end;

      8 : begin
      end;
    end;

    fSysData.tbSelectionCriteria.Next;
  end;

  if fSysData.tbSysReports.Locate('ReportID', TAdvOfficeRadioButton(Sender).Tag, []) then begin
    ReportData.ReportID := TAdvOfficeRadioButton(Sender).Tag;
    ReportData.RepName := fSysData.tbSysReportsReportName.AsString;
    ReportData.RepTitle := fSysData.tbSysReportsReportTitle.AsString;
    ReportData.RepModule := fSysData.tbSysReportsModule.AsString;
    ReportData.RepOrientation := fSysData.tbSysReportsReportOrientaton.AsString;
    ReportData.RepPageIndex := fSysData.tbSysReportsCriteriaPageIndex.AsInteger;
  end;
finally
end;

报告的过程是:

  1. 用户点击按钮

  2. 单选按钮是通过按钮单击

  3. 创建的
  4. 用户点击单选按钮

  5. 通过单击单选按钮

  6. 创建报告条件
  7. 用户输入数据或DblClicks从列表中选择数据。

  8. 用户点击预览按钮查看报告 - 这是FindComponent失败并返回nil的地方..

  9. 在设计时创建所有条件之前,所有代码都有效,然后添加上面的代码。

    以下代码是需要添加到查询以检索报告数据的部分:

    if Length(TMyAdvEdit(FindComponent('edQuoteReference')).Text) > 0 then
      qryTempTable.SQL.Add('  and q.UserReference = "' + TMyAdvEdit(FindComponent('edQuoteReference')).Text + '"');
    

    这是FindComponent()第一次失败,不再继续。

    我已经尝试了各种方法来创建组件,但是每个方法都会导致访问冲突,因为组件是零。

    我到处寻找,并尝试了我能想到的一切,以解决这个问题。

2 个答案:

答案 0 :(得分:7)

FindComponent搜索方法调用主题所拥有的组件。您在表单上调用FindComponent,因此在表单拥有的组件中查找组件。但是您搜索的控件不归表单所有,它由gbSelectionCriteria拥有,这是您作为Owner参数传递给控件构造函数的内容。

如果您希望以您的方式使用FindComponent,则需要使表单成为您创建的控件的所有者。然后,当您在表单上调用FindComponent时,它可以找到控件,因为它是所有者。将Self传递给控件的构造函数以使其成为过去:

TMyAdvEdit.Create(Self)

我必须在这里做一些相当大的猜测。也许这段代码实际上存在于数据模块而不是表单中。但正如我所说,基本原则就是这样。

答案 1 :(得分:1)

首先,如果这是在错误的地方,我会道歉..

感谢您的回复和答案,我已经这么做了很多年了,我无法相信我错过了这么小的事情。

此,     如果FindComponent(Name)&lt;&gt;没有,

应该是这样的,     如果gbSelectionCriteria.FindComponent(Name)&lt;&gt;没有,

我通常不会使用,这只是测试创建组件的一种方法。 我将组件可见性设置为false,然后在创建后将其设置为true以在创建时停止闪烁。

再次感谢..