![]()  | 
	
 
  | 
		
			
  | 	
	
	
		
		|||||||
| Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны | 
![]()  | 
	
	
| 
		 | 
	Опции темы | Поиск в этой теме | Опции просмотра | 
| 
		 
			 
			#1  
			
			
			
			
		 
		
		
	 | 
|||
		
		
  | 
|||
| 
	
	
		
			
			 Приветствую всех участников форума! Проконсультируйте, по возможности…  
		
	
		
		
		
		
		
	
		
		
	
	
	Суть проблемы: 1. При сохранении формы в файл процедурой WriteComponentResFile, осуществляется корректное сохранение формы, расположенных на ней компонентов, всех свойств и "событий". 2. Если это проделать с отдельным компонентом – сохраняется всё, кроме "событий". В первом случае, при загрузке формы из файла, как форма объекта, так и все расположенные на ней компоненты корректно реагируют на заданные события. Во втором случае соответственно реакций на события нет. Если в первом случае в созданном бинарном файле имеются данные с названием событий, например |??#&@OnMouseMove??MyControlMouseMove#%8#, то во втором случае такие данные отсутствуют… И собственно вопрос, как добиться того, чтобы при сохранении отдельного компонента, сохранялись данные о событиях?  | 
| 
		 
			 
			#2  
			
			
			
			
		 
		
		
	 | 
||||
		
		
  | 
||||
| 
	
	
		
			
			 MethodAddress(), MethodName() тебе в помощь. 
		
	
		
		
		
		
			
		
		
		
		
	
		
		
	
	
	 | 
| 
		 
			 
			#3  
			
			
			
			
		 
		
		
	 | 
|||
		
		
  | 
|||
| 
	
	
		
			
			 Цитата: 
	
  | 
| 
		 
			 
			#4  
			
			
			
			
		 
		
		
	 | 
|||
		
		
  | 
|||
| 
	
	
		
			
			 Мда, третий день эксперементов в пустую. Не удалось одержать победу в данной ситуации... Судя по всему придется писать свой врайтер/ридер... 
		
	
		
		
		
		
		
	
		
		
	
	
	 | 
| 
		 
			 
			#5  
			
			
			
			
		 
		
		
	 | 
|||
		
		
  | 
|||
| 
	
	
		
			
			 Может поможет: 
		
	
		
		
		
		
		
	
		
		
	
	
	Код: 
	procedure TForm1.Save_Me2;
var
  ms: TMemoryStream;
  fs: TFileStream;
begin
  fs := TFileStream.Create('C:\987.222', fmCreate or fmOpenWrite);
  ms := TMemoryStream.Create;
  try
    ms.WriteComponent(self);
    ms.Seek(0, soFromBeginning);
    ObjectBinaryToText(ms, fs);
  finally
    ms.Free;
    fs.free;
  end;
end; | 
| 
		 
			 
			#6  
			
			
			
			
		 
		
		
	 | 
|||
		
		
  | 
|||
| 
	
	
		
			
			 Цитата: 
	
 Благодарю, roamer, но к сожалению результат выполнения этой подпрограммы аналогичен результату выполнения процедуры WriteComponentResFile(), т.е. в файл сохраняется всё кроме ссылок на события...  | 
| 
		 
			 
			#7  
			
			
			
			
		 
		
		
	 | 
|||
		
		
  | 
|||
| 
	
	
		
			
			 Цитата: 
	
 Например здесь читается и пишется кнопка и таблица Код: 
	unit Unit2;
