Ошибка a component named already exists

As far as my exploration along this line, yes the problem of «already exists» stems from having intances of the editor with the same value for the Name property. As another work around do not visually create the editor(s). Create a new component based on TForm/TFrame/TPanel for the editor(s) you want the user to be able to create multiple instances of. You will have to hand code the creation & deletion of any sub-controls, Setting their properties within your code and assigning values — anything from V_Btn = new TBitBtn(this), V_Btn->Color = clTeal, to V_Btn->OnClick = Close_The_Window. BUT NEVER assign a value to the Name property of any component in the new class and do not set the Name property of the editor once you have created an instance of the editor. Treat the Name property for editor as if it did not exist. After you have created the class and added it to your project the following is valid :

TMyeditor* Editor_01 = new TMyeditor(Main_Form);
TMyeditor* Editor_02 = new TMyeditor(Main_Form);
  Editor_01->Parent = Tab_Sheet_Addresses;
  Editor_02->Parent = Tab_Sheet_Billing;

The more complex the design concept for your editor the more effort you will undergoe to code the class. However this approach will resolve the «already exists» error.

            End of answer.

The following is tangental to the original question as it is an extension of what you may want to further do with your code & I write it to help you along should it be the case. The following allows you to efficiently store/retrieve the editor(s) and its published properties such as position on the user’s screen, themes, etc. If you’ve gone the above route, add the following :

void RegisterClassesWithStreamingSystem(void)
{   
  // Make sure that as part of the startup   
  // code TMyEditor is registered   
  // with the streaming system.   
  #pragma startup RegisterClassesWithStreamingSystem  
  Classes::RegisterClass(__classid(TMyEditor)); 
}

You can now ComponentToString <—> StringToComponent[*1] the editor(s).
You can now create a simple database of each editor saving it [*2] and re-creating the editor(s) at runtime. Saving & Recreating is almost entirely done by the TReader/TWriter objects.
{It is worth while to read about TReader/TWriter which is included in the Delphi help file}

[ Presupposing you have an instances of TMyEditor you want to save called Editor_01 & Editor_02 and
you’ve created the dataset and assigned it to a TClientDataSet named «CDS» ]

//How to write the Editors
String_Version_Of_Editor = ComponentToString(Editor_01);
CDS->Insert();
CDS->FieldByName("Data")->AsString = String_Version_Of_Editor;
CDS->Post();
String_Version_Of_Editor = ComponentToString(Editor_02);
CDS->Insert();
CDS->FieldByName("Data")->AsString = String_Version_Of_Editor;
CDS->Post();

//How to read, create an instance of, set the Owner of 
//(allowing for automatic destruction/deletion
// if desired, Vis-à-vis Let the compiler/runtime package handle that), 
//& setting the form's Parent
AnsiString   String_Version_Of_Editor; 
TWinControl* New_Editor;
String_Version_Of_Editor = CDS->FieldByName("Data")->AsString;
//The next line creates/constructs the new editor
New_Editor = StringToComponent(String_Version_Of_Editor);
//The next line sets the new editor's Owner to Main_Form 
//It also assigns Main_Form the responsibility of object cleanup
Main_Form->Insert(New_Editor);
//The next line sets the Editor's Parent causing it to be part of the 
//displayed user interface (it has been invisble since creation)
New_Editor->Parent = Tab_Sheet_Addresses;
//Move on to the next editor;
CDS->Next();
String_Version_Of_Editor = CDS->FieldByName("Data")->AsString;
New_Editor = StringToComponent(String_Version_Of_Editor);
Main_Form->Insert(New_Editor);
New_Editor->Parent = Tab_Sheet_Billing;

