Delphi: "Свойство ClientHeight не существует"

Моя Delphi-программа прекрасно собирается и компилируется, однако, как только она запускается в режиме отладки, я получаю следующую ошибку;

Свойство ClientHeight не существует

После просмотра всех исходных файлов.DFM, в каждой форме есть код, который есть;

ClientHeight = 111

Я не понимаю, где я здесь не так?

5 ответов

Решение

Ваши формы были бы сохранены с более новой версией Delphi. К сожалению, вам нужно будет открыть каждую форму в IDE и снова сохранить ее, чтобы очистить новые свойства. Существует инструмент, который может помочь вам, под названием DFMCheck ( http://andy.jgknet.de/blog/ide-tools/dfmcheck/). Это дополнение, которое будет проходить через все ваши формы и сообщать вам о любых проблемах с формами, которые будут отображаться только во время выполнения.

Причина, по которой вы видите проблему, заключается в следующем. Delphi сохраняет формы со всеми свойствами. Он использует потоковую передачу для загрузки форм во время выполнения. Когда он пытается загрузить форму с несуществующими свойствами, вы получите такую ​​ошибку, поскольку потоковая система пытается установить свойство для компонента, когда свойство не существует.

Я знаю, что это старая тема, но, надеюсь, это поможет другим, у которых есть эта проблема.

В таких случаях, когда ваш класс унаследовал от других, и вы знаете, что свойства есть, просто повторно опубликуйте их. Добавьте опубликованный раздел и добавьте их снова, например:

published
property ClientWidth;
property ClientHeight;

Это затем вынуждает компилятор скомпилировать эти typeinfo для частей, где родительские классы могут иметь предварительные объявления, и, таким образом, решить вашу проблему. Надеюсь, это кому-нибудь поможет, у меня ушло 3 дня, чтобы в итоге найти решение.

Такая же ошибка происходит в современном Delphi (например, Rio 10.3) с FMX-кадрами. После некоторого расследования выяснилось, что это вызвано изменением наследования TFrame. Пример ниже:

type
  // Declaration of custom type
  TFrameEx = class(TFrame) .. {here I override a couple of methods} end;

// Causes a bug (described below)
TMyFrame = class(TFrameEx)

// Works fine
TMyFrame = class(TFrame)

Объяснение:
Из-за измененного типа Delphi не смог правильно выбрать тип TMyFrame между FMX и VCL. Поэтому, когда TMyFrame был открыт в IDE, он попросил бы удалить свойства FMX (не существующие в VCL, например, Size.Width) и добавить свойства VCL (например, ClientWidth). При сохранении это привело бы к ошибкам TMyFrame - в процессе выполнения после инициализации отобразилась бы ошибка "Свойство ClientHeight не существует".

В моем случае я унаследовал TFrame, который был сохранен в Delphi 7, и я изменил .dfm для разрешения.

Первая строка: "объект" frmMain: TfrmMain

Я изменил на «унаследованный», вот так: унаследованный frmMain: TfrmMain

Был похожий баг. Сначала вам нужен файл dfm для вашего кадра. Когда вы наследуете кадр, файл dfm должен начинаться с «унаследованного MyFrame: TFRameEx», а НЕ «объекта MyFrame: TFrameEx». Без наследования, когда я это делал, добавлялись свойства TForm, а в редакторе у фрейма были события TForm, в Delphi 10.3. Таким образом, Delphi действительно нуждается в dfm, чтобы найти правильный тип. Если вы используете меню ide, это будет сделано автоматически. New->Others->inheritables создаст dfm с унаследованной строкой, создаст файл с {$R *.dfm} в нем и строку в исходном коде проекта "unitname in '......pas' {MyFrame TFrame};" Или вы можете сделать это вручную. Что касается возможности иметь несколько кадров в одном устройстве, я сам не проверял это, но, поскольку строка {$R *.dfm}, это может быть выполнимо.

хотел, чтобы это был комментарий к решению kromster, но, видимо, не могу комментировать.

Другие вопросы по тегам