interface
uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls, Db, DBTables;
type
  TForm1 = class(TForm)
    SaveTable: TButton;
    DatabaseA: TDatabase;
    Table1: TTable;
    Table1NAME: TStringField;
    Table1SIZE: TSmallintField;
    Table1WEIGHT: TSmallintField;
    Table1AREA: TStringField;
    Table1BMP: TBlobField;
    Memo_Show_Writer: TMemo;
    Memo_Log: TMemo;
    DataSource1: TDataSource;
    LoadTable: TButton;
    Memo_Show_Reader: TMemo;
    SaveButton: TButton;
    TestButton: TButton;
    LoadButton: TButton;
    procedure Table1BMPChange(Sender: TField);
    procedure Table1AREAChange(Sender: TField);
    procedure SaveTableClick(Sender: TObject);
    procedure Table1CalcFields(DataSet: TDataSet);
    procedure LoadTableClick(Sender: TObject);
    procedure TestButtonClick(Sender: TObject);
    procedure SaveButtonClick(Sender: TObject);
    procedure LoadButtonClick(Sender: TObject);
  private
    procedure FindAncestorEvent(Writer: TWriter; Component: TComponent;
      const Name: string; var Ancestor, RootAncestor: TComponent);
    procedure ShowBinaryStream(S1: TStream; Lines: TStrings);
    procedure SaveComponentToFile(T: TComponent; FileName:String);
    procedure RestoreComponentFromFile(ComponentName: String; FileName:String);
    { Private declarations }
  public
    { Public declarations }
  end;
var
  Form1: TForm1;
implementation
uses Unit3;
{$R *.DFM}
/// следующие методы только для отладки - что бы были
procedure TForm1.Table1BMPChange(Sender: TField);
begin
  Memo_Log.Lines.Add('Table1BMPChange');
end;
procedure TForm1.Table1AREAChange(Sender: TField);
begin
  Memo_Log.Lines.Add('Table1AREAChange');
end;
procedure TForm1.Table1CalcFields(DataSet: TDataSet);
begin
   Memo_Log.Lines.Add('Table1CalcFields'); //
end;
/// процедура вызывается где то изнутри процедур чтения и записи
procedure TForm1.FindAncestorEvent (Writer: TWriter; Component: TComponent;
    const Name: string; var Ancestor, RootAncestor: TComponent);
begin
  Memo_Log.Lines.Add(Name);
end;
/// процедура показывает TStream в удобочитаемом виде
procedure TForm1.ShowBinaryStream(S1:TStream;Lines:TStrings);
var
  S2:TStream;
begin
  S2:=TMemoryStream.Create;
  try
    try
      S1.Position:=0;
      ObjectBinaryToText(S1, S2);
    except
      Memo_Log.Lines.Add('Ошибка конвертации');
    end;
    S2.Position:=0;
    Lines.LoadFromStream(S2);
  finally
    S2.Free;
  end;
end;
/// процедура сохраняет компоненту в файл
procedure TForm1.SaveComponentToFile(T:TComponent; FileName:String);
var//63216
  Writer:TWriter;
  MemoryStream,S2:TStream;
begin
  MemoryStream:=TMemoryStream.Create;
  try
    Writer:=TWriter.Create(MemoryStream, 8192);
    try
      Writer.OnFindAncestor :=  FindAncestorEvent;
      Writer.Root := Self;  // чьи методы будут использоваться
      Writer.WriteSignature; 
      Writer.WriteComponent(T);
    finally
      Writer.Free;
    end;
    // копируем MemoryStream на файл
    MemoryStream.Position:=0;
    S2:=TFileStream.Create(FileName,fmCreate);
    try
      S2.CopyFrom(MemoryStream,0);
    finally
      S2.Free;
    end;
    ShowBinaryStream(MemoryStream,Memo_Show_Writer.Lines);
    FreeAndNil(T); // уничтожаем компонент, что бы потом проверить
  finally
    MemoryStream.Free;
  end;
end;
/// читает компонент из файла
procedure TForm1.RestoreComponentFromFile(ComponentName:String; FileName:String);
var
  Reader:TReader;
  S1:TStream;
  T,T1:TComponent;
begin
  S1:=TFileStream.Create(FileName,fmOpenRead);
  try
    ShowBinaryStream(S1, Memo_Show_Reader.Lines );
    S1.Position:=0;
    Table1.Free;
    Reader:=TReader.Create(S1,8192);
    try
      Reader.BeginReferences;
      Reader.Owner  :=Self; // !!
      Reader.Root   :=Self; // чьи методы будут использоваться
      Reader.ReadSignature;
      T:=Reader.ReadComponent(Nil);
      T1:=FindComponent(ComponentName);
      if T = Nil then
        Memo_Log.Lines.Add('Компонент не прочитался')
      else
      if T1 = Nil then
        Memo_Log.Lines.Add('Компонент не находится')
      else
      if T1<>T then
        Memo_Log.Lines.Add('Компоненты не совпадают')
      else
        Memo_Log.Lines.Add('Компонент прочитался');
      Reader.EndReferences;
    finally
      Reader.Free;
    end;
    if T Is TControl then TControl(T).Parent:=Self;  // это тоже может быть важно
  finally
    S1.Free;
  end;