People who read the above who are astute will have noted that in the above code the New_Editor is of type TWincontrol not TMyEditor — though it likely should have been. However I did this to draw attention to the fact that problematically the TReader object in Delphi which is really doing the work of converting a string to a component object instance creates/constructs any object which has been registered with the streaming class via RegisterClass. In this manner explicit creation of the editor via explicitedly naming it’s type is avoided. If thought is given to the design of TMyEditor and its descendents the only change required to the code is to change TWinControl* to TMyEditor* — even that is not required if published properties beyond TWinControl* are not accessed outside the scope of TMyEditor — Example TMyEditor has access to the variables whose values it is editing and does not require this information to be supplied to the editor.(If working from a DataModule, #include the datamodule’s header into TMyEditor).

Side Note:
You may have a utility to know what class was read from the database so that you may place the instance where it belongs. To do this #include <typeinfo> into your code.
Example : If you have instances of TMyEditor, TMyEditor_Generation_01, TMyEditor_Generation_02, etc writen to the database the following will allow you to examine the instances read at runtime for placement into the user interface :

 if (typeid(New).name() == "TMyEditor *")
   New_Editor->Parent = Tab_Sheet_Addresses;
  else
   if (typeid(New).name() == "TMyEditor_Generation_01 *")
     New_Editor->Parent = Tab_Sheet_Billing;
   else
    if (typeid(New).name() == "TMyEditor_Generation_02 *")
      New_Editor->Parent = Tab_Sheet_Other_Editor;

typeid(__).name() will return a string which is the name of the class, in this case will also inculde » *».

The above allows ANY object(s) to be stored in the database and recreated. The entries within the database are not required to be related. The TReader object buried in Delphi’s code will decide at runtime what they are and use the correct constructor.

[*1] Note : The ComponentToString and StringToComponent are examples in the delpi/c++ help file.

[*2] Note : What is being saved are the published properties, therefore in your editor class any values you want stored and retrieved which are not already inherited and published should be declared in the __published section of your new class. Those items may also be custom objects, for those you will likely code custom specific methods/functions for the read/write access specifiers in defining the _property. I would suggest translating any complex object into a string value for ease of examining your code while under development.

Rasool

4 / 109 / 0

Регистрация: 02.04.2009

Сообщений: 390

1

27.10.2017, 15:24. Показов 13655. Ответов 7

Метки нет (Все метки)


Студворк — интернет-сервис помощи студентам

Моя программа работает с «железом», она управляет специальной измерительной системой, которая измеряет геометрические параметры деталей с помощью лазера по отдельным точкам. Измеренные значения точек сопоставляются с эталонными значениями, нанесенными на загруженную виртуальную эталонную 3d-модель детали, и делается вывод о годности детали или, соответственно, не годности. Есть два режима работы. При нажатии кнопки (событие TfrmBazir.actStartExecute) на главной формочке TfrmBazir появляется новая формочка с результатами измерений TfrmBladeMeasureResults:
1) без проведения непосредственного измерения детали, получаем только эталонные точки на 3d-модели детали;
2) с проведением измерений детали и получением реальных точек.
В моей программе имеет место следующая проблема. Генерируем формочку TfrmBladeMeasureResults без проведения измерений системой, потом закрываем ее, потом снова открываем — все проходим без проблем. Генерируем формочку TfrmBladeMeasureResults с проведением измерений системой, потом закрываем ее, потом снова открываем — форма не открывается, вместо этого выдается ошибка «A component named frmBladeMeasureResults already exists». В чем может быть дело?

Delphi
1
2
3
4
5
6
7
8
9
10
11
12
procedure TfrmBazir.actStartExecute(Sender: TObject);
var
    frmMSRResults: TfrmBladeMeasureResults;
begin
        // ...
        frmMSRResults := TfrmBladeMeasureResults.Create(self);
        frmMSRResults.lblPathToModel.Caption := ModelFileName;
        frmMSRResults.Show;
        frmMSRResults.WindowState := wsMaximized;
        frmMSRResults.NeedToAutoCloseAfterMeasure := False;
        // ...
end;



0



Programming

Эксперт

94731 / 64177 / 26122

Регистрация: 12.04.2006

Сообщений: 116,782

27.10.2017, 15:24

Ответы с готовыми решениями:

Программа для накрутки «мне нравиться» «подписчиков»»
Народ привет тут увидал прогу называеться FVCheat она накручивает ВК подписчиков сердечек (мне…

В каждом слове текста замените «а» на букву «е», если «а» стоит на четном месте, и заменить букву «б» на сочетание «ак»,
В каждом слове текста замените &quot;а&quot; на букву &quot;е&quot;, если &quot;а&quot; стоит на четном месте, и заменить букву…

Из слов «Работа», «крест», «тон» составить фразу «Кто не работает, тот не ест» и определить ее длину
Из слова &quot;Работа&quot;,&quot;крест&quot;,&quot;тон&quot; составить фразу:&quot;Кто не работает, тот не ест&quot; и определить ее длину.

На форме располагаются компоненты: редактор Edit; линейка ScrollBar; радионабор с опциями «Цветы», «Деревья», «Рыбы», «Звери»
Доброго времени суток, 2 курс 2 семестр, пришли, препод раздал задачи, сказал качайте дома и…

7

5158 / 4111 / 1031

Регистрация: 29.08.2013

Сообщений: 26,092

Записей в блоге: 3

27.10.2017, 16:06

2

ошибка у тебя есть, исходники тоже, отладчик в руки и вперед
по 10 строчкам кода сложно гадать почему у тебя ошибка вылезает



0



Rasool

4 / 109 / 0

Регистрация: 02.04.2009

Сообщений: 390

27.10.2017, 18:53

 [ТС]

3

Я погуглил сообщение об ошибке, нашел следующее:

TComponent.SetName вызывает TComponent.ValidateName, которая, в свою очередь, вызывает функцию FindComponent (поиск компонента по имени среди компонентов, для которых Self является владельцем (Owner)). И если компонент с таким же именем найден, то вызывается Exception с сообщением формата SDuplicateName. Теперь стоит посмотреть на свой код. Почему к моменту fmReserve:=TfmReserve.Create(self);
у self уже является владельцем компонента с таким же именем.

Значит, self надо поменять на что-то другое?

Добавлено через 12 минут

Цитата
Сообщение от qwertehok
Посмотреть сообщение

ошибка у тебя есть, исходники тоже, отладчик в руки и вперед
по 10 строчкам кода сложно гадать почему у тебя ошибка вылезает

Отладчик останавливается на строчке

Delphi
1
    frmMSRResults := TfrmBladeMeasureResults.Create(self);



0



qwertehok

27.10.2017, 18:58

Не по теме:

мой магический шар тоже на этих строчках останавливается



0



Rasool

4 / 109 / 0

Регистрация: 02.04.2009

Сообщений: 390

27.10.2017, 19:45

 [ТС]

5

Небольшое пояснение:

Delphi
1
2
3
    TfrmBladeMeasureResults = class(TfrmMeasureResults)
    TfrmMeasureResults = class(TForm)
    TfrmBazir = class(TForm)



0



5552 / 4335 / 1385

Регистрация: 14.04.2014

Сообщений: 19,408

Записей в блоге: 19

28.10.2017, 05:52

6

эта ошибка возникает когда на на форме УЖЕ ЕСТЬ КОМПОНЕНТ с таким же именем, или УЖЕ ЕСТЬ ФОРМА с таким же именем среди других форм (неожиданно, да?))))

