Форум: "Основная";
Текущий архив: 2003.01.16;
Скачать: [xml.tar.bz2];
ВнизClass TButton not found Найти похожие ветки
← →
Алексей П (2003-01-04 18:27) [0]Не подскажет ли кто как побароть исключение "Class TButton not found"
задача: создать форму,сохраненную ранее.
// попытка выполнить задачу
procedure TForm11.Button2Click(Sender: TObject);
var
Form:TForm;
s:String;
begin
s :=ExtractFilePath(Application.ExeName)+"Form._dfm";
Form:=TForm.Create(Self);
LoadComponentFromTextFile(Form,s);
Form.Show
end;
procedure LoadComponentFromTextFile(Component: TComponent; const FileName: string);
var
ms: TMemoryStream;
fs: TFileStream;
begin
fs := TFileStream.Create(FileName, fmOpenRead);
ms := TMemoryStream.Create;
try
ObjectTextToBinary(fs, ms);
ms.position := 0;
ms.ReadComponent(Component);
finally
ms.Free;
fs.free;
end;
end;
//-----------------------
// сам файл "Form._dfm"
object Form_11: TForm
Left = 244
Top = 180
Width = 696
Height = 480
Caption = "Form11"
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = "MS Sans Serif"
Font.Style = []
OldCreateOrder = False
Visible = True
PixelsPerInch = 96
TextHeight = 13
object Button4: TButton
Left = 96
Top = 352
Width = 75
Height = 25
Caption = "Button4"
TabOrder = 6
end
end
← →
Юрий Зотов (2003-01-04 18:36) [1]> как побароть исключение "Class TButton not found"
В initialization модуля главной формы: RegisterClass(TButton);
И так же c самой формой и остальными компонентами.
Еще см. RegisterClasses.
← →
Алексей П (2003-01-05 09:32) [2]Спасибо за подсказку, прекрасно, но ...
В файл сохраняюся ссылки обработчиков событий на процедуры, а при попытке их загрузить - исключение: "Invalid Property Value".
А как с этим бороться?
← →
Delirium^.Tremens (2003-01-05 09:37) [3]Попробуй:
Form:=TForm.CreateNew(...);
← →
Алексей П (2003-01-05 09:45) [4]Form:=TForm.CreateNew(...);
Не проходит
← →
Delirium^.Tremens (2003-01-05 09:50) [5]
> Алексей П (05.01.03 09:45)
> Form:=TForm.CreateNew(...);
> Не проходит
Куда не проходит?
← →
Алексей П (2003-01-05 09:55) [6]После замены
Form:=TForm.Create(Self);
на
Form:=TForm.CreateNew(Self);
Исключение осталось на месте.
← →
Delirium^.Tremens (2003-01-05 10:04) [7]TForm.CreateNew() создает пустышку, содержимое которой можно считать из файла *.dfm, но RegisterClasses все же потребуется.
← →
Юрий Зотов (2003-01-05 10:13) [8]> В файл сохраняюся ссылки обработчиков событий на процедуры, а
> при попытке их загрузить - исключение: "Invalid Property Value".
Естественно. Вы же создаете экземпляр TForm, а в этом классе никаких обработчиков нет. Создавайте экземпляр того класса, который реально был сохранен. Если он при чтении заранее неизвестен, то может быть считан из того же файла.
← →
Алексей П (2003-01-05 12:30) [9]>>Естественно. Вы же создаете экземпляр TForm, а в этом классе >>никаких обработчиков нет.
Это я монимаю.
>>Создавайте экземпляр того класса, который реально был сохранен.
Форма, которую я пытаюсь сохранить/загрузить имеет свои процедуры обработки событий, которые используются при дизайне этой формы в Run-Time, и при открытии этой формы в дальнейшем могут и непонадобиться. Так вот мне надо либо сохранить ее без этих процедур и свойств, либо без них загрузить.
Как это можно реализовать?
>>Если он при чтении заранее неизвестен, то может быть считан из того же файла.
Как это можно сделать?
← →
Skier (2003-01-05 12:58) [10]>Алексей П
> Так вот мне надо либо сохранить ее без этих процедур и свойств,
> либо без них загрузить.
Самое простое - это перед сохранением обнулить все ненужные
обработчики (SomeButton.OnClick := nil)
> Как это можно сделать?
Считать имя класса из того же файла (как это делает Delphi)
и потом (для создания экземпляров этого класса) поспользоваться GetClass(...) либо FindClass(...), предварительно зарегистрировав все классы, которые
могут быть использованы (см. RegisterClasses)
← →
Юрий Зотов (2003-01-05 12:59) [11]Можно сохранить без ссылок на методы либо ручками, либо переопределив объявления событий (stored False), но вряд ли это будет хорошо. Загрузить без ссылок на методы тоже можно ручками, но это немалая головная боль. Гораздо проще сохранять и грузить как есть, но сразу после загрузки очистить ссылки на обработчики (присвоить им nil). Сделать это можно через RTTI (модуль TypInfo, процедура GetPropList с фильтром tkMethod и далее цикл по списку с SetMethodProp).
Считать класс формы из текстового DFM можно тоже ручками (он в конце первой строки, а затем GetClass), но лучше и проще сделать это автоматически:
Component := MemoryStream.ReadComponent(nil);
Компонент будет создан с правильным классом (из самого DFM). Создавать его перед этим вручную не нужно, иначе будет утечка памяти.
В любом случае требуется предварительная регистрация классов.
← →
awex (2003-01-05 14:05) [12]
procedure OnFindMetod(Reader: TReader; const MethodName: string;
var Address: Pointer; var Error: Boolean);
begin
MessageDlg(MethodName, mtWarning, [mbOK], 0);
Address := nil;
Error := False; // По сути это простая заглушка
end;
// Создание компонеты из потока с игнорированием обработчиков
procedure CreateComponent(AOwner: TComponent;
InstanceClass: TComponentClass;
var Reference,
BufferStream: TStream);
var
Reader: TReader;
begin
Reader := TReader.Create(BufferStream, 4096);
Reader.OnFindMethod := OnFindMetod;
TComponent(Reference) := InstanceClass.Create(AOwner);
try
try
BufferStream.Position := 0;
BufferStream.ReadResHeader;
Reader.ReadRootComponent(TComponent(Reference));
except
MessageDlg("Error!!", mtWarning, [mbOK], 0);
end;
finally
Reader.Free;
end;
end;
← →
Юрий Зотов (2003-01-05 16:40) [13]Сначала Create, потом ReadRootComponent.
А ведь это форма. Не получится "Component ... already exists"?
Видимо, все же CreateNew. И TFormClass.
← →
Delirium^.Tremens (2003-01-05 17:02) [14]Юрий Зотов © (05.01.03 16:40)
Как Вы уже сказали (04.01.03 18:36), причина ошибки в отсутствии
RegisterClasses([TFMyForm, TButton, TDBGrid..]);
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2003.01.16;
Скачать: [xml.tar.bz2];
Память: 0.48 MB
Время: 0.01 c