end;
/// тест сохраняемой кнопки
procedure TForm1.TestButtonClick(Sender: TObject);
begin
  Memo_Log.Lines.Add('Test - OK');
end;
//а теперь пишем и читает таблицу
procedure TForm1.SaveTableClick(Sender: TObject);
begin
  SaveComponentToFile(Table1,ChangeFileExt(ParamStr(0),'.Table1.dfm'))
end;
procedure TForm1.LoadTableClick(Sender: TObject);
begin
  RestoreComponentFromFile('Table1',ChangeFileExt(ParamStr(0),'.TestButton.dfm'));
end;
//а теперь пишем и читает кнопку
procedure TForm1.SaveButtonClick(Sender: TObject);
begin
   SaveComponentToFile(TestButton,ChangeFileExt(ParamStr(0),'.TestButton.dfm'));
end;
procedure TForm1.LoadButtonClick(Sender: TObject);
begin
  RestoreComponentFromFile('TestButton',ChangeFileExt(ParamStr(0),'.TestButton.dfm'));
end;
end.Код: 
	object Form1: TForm1
  Left = 325
  Top = 164
  Width = 634
  Height = 800
  Caption = 'Form1'
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'MS Sans Serif'
  Font.Style = []
  OldCreateOrder = False
  PixelsPerInch = 96
  TextHeight = 13
  object SaveTable: TButton
    Left = 8
    Top = 8
    Width = 75
    Height = 25
    Caption = 'SaveTable'
    TabOrder = 0
    OnClick = SaveTableClick
  end
  object Memo_Show_Writer: TMemo
    Left = 8
    Top = 232
    Width = 609
    Height = 257
    ScrollBars = ssBoth
    TabOrder = 1
  end
  object Memo_Log: TMemo
    Left = 8
    Top = 72
    Width = 361
    Height = 145
    TabOrder = 2
  end
  object LoadTable: TButton
    Left = 8
    Top = 32
    Width = 75
    Height = 25
    Caption = 'LoadTable'
    TabOrder = 3
    OnClick = LoadTableClick
  end
  object Memo_Show_Reader: TMemo
    Left = 8
    Top = 496
    Width = 609
    Height = 265
    ScrollBars = ssBoth
    TabOrder = 4
  end
  object SaveButton: TButton
    Left = 96
    Top = 8
    Width = 75
    Height = 25
    Caption = 'SaveButton'
    TabOrder = 5
    OnClick = SaveButtonClick
  end
  object TestButton: TButton
    Left = 480
    Top = 24
    Width = 75
    Height = 25
    Caption = 'TestButton'
    TabOrder = 6
    OnClick = TestButtonClick
  end
  object LoadButton: TButton
    Left = 97
    Top = 34
    Width = 73
    Height = 25
    Caption = 'LoadButton'
    TabOrder = 7
    OnClick = LoadButtonClick
  end
  object Table1: TTable
    OnCalcFields = Table1CalcFields
    DatabaseName = 'A'
    MasterSource = DataSource1
    TableName = 'animals.dbf'
    Left = 400
    Top = 24
    object Table1NAME: TStringField
      FieldName = 'NAME'
      Size = 10
    end
    object Table1SIZE: TSmallintField
      FieldName = 'SIZE'
    end
    object Table1WEIGHT: TSmallintField
      FieldName = 'WEIGHT'
    end
    object Table1AREA: TStringField
      FieldName = 'AREA'
      OnChange = Table1AREAChange
    end
    object Table1BMP: TBlobField
      FieldName = 'BMP'
      OnChange = Table1BMPChange
      BlobType = ftTypedBinary
      Size = 1
    end
  end
  object DatabaseA: TDatabase
    AliasName = 'DBDEMOS'
    Connected = True
    DatabaseName = 'A'
    SessionName = 'Default'
    Left = 336
    Top = 24
  end
  object DataSource1: TDataSource
    DataSet = Form3.Table1
    Left = 368
    Top = 24
  end
