Форум: "Основная";
Текущий архив: 2005.03.13;
Скачать: [xml.tar.bz2];
ВнизВыяснение причины сообщения "A component named . already exists" Найти похожие ветки
← →
Димон (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)
Проблемы? Можно подробнее? :) Какие, например.
Страницы: 1 2 вся ветка
Форум: "Основная";
Текущий архив: 2005.03.13;
Скачать: [xml.tar.bz2];
Память: 0.56 MB
Время: 0.047 c