99% за то что вы форму создаете (Create) показываете (Show) и закрываете (Close)
не хватает только места, где вы ее разрушаете (Free)
так что при создании новой копии вам говорят, что такой компонент уже существует

решения на выбор
1. в обработчике OnClose поставить Action := caFree
2. хранить ссылку на созданную форму и явно ее разрушать где-то например перед повторным созданием
FMyForm.Free
3. Вызывать форму модально
https://www.cyberforum.ru/blog… g4873.html



1



4 / 109 / 0

Регистрация: 02.04.2009

Сообщений: 390

28.10.2017, 09:24

 [ТС]

7

Цитата
Сообщение от krapotkin
Посмотреть сообщение

эта ошибка возникает когда на на форме УЖЕ ЕСТЬ КОМПОНЕНТ с таким же именем, или УЖЕ ЕСТЬ ФОРМА с таким же именем среди других форм (неожиданно, да?))))
99% за то что вы форму создаете (Create) показываете (Show) и закрываете (Close)
не хватает только места, где вы ее разрушаете (Free)
так что при создании новой копии вам говорят, что такой компонент уже существует
решения на выбор
1. в обработчике OnClose поставить Action := caFree
2. хранить ссылку на созданную форму и явно ее разрушать где-то например перед повторным созданием
FMyForm.Free
3. Вызывать форму модально
https://www.cyberforum.ru/blog… g4873.html

Большое спасибо, будем думать.



0



167 / 107 / 22

Регистрация: 02.01.2012

Сообщений: 596

28.10.2017, 09:42

8

Ещё можно решать проблему «в лоб» — каждый раз менять Name, например, добавлять порядковый номер



0



IT_Exp

Эксперт

87844 / 49110 / 22898

Регистрация: 17.06.2006

Сообщений: 92,604

28.10.2017, 09:42

Помогаю со студенческими работами здесь

Тысячные числа исправлять к примеру с «1200» на «1 200», «12000» на «12 000» и т.д
Собственно числа исправлять к примеру с &quot;1200&quot; на &quot;1 200&quot;, &quot;12000&quot; на &quot;12 000&quot;, &quot;120000&quot; на…

В слове Х перед каждой буквой «к», которой предшествует буква «с», вставить букву «н»
Привет всем) вот условие задачи:В слове Х перед каждой буквой &quot;к&quot;, которой предшествует буква &quot;с&quot;,…

Дана строка. Заменить все буквы «м» на «н». Заменить все вхождения сочетаний букв «про» на «нет»
2.Дана строка.
1) Заменить все буквы м на н.
2) Заменить все вхождения сочетаний букв &quot;про&quot; на…

Замените в слове Х все буквы «а» на сочетание «ку», а сочетание «ку» на букву «б»
Написать программу, заменяющую в слове Х все буквы &quot;а&quot; на сочетание &quot;ку&quot;, а сочетание &quot;ку&quot; на букву…

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:

8

 
Димон
 
(2005-03-01 12:02)
[0]

Есть примерно такой код, который выполняется в одном из методов другой формы:

kForm := TMyForm.Create(Application);
try
  Result := kForm.ShowModal = mrOk;
  if Result then
     kForm.SaveResults(ResultObject);
finally
  kForm.Release();
end;

После этого кода результаты диАлогового ввода пользователя, сохраненные командой SaveResults в ResultObject, неким образом обрабатываются.

Бывают случае когда обработка заканчивается с ошибкой. После этого в пириведенном выше коде возбуждается исключение указанное в сабже.

Вопрос: что приводит к такой ошибке?

Проде бы TComponent должен сам заботиться о выборе имени дабы избежать конфликта имен в рамках своего owner. С чем может быть связано отсутствие такого подбора в моем случае?


 
Shirson ©
 
(2005-03-01 12:07)
[1]

В каком месте кода идёт возбуждение и что за обработка идёт?


 
clickmaker ©
 
(2005-03-01 12:10)
[2]


> Проде бы TComponent должен сам заботиться о выборе имени
>

в ран-тайме не должен


 
Димон
 
(2005-03-01 12:12)
[3]


> В каком месте кода идёт возбуждение и что за обработка идёт?

Сразу после.

Но связь интересующей меня ошибки с ошибкой при обработке ResultObject это только мое предположение, т.к. ошибка происходит у заказчика. И заказчик не может описать что он делал до получения «a component named … already exists».

Я предполагаю, что форма как-то некорректно удаляется или еще что. Собственно я бы мог разобраться с формированием имени в модуле classes. Но я бы очень хотел прежде чем это делать (все-таки там немало кода) услышать мнения общественности. Может кто с этим сталкивался.


 
Юрий Зотов ©
 
(2005-03-01 12:13)
[4]

Нужно видеть:
— код SaveResults;
— ResultObject (хотя бы, как объявлен, где и как создается и уничтожается);
— код обработки.


 
Димон
 
(2005-03-01 12:15)
[5]


> в ран-тайме не должен

Раааазве. А ты попробуй :)))

showmessage(TForm2.create(application).name);
showmessage(TForm2.create(application).name);
showmessage(TForm2.create(application).name);
showmessage(TForm2.create(application).name);

Прекрасно отработает каждый раз генеря новое имя :)


 
Юрий Зотов ©
 
(2005-03-01 12:18)
[6]

> Вроде бы TComponent должен сам заботиться о выборе имени

Выбор уникального имени — задача дизайнера, а не компонента. Откройте DFM — там имена уже жестко проставлены. Они же жестко прописаны в коде, как ссылочные published-поля и по ним как раз и идет инициализация этих полей при чтении DFM (см. FieldAddress).


 
Димон
 
(2005-03-01 12:20)
[7]


>  [4] Юрий Зотов ©   (01.03.05 12:13)

Добрый день, Юрий.

1) Код обработки показать не могу. Это тысяч 15 строк. Фактически это построение поискового sql запроса к базе sql на основе развернутых метаданных и текущего состояния ResultObject.

2) Если ближе к телу, то код такой
CLASS FUNCTION TForm_MLDocumentFilter._Execute(
  const aFrameFilterClass: TFrame_MLChapterItemClass;
  const aFilter: IMLFilter;
  const aCls: TMLChapterItemClass): Boolean;
VAR
  kForm: TForm_MLDocumentFilter;
  kFilter: IMLFilter;
BEGIN
  // Создаем копию фильтра
  kFilter := aFilter.__Clone();
  // Создаем форму
  kForm := TForm_MLDocumentFilter.fCreate(aFrameFilterClass, kFilter, aCls);
  try
     // Выполняем форму в модальном режиме
     Result := kForm.ShowModal = mrOk;
     // Если пользователь нажал кнопку OK то копируем из временного объекта в постоянный
     if Result then aFilter.__Assign(kFilter); // Это SaveResults из примера
  finally
     kForm.Release();
  end;
END;

где fCreate это конструктор вызывающий inherited Create(application) + несколько простых действий.

3) Код saveResults — это просто копирование значений объекта.


 
Димон
 
(2005-03-01 12:22)
[8]


>  [6] Юрий Зотов ©   (01.03.05 12:18)

Тода как объяснить работоспособность моего кода из [5]?


 
Юрий Зотов ©
 
(2005-03-01 12:27)
[9]

> Димон   (01.03.05 12:20) [7]

Загадок стало еще больше. Надо сымитировать ошибку при обработке и ходить отладчиком.

Ясно одно — при ошибке не уничтожается какой-то контейнер (например, форма), а потом этот же контейнер загружается — отсюда и дубликат имен. Если ошибки нет, то контейнер уничтожается и при загрузке все проходит ОК.


 
Димон
 
(2005-03-01 12:30)
[10]


>  [9] Юрий Зотов ©   (01.03.05 12:27)


> Загадок стало еще больше

Да сам в загадках.


> Надо сымитировать ошибку при обработке и ходить отладчиком.

Не получается — она, зараза, неведенная. Т.е. некоторая последовательность играет роль.


> Ясно одно — при ошибке не уничтожается какой-то контейнер

Опять же повторю, что вроде бы в этом случае должно сгенериться новое уникальное имя. Мой пример из [5] показывает это.

Т.е. такое ощущение, что что-то уничтожилось но не до конца :))


 
Димон
 
(2005-03-01 12:39)
[11]