end | 
| 
		 
			 
			#8  
			
			
			
			
		 
		
		
	 | 
|||
		
		
  | 
|||
| 
	
	
		
			
			 Спасибо, icWasya. Ваши наработки в действительности осуществляют сохранение всех данных компонента. Бегло просмотрел исходники стандартных подпрограмм WriteComponentResFile/ReadComponentResFile - по сути код идентичен приведенному Вами (работа так же осуществляется с TWriter и TReader). В Вашем примере всё работает, а стандартные - работают не корректно, но да бог с ним... Еще раз огробное спасибо за пример. 
		
	
		
		
		
		
		
	
		
		
	
	
	 | 
| 
		 
			 
			#9  
			
			
			
			
		 
		
		
	 | 
|||
		
		
  | 
|||
| 
	
	
		
			
			 Цитата: 
	
  | 
| 
		 
			 
			#10  
			
			
			
			
		 
		
		
	 | 
|||
		
		
  | 
|||
| 
	
	
		
			
			 Выдает сообщение "Компоненты не совпадают" ХЕЕЕЛП!!! 
		
	
		
		
		
		
		
	
		
		
	
	
	 | 
| 
		 
			 
			#11  
			
			
			
			
		 
		
		
	 | 
||||
		
		
  | 
||||
| 
	
	
		
			
			 Цитата: 
	
 Единственно только ошибка есть здесь: Код: 
	procedure TForm1.LoadTableClick(Sender: TObject);
begin
  RestoreComponentFromFile('Table1',ChangeFileExt(ParamStr(0),'.TestButton.dfm'));
end;Код: 
	procedure TForm1.LoadTableClick(Sender: TObject);
begin
  RestoreComponentFromFile('Table1',ChangeFileExt(ParamStr(0),'.Table1.dfm'));
end; | 
| 
		 
			 
			#12  
			
			
			
			
		 
		
		
	 | 
|||
		
		
  | 
|||
| 
	
	
		
			
			 У меня вот такая структура 
		
	
		
		
		
		
		
	
		
		
	
	
	Form-Panel-ScrollBox-RichEdit Мне нужно сохранить ScrollBox со всеми компонентами на ней Вроде сохраняет и в файлике можно посмотреть если блокнотом открыть а когда считываю, то ScrollBox.ComponentCount=0, хотя они на ней появляются, помогите пожулуйста  | 
| 
		 
			 
			#13  
			
			
			
			
		 
		
		
	 | 
||||
		
		
  | 
||||
| 
	
	
		
			
			 Цитата: 
	
  | 
| 
		 
			 
			#14  
			
			
			
			
		 
		
		
	 | 
|||
		
		
  | 
|||
| 
	
	
		
			
			 Добрый день, с этим вроде разобрался, вот только возникла другая проблемка у ScrollBox, на который выводятся компоненты отваливается Canvas. 
		
	
		
		
		
		
		
	
		
		
	
	
	До восстановления компонент из файла все ок. После ничего не могу рисовать на ScrollBox. Знаю что у ScrollBox нет свойства Canvas, поэтомуделаю вот так Canva:=TCanvas.Create; Canva.Handle:=getdc(ScrollBox1.Handle); и все прокатывало после восстановления компонент, рушится какая-то связка, пересоздать канву и переназначить Handle не помогает  | 
| 
		 
			 
			#15  
			
			
			
			
		 
		
		
	 | 
||||
		
		
  | 
||||
| 
	
	
		
			
			 Цитата: 
	
 Код: 
	var
  Canva: TControlCanvas;
begin
  Canva := TControlCanvas.Create;
  try
    Canva.Control := ScrollBox1;
    Canva.Brush.Color := clRed;
    Canva.Ellipse(10, 20, 30, 40);
  finally
    Canva.Free;
  end;
end; |