Ошибки Delphi "EClassNotFound" и возможность поврежденного DFM
Я получаю каскадный набор ошибок "EClassNotFound" в моем проекте Delphi 2007. Кажется, не вызвано отсутствующим значением свойства Name, как это часто бывает, и хотя добавление RegisterClass(XXX) в раздел (-ы) инициализации исправляет имеющуюся ошибку EClassNotFound, другой, по-видимому, следует за ней бесконечно.
Я наконец-то взломал файл DFM в текстовом редакторе, и он, вероятно, выглядит испорченным (много не-ASCII-символов среди имен элементов формы и очень "неструктурированный" вид по сравнению с тем, что я привык видеть в файле DFM).). (Я бы опубликовал то же самое здесь, но не уверен, что все в порядке, с не-ASCII, так что будет сдерживаться).
Форма загружается нормально, и кажется, что компиляция / проверка синтаксиса тоже ОК, но как только я запустил ее, проблема.
Возвращаясь к ранним версиям этого в SVN, похоже, что он находился в этом состоянии в течение некоторого времени, что заставляет меня думать, что либо A) файл DFM не является моей проблемой, либо B) потоковая передача форм Delphi является довольно ошибочной -устойчивый / крепкий (Бонусный вопрос: что это?).
Если файл DFM является проблемой, и он поврежден, откат должен быть СПОСОБОМ возврата, и это будет дорого. Учитывая, что IDE все еще может загрузить его, есть ли утилита, которая может очистить файл?
Или я полностью не в курсе дела с DFM в качестве основного подозреваемого?
Спасибо людям за вклад. Забыл о бинарных / текстовых опциях с файлами DFM, так что это было полезно. Похоже, сам DFM не поврежден.
Тем не менее проблема с EClassError. В связи с отсутствием значений свойств или ссылками на несуществующие свойства и т. д., возникает еще один вопрос: для какого класса дается ошибка (в настоящее время это TnxSqlUpdateObject, но, вероятно, более ожидаемый, если опыт до сих пор не противоречит) обычно / всегда актуальный "виновник" класса / объекта?
Например, сейчас моя основная форма имеет четыре ссылки на TnxSqlUpdateObject, которые фактически отброшены в форме. Если я поместил RegisterClass(TnxSqlUpdateObject) в раздел инициализации, он нормально работает для этой ошибки EClassNotFound, но затем переходит к следующей (в данном случае TStringField).
В этом случае я переустанавливал компоненты NexusDB, а также создал новый проект с использованием некоторых компонентов, которые, по моему мнению, могут быть проблемой. Он компилируется и работает нормально, пока я не добавлю эту другую форму из моего реального проекта (который, в свою очередь, к сожалению, ссылается на довольно много других).
Итак, похоже, что моя настоящая проблема в том, как методично диагностировать и исправлять все без исключения ошибки EClassNotFound?
6 ответов
Я получаю эту ошибку, если компонент находится в форме, но в исходном файле также нет записи в определении формы. Чаще всего, когда я скопировал и вставил из другой формы. Самое простое решение - выбрать компонент, вырезать его и вставить обратно. Когда вы сохраните, модуль компонента будет добавлен к источнику, и когда вы запустите его снова, все будет в порядке.
Если вы можете загрузить форму в Delphi IDE, ресурс DFM не будет поврежден. Delphi использует тот же код для загрузки DFM, что и конечный исполняемый файл, поэтому я думаю, что причина не в этом.
Вы можете открыть DFM непосредственно в Delphi IDE (если соответствующий файл pas не открыт), или вы можете использовать Alt+F12 для переключения между представлением формы и представлением текста DFM. В этом представлении структура должна быть вменяемой, с правильным отступом и так далее.
Как указал Gamecat, вы можете использовать команду во всплывающем меню формы для переключения формата хранения DFM. Оставьте это как текст для Delphi 5+, так будет лучше с SVN.
Что касается причины вашей проблемы во время выполнения - я понятия не имею...
Изменить: После того, как вы исключили DFM как источник проблемы, я могу только предположить, что отсутствует важный элемент в списке использований, что может произойти, только если не все компоненты в вашей форме имеют соответствующее поле участника. Вы должны проверить, что все компоненты, на которые есть ссылки в DFM, также находятся в форме, даже если вы не обращаетесь к ним в своем коде. Это, в свою очередь, приведет к тому, что Delphi добавит недостающие единицы к предложению использования при сохранении файла. Регистрация компонентов вручную не требуется, если в классе формы есть ссылки на все компоненты в DFM.
Для быстрой проверки вы можете создать тестовую форму, перетащить на нее все компоненты, которые есть у вашей "проблемной" формы (достаточно одного экземпляра), и проверить, работает ли она.
Если у вас есть недавно скомпилированный exe-файл, который работает, вы можете использовать редактор ресурсов, такой как PE Explorer, чтобы получить определение dfm. Затем вы можете сравнить тот из exe с тем, что у вас сейчас есть.
Я считаю, что есть инструменты для преобразования двоичных dfm-файлов в текстовые файлы. Это даст вам лучший обзор файла и поможет вам решить, действительно ли он поврежден или нет. Я вижу, что у Феликса есть кое-что по теме.
Если Delphi IDE показывает форму нормально, без ошибок, я не могу поверить, что есть коррупционная ошибка. Может ли быть проблема с пакетом? Вы используете runtime-пакеты?
Обновить:
Вы пытались использовать Eurekalog или madExcept или что-то подобное, чтобы получить более подробное сообщение об ошибке с помощью callstack и memorydumt? Может быть, это даст вам некоторое представление о проблеме.
Но, как правило, я думаю, что эта ошибка происходит из-за отсутствия пакета времени выполнения или отсутствующего модуля в предложении использования. Если вы думаете, что компонент witch вызывает ошибку, найдите в источнике вызов RegisterClass() и посмотрите, включен ли этот модуль в условие использования projcets. Если нет, добавьте его и попробуйте снова.
Ну, файл dfm может быть двоичным или текстовым (как я прав, начиная с версии 4.0).
Вы можете проверить это, щелкнув правой кнопкой мыши на форме и отметив флажок Text DFM.
Если файл dfm поврежден, то вы можете попытаться исправить его, удалив все подозрительные строки. Обязательно оставьте объект.. конечные наборы без изменений, и вы, вероятно, потеряете только некоторые значения свойств.
Кстати, файл dfm должен выглядеть так (чтобы получить представление об общей структуре):
object Form5: TForm5
Left = 0
DesignSize = (
426
652)
object Button1: TButton
Left = 343
end
object Memo2: TMemo
Anchors = [akLeft, akTop, akRight, akBottom]
end
end
Если это не выглядит так, вы, вероятно, редактируете двоичный файл.
Попробуй это:
- Сначала сделайте резервную копию
- Щелкните правой кнопкой мыши на форме в дизайнере; снимите флажок "Текст DFM"
- Сохранить
- Щелкните правой кнопкой мыши на форме в дизайнере; отметьте "Текст DFM"
- Сохранить
Это может произойти, если вы изменили один из своих пользовательских компонентов и удалили из него свойство. Свойство по-прежнему в DFM, и Delphi пытается его инициализировать.
Попробуйте вручную удалить детали из вашего DFM, чтобы вы могли точно определить, какой компонент вызывает проблему.