Еще подлость в том, что подебужить classes нормально не получается: все строки съехавшие, т.е. часто ходишь по пустым местам, тогда как у нормальных строк не стоит слева точечка :(((


 
MU
 
(2005-03-01 12:42)
[12]

Destroys the form and frees its associated memory.

procedure Release;

Description

Use Release to destroy the form and free its associated memory.

Release does not destroy the form until all event handlers of the form and event handlers of components on the form have finished executing. Release also guarantees that all messages in the form»s event queue are processed before the form is released. Any event handlers of the form should use Release instead of Free. Failing to do so could lead to an access violation.

Note: Release returns immediately to the caller. It does not wait for the form to be freed before returning.


 
Димон
 
(2005-03-01 12:44)
[13]

Понимаешь, в чем дело, как работает Release я в общем то знаю (код то доступен). Другой вопрос: ну и что? Ну допустим я пытаюсь второй раз открыть ту же форму. Ну и что? Пример из [5] показывает, что факт неудаленности предыдущей формы не должен оказыать никакого влияния — должно сгенериться новое уникальное имя.


 
Юрий Зотов ©
 
(2005-03-01 12:53)
[14]

> Димон   (01.03.05 12:22) [8]

> Тода как объяснить работоспособность моего кода из [5]?

Ответ лежит в модуле Classes:

function TReader.ReadRootComponent(Root: TComponent): TComponent;
 function FindUniqueName(const Name: string): string;

Вот эта самая FindUniqueName и формирует суффикс «_цифра». Но работает все это только для глобальных компонентов, а имена внутренних компонентов жестко прописаны в DFM и грузятся оттуда без всякой модификации (ведь иначе будет невозможно проинициализировать соответствующие поля контейнера).

В любом случае видим, что сам компонент о выборе своего имени не заботится. Он только проверяет его в SetName.


 
KSergey ©
 
(2005-03-01 12:54)
[15]

> [13] Димон   (01.03.05 12:44)
> должно сгенериться
> новое уникальное имя.

Вам тут уже сказали не раз: НЕ ДОЛЖНО!! Не должно — и все тут!
И никакой ваш пример тут не убедителен, я сам на это не раз натыкался (к стати, может форма и генерит новое имя верно, но в ней ли дело? Что у вас там создается — хрен знает. Может и не в ней дело.

Теперь еще. После вызова Release, как вы знаете, сразу объект не уничтожается. В этом может быть как раз и косяк.

Я взял за правило динамически создаваемым объектам давать имя — пустую строку. Тогда никто никогда не ругается.

Опять же в этом коде просто НЕТ СМЫСЛА в Release. Это излишняя нагрузка на систему, не более.


 
KSergey ©
 
(2005-03-01 12:56)
[16]

> [14] Юрий Зотов ©   (01.03.05 12:53)
> имена внутренних компонентов жестко прописаны в DFM

Блин, точно! Он же не просто объект создает, а форму… Туплю…

К стати, именно в Release тут может и быть косяк: если объект таки успеет разрушиться — то ошибки нет, если не успевает — ошибка. Выкинуть. Глупость это здесь полная.


 
clickmaker ©
 
(2005-03-01 13:00)
[17]


> Димон   (01.03.05 12:44) [13]

а тебе так принципиально это release? Делай просто Free


 
Юрий Зотов ©
 
(2005-03-01 13:03)
[18]

> Димон   (01.03.05 12:44) [13]

> Ну допустим я пытаюсь второй раз открыть ту же форму.
> Ну и что?

Не открыть, а загрузить. И при чтении из DFM первого же внутреннего компонента формы выясняется, что компонент с таким именем на этой форме уже есть. И приплыли.

Скорее всего, причина именно в этом.

> Пример из [5] показывает…

См. [14]. Для внутренних компонентов пример из [5] неприменим.


 
Димон
 
(2005-03-01 13:45)
[19]


>  [18] Юрий Зотов ©   (01.03.05 13:03)

Привет с внутренними компонентами неприминим — т.к. внутренние компоненты я не создаю. Это раз.


>  [16] KSergey ©   (01.03.05 12:56)

Мой пример очень даже убедителен. Для форм нет необъходимости задавать уникальные имена.

Мне не сложно — я очищаю имя. Это не проблема. Конечно же все работает.

Проблема в том, что я не понимаю такое поведение — если имя не уникально, то ошибки нет, но только в том случае, если раньше не было где-то как-то возникшего исключения. Знал бы где! Такое ощущение, что механизм выделения имен нарушается. Как? Фиг его знает. Потому и спрашиваю.


 
Димон
 
(2005-03-01 13:46)
[20]


> Привет

пример :)


 
KSergey ©
 
(2005-03-01 13:49)
[21]

> [19] Димон   (01.03.05 13:45)
> Потому и спрашиваю.

Внимательно вдумайтесь в термин ЮЗ «внутренние компоненты».
Признаюсь, я не сразу въехал, как только понял -все стало ясно.

PS
Если уж так нужна подсказка: в вашем примере [5] форма — явно пустая. А можеи и не в этом дело… (к ЮЗ: но ведь я могу создать 2 экземпляра одной и той же формы! Любой!)


 
Димон
 
(2005-03-01 13:56)
[22]


>  [21] KSergey ©   (01.03.05 13:49)

Не пустая :)))

Братья, вы в общем-то о чем-то не том говорите. Я так понимаю, что с такой ситуацией вы просто не сталкивались :)  

Здесь есть явное нарушение работы «выделятеля уникальных имен» по причине сложно наведенной ошибки.

Собственно вопрос о алгоритме выделения имен. Что там предположительно может сломаться. :))


 
Димон
 
(2005-03-01 14:02)
[23]

Собственно в алгоритме я со временем сам разберусь. Сейчас исправил пока очисткой имени. Но вопрос все-таки волнует, что может так сломаться, что форма не может снова быть создана. :)) И если кто-то с таким же сталкивался, то буду крайне рад получить данную информацию.


 
BlackTr
 
(2005-03-01 14:22)
[24]

У меня такая фигня была на 5 делфи, вылечилось установкой обновлений…
До конца так и не вьехал в чем причина была :)


 
Димон
 
(2005-03-01 14:24)
[25]

Во! ЗдрАвая информация. Есть у меня ощущение, что глюк :)


 
Юрий Зотов ©
 
(2005-03-01 16:09)
[26]

> Димон   (01.03.05 13:45) [19]

> Привет с внутренними компонентами неприминим — т.к. внутренние
> компоненты я не создаю.

Пишем: TForm2.Create(Application).Show — и видим форму со всеми ее компонентами. Мы их создавали? Нет, мы создавали только саму форму. Но они же есть — значит, кто-то их создал?

Так откуда же они взялись, как Вы считаете? И что в свете этого означает процитированная Ваша фраза, раз Вы сами говорите, что форма не пустая?


 
Димон
 
(2005-03-01 16:28)
[27]

Юрий, при всем моем уважении, ей богу вы придираетесь к словам :)

Я привел пример, что и как я создаю. Зависимые компоненты также создаются. Я лично непосредственно это не делаю.

Все мое утверждение было о том, что в любом случае при создании формы (даже той, которая разработана в design time) имя должно выставиться уникальным, что и демонстрирует пример из [5].

:))


 
Юрий Зотов ©
 
(2005-03-01 18:03)
[28]

> Димон   (01.03.05 16:28) [27]

> ей богу вы придираетесь к словам

Да мне-то что? Это не я придираюсь, а программа, которая не работает.

> Зависимые компоненты также создаются. Я лично непосредственно
> это не делаю.

А какая программе разница, чей код вызвал Create — Ваш или Борланловский?

> Все мое утверждение было о том, что в любом случае при
> создании формы (даже той, которая разработана в design time)
> имя должно выставиться уникальным, что и демонстрирует пример
> из [5].

Сорри, мне не хочется повторять в третий раз [14] и [18]. Очень советую внимательно посмотреть TReader.ReadRootComponent в Classes.


 
Димон
 
(2005-03-01 18:09)
[29]

Контрольный вопрос, или я что-то не понимаю?

Причем здесь внутренние компоненты? Ругается то на имя формы! Именно оно «already exists», а не имя внутренних компонентов.

Указанные методы я смотрел. Да, не очень детально. Но я как раз и не понимаю, какие могут быть причины, чтобы не делать суффикс «_xxx» к имени формы.

Собственно о том и спрашиваю. Может знаете :)


 
Димон
 
(2005-03-01 18:10)
[30]

Кстати да, я не сказал в вопросе, что ругается на имя формы, а не на имя внутреннего компонента. Прошу прощения, не подумал, что это важно.

:)


 
Димон
 
(2005-03-01 18:14)
[31]

Понимаете ли, если бы я смоделировал ситуацию ошибки (я говорил, что знаю ее только на словах), то мог бы понять, что нарушается в этом механизме. Если не с использование «use debug dcu», то хоть cpu бы просмотрел.

Но смотря на алгоритм наделения компонентов уникальными номерами я не могу понять, что в нем может пойти не так.

Собственно надежда на то, что кто-то с этим вопросом разбирался.

Всем спасибо.


 
Юрий Зотов ©
 
(2005-03-01 18:35)
[32]

> Димон   (01.03.05 18:10) [30]
> Кстати да, я не сказал в вопросе, что ругается на имя формы, а
> не на имя внутреннего компонента. Прошу прощения, не подумал,
> что это важно.

Дим, ну ни фига себе! Это же в корне переворачивает ситуацию. Выходит, мы 30 постов просто не понимали друг друга.

Начинаем сначала:
— приведите все же имя формы, на которое ругается;
— кто является ее Owner»ом — Application или кто-то еще?


 
Димон
 
(2005-03-01 18:40)
[33]


>  [32] Юрий Зотов ©   (01.03.05 18:35)

Повторно прошу прощения, Юрий.

1) Ругается на «TForm_MLDocumentFilter». Где ругается, не знаю. Т.к. посторю, что не могу смоделировать ошибку — все со слов нашей техподдержки, которые лично видели ошибку, но не знают предысторию ее возникновения.

2) Application


 
Набережных С. ©
 
(2005-03-01 18:47)
[34]


> kForm.Release();

Возможно, к моменту второй попытки выполнить этот код тот экземпляр , который был создан при первом обращении, еще не уничтожен. Ну а так как имя у всех TMyForm одно и то-же, загружаемое из ресурсов, то и получаем эту ошибку. Поставь точку останова в OnDestroy, если дело в этом, то сразу обнаружишь. А имена компонентов на форме уникальны только в пределах этой формы.


 
Димон
 
(2005-03-01 18:55)
[35]


>  [34] Набережных С. ©   (01.03.05 18:47)

не в этом дело:))) [5] показывает, что ты можешь создавать сколько угодно одинаковых форм. Об уникальности имен позаботится сам vcl.


 
Набережных С. ©
 
(2005-03-01 19:00)
[36]


> Димон   (01.03.05 18:55) [35]

Попробуй все-таки заменить Release на Free. Ну для моего спокойствия:) Тем более, что релиз здесь вроде как и ни к чему…


 
Димон
 
(2005-03-01 19:06)
[37]


>  [36] Набережных С. ©   (01.03.05 19:00)

да я уже заменил:)
Самая проблема теперь протестировать. Ошибку мне так и не удалось смоделировать. Когда-то давно, давно, только когда я написал этот блок я видел сам пару раз эту ошибку. Теперь никак — не могу смоделировать:((((((


 
Набережных С. ©
 
(2005-03-01 19:35)
[38]

Ну могу только сказать, что в такой конструкции(с Free) у меня никогда ни единой проблемы не было. Прошелся поиском, такая ошибка генерится только в методе TComponent.ValidateRename. Копай, где и как он вызывается — вставка, удаление, переименование.
I>
> Теперь никак — не могу смоделировать

А может, ее уже и нету?<


 
Anatoly Podgoretsky ©
 
(2005-03-01 19:48)
[39]

Набережных С. ©   (01.03.05 19:00) [36]
Попробуй все-таки заменить Release на Free.
Набережных С. ©   (01.03.05 19:00) [36]
Попробуй все-таки заменить Release на Free. Ну для моего спокойствия:) Тем более, что релиз здесь вроде как и ни к

Release должен применяться внутри объекта (класса), вот с ним были проблемы при применении извне.
А Free снаружи, проблем тоже ни когда не было.


 
Димон
 
(2005-03-01 20:11)
[40]


>  [38] Набережных С. ©   (01.03.05 19:35)

может и нету :))


>  [39] Anatoly Podgoretsky ©   (01.03.05 19:48)

Проблемы? Можно подробнее? :) Какие, например.


 
Anatoly Podgoretsky ©
 
(2005-03-01 20:24)
[41]

Зависание


This can happen when the named component is present in the PAS file, but not on the form, or vice-versa. In my experience, it comes up when you move a form from a particular version of Delphi in which the component was installed to one in which the component type is not installed. Most often, it is in the DFM file, which will not display the component because it can’t be found. Right-click on the form and edit as text, then search on the name.

Alternately, it could be absent from the form, but the declaration in the PAS file may still be present. If that is the case, remove the declaration and then place your new component.

As to the behavior described with CodeSite, I have no idea, as I have never experienced that. You could try a message to Ray Konopka, who is very helpful.

Solution 1

Giving MainForm as the Owner in TFrm1.Create will include the newly created form in the components list of MainForm. A component ensures that this list doesn’t contain any two components with the same non-empty name (otherwise FindComponent won’t work). This mechanism also works when a component changes its name.

As long as you don’t specify the name in TFrm1.Create it is most likely that it is set by the LoadFromFile method, which means that you don’t have much influence on the name unless you change the file’s content.

A valid workaround is to create the form with nil as Owner, load the form from the file, change the name to a unique value or to an empty string and finally call MainForm.InsertComponent.

procedure MyProcedure1;           
var MyFrm: TFrm1;
begin
  ... 
  MyFrm:= TFrm1.create(nil);
  MyFrm.BringToFront;
  MyFrm.LoadFromFile(someFile);
  MyFrm.Name := ''; // or some unique name
  MainForm.InsertComponent(MyFrm);
end;

Solution 2

The message is caused because each form must be uniquely named.

When you create a form twice, you need to ensure each instance has a unique name, or set the Name to an empty string. The latter also is the trick when using multiple instances of a data module, so that the automatic linking of data-aware controls does not end up always using the first instance.

Add

MyFrm.Name := MyFrm.Name + <something unique>;
MyFrm.Name := '';

after the Create call and you should be fine

Solution 3

MyFrm.Name is the same for both instances…

Make sure than MyFrm.Name is unique…

Related videos on Youtube

Select Multiple Expansions for a Component in Strange Eons

00 : 19

Select Multiple Expansions for a Component in Strange Eons

Scrap.TF Trade Offer Error

02 : 02

Scrap.TF Trade Offer Error

Fix We found a problem with some content in excel

05 : 18

Fix We found a problem with some content in excel

Strange Eons Tutorial

09 : 15

failed to create component reportviewer. the error message follows system.runtime.interopservices C#

01 : 04

failed to create component reportviewer. the error message follows system.runtime.interopservices C#

Discovered – currently not indexed 100% fix this issue (With Demo)

13 : 01

Discovered – currently not indexed 100% fix this issue (With Demo)

Cách sửa lỗi destination path  already exists and is not an empty directory khi clone git

04 : 05

Cách sửa lỗi destination path already exists and is not an empty directory khi clone git

How did I fix the error: "Could not find a version that satisfies the requirement"

00 : 52

How did I fix the error: «Could not find a version that satisfies the requirement»

How do I fix error ”CharacterStringTooLong (Value is too long) encountered with {Value}"?

01 : 56

How do I fix error ”CharacterStringTooLong (Value is too long) encountered with {Value}»?

Fix - Some data has already been output to browser on TCPDF

00 : 59

Fix — Some data has already been output to browser on TCPDF

problems setting up Django - ValueError Empty Module name - Django

01 : 25

problems setting up Django — ValueError Empty Module name — Django

export 'default' imported as was not found in  components possible exports default error fixed react

05 : 18

export ‘default’ imported as was not found in components possible exports default error fixed react

Lightning Data Service Basics For Aura Components | Handle Record Changes and Errors | Tutorial

02 : 15

Lightning Data Service Basics For Aura Components | Handle Record Changes and Errors | Tutorial

Comments

  • I want to let the user to create multiple instances of the same form (let’s call it Form1 which is a MDI child form). So I have two procedures like this where I create the forms.

    procedure MyProcedure1;           // procedure 2 is similar. it also has a var called MyFrm
    var MyFrm: TFrm1;
    begin
      ... 
      MyFrm:= TFrm1.create(MainForm);
      MyFrm.BringToFront;
      MyFrm.LoadFromFile(someFile);
    end;
    

    As you can see MyFrm is local var. This is ok for me as I don’t need to programatically access the form after I create it. There is no other global variable named Frm1. In the OnClose event of MyFrm I have Action:= caFree;

    What could cause the error above?
    A user sent that error. It happened only once and I cannot reproduce it.


    Edit:

    1. The error appears in the «MyFrm:= TFrm1.create» line.

    2. Some people suggested that I need to programatically give unique names to my dynamically created forms. I also wondered myself what name a form takes when it is created so I stepped into the code while calling the MyProcedure1 procedure.
      Delphi automatically gives unique names like
      MyFrm.name= MyFrm, then
      MyFrm.name= MyFrm_1,
      MyFrm.name= MyFrm_2,
      MyFrm.name= MyFrm_3, and so on.

    3. The MyFrm.Name is not altered in LoadFromFile. I have checked (breakpoint) the value of ‘MyFrm.Name’ at the end of procedure MyProcedure1; after LoadFromFile. The name is unique.

    4. As some people suggested, I override the SetName procedure and checked the name of TMyFrm. Indeed each form gets a unique name.

      procedure TMyFrm.SetName(const Value: TComponentName);
      begin
      ShowMessage(Value);
      inherited;
      end;

    5. I have many forms in this app but only the MainForm is auto-created.

    6. I don’t use threads. Anyway this will not be relevant since the forms are created by user (so multi-threading is irrelevant unless the user can create 2 forms at the same time).

    • Er, what’s this LoadFromFile method? It must be one of yours, unless it’s something added in XE.

    • @Altar, are you by any chance using multiple threads?

    • @Altar: Check this link gnostice.com/… and find if there is a mistake like that in your code

  • The Name need to be unique or nothing. MyFrm.Name := '' is better if you don’t care about the name, because you don’t need to figure out an new name AND the VCL gets to skip checking the name for uniqueness.

  • Nope. Delphi automatically assign a unique name to dynamically created forms.

  • Delphi automatically assign unique names to dynamically created forms.

  • Hi Uwe. I took your advice and I did a search for ‘name’ in the entire Frm1 unit (I also manually inspected LoadFromFile — just to be sure). Nobody is setting the ‘Name’ property.

  • I did that but at the end of procedure MyProcedure1. It is the same as your idea since at that point the MyFrm goes out of scope and nobody else access it.

  • Even though MyFrm (the variable) goes out of scope, the form itself exists not only in the heap, but also as a member of a global list of forms that belongs to the Screen global objects. Thus the requirement for the unique name (or else no name at all). I was not aware of the unique-auto-naming feature already in delphi, so I assume that the problem is happening elsewhere deep inside the VCL/RTL. Assume you tried the name := » to see if that solves it?

  • None of this has anything to do with the question asked, which was about a problem creating multiple instances of a form at runtime. The question has absolutely nothing do do with the design time editor, property editors, registering classes, or anything else in your entire answer.

Recents

Related

  • Ошибка a certificate chain could not be built to a trusted root authority 0x800b010a
  • Ошибка a bootable device has not been detected
  • Ошибка 9c59 при установке internet explorer 11
  • Ошибка 9c54 бмв е60 датчик auc
  • Ошибка 9c48 центра обновления windows 7