Я использую Delphi 7 с рядом сторонних компонентов. Мое основное приложение-заглушка загружает несколько DLL, которые представляют собой различные модули, такие как кредиторы, должники, заказы на поставку и т. Д.FindComponent не находит компоненты, созданные в Runtime
У меня проблема с 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;
Процесс докладов является:
Пользователь нажимает на кнопку
кнопкиРадио создаются с помощью кнопки мыши
пользователь нажимает кнопку радио
Критерии отчета создается с помощью переключателя
Пользователь вводит данные или DblClicks для выбора данных из списка.
пользователь щелкает кнопку Preview для просмотра отчета - это где FindComponent терпит неудачу и возвращает NIL ..
Весь код работал раньше, когда я создал все критерии во время разработки, а затем добавил код выше.
Приведенный ниже код является частью того, что нужно добавить в запрос, чтобы получить данные для отчета:
if Length(TMyAdvEdit(FindComponent('edQuoteReference')).Text) > 0 then
qryTempTable.SQL.Add(' and q.UserReference = "' + TMyAdvEdit(FindComponent('edQuoteReference')).Text + '"');
Это первый раз FindComponent()
терпит неудачу и не идет дальше.
Я пробовал различные способы создания компонентов, но каждый из них приводит к нарушению доступа, потому что компонент равен нулю.
Я искал всюду и старался все, о чем я мог думать, для решения этой проблемы.
У меня есть совет. Вы наклеили здесь большое количество постороннего кода, и трудно увидеть дерево для деревьев. Было бы намного проще для всех, особенно для вас, если бы вы сократили код до минимальной формы. A [mcve]. –
(1) Для вашей выгоды, пожалуйста, прекратите использование ** с **. Вы знаете, сколько раз вы случайно ссылались на члена вашего вновь созданного «TMyAdvEdit», не понимая этого? *** *** нет *** непреложной причины использовать ** с **; как минимум, вы всегда можете объявить локальную переменную, такую как «NewAdvEdit» (2), я также не буду беспокоиться о «NewAdv.Visible: = False;» и позже установить ее в «True». Если ваш компонент не делает что-то неясное, вы не должны обрабатывать сообщение краски между этими двумя строками. –