Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > [ "Начинающим" ]
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 25.10.2014, 13:16
Gareth Gareth вне форума
Активный
 
Регистрация: 21.03.2013
Адрес: Приднестровье
Сообщения: 202
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию Сохранение динамических компонентов

Здравствуйте.

Для своих нужд пишу программу, в ней динамически (runtime) создаются много компонентов, штук 50 панелей, 150 label`ов, 50 edit`ов и тд..в общем не мало компонентов.

Вот открыл я прогу, понасоздавал компонентов сколько мне надо, а при следующем открытии их же не будет). Подскажите, коим образом можно это дело сохранить? В начале думал ini, но что-то мне подсказывает, что через ini, это будет жесть...


Ранее я уже озвучивал данный вопрос, в этой теме клац, Но мой мозг не совсем понял) разжуйте пожалуйста.

Последний раз редактировалось Gareth, 25.10.2014 в 13:27.
Ответить с цитированием
  #2  
Старый 25.10.2014, 13:51
Аватар для Alegun
Alegun Alegun вне форума
LMD-DML
 
Регистрация: 12.07.2009
Адрес: Богородское
Сообщения: 3,025
Версия Delphi: D7E
Репутация: 1834
По умолчанию

А что, сохранение через потоковый WriteComponent вам не подходит разве?
Тогда действительно, при завершении работы сборки можно всё сохранить в ini-файле, посредством циклического перебора компонентов на форме, их класс, размер, позицию, название etc., гимора особого не будет, поскольку это всё автоматом происходит, а при старте по этим данным их воссоздавать - проблема лишь в динамически подключаемых процедурах обработки сообщений, но это тоже не очень сложно, при грамотной разработке их содержимого, и если не ошибаюсь, то пример подобного я вам уже приводил ранее
Ответить с цитированием
Этот пользователь сказал Спасибо Alegun за это полезное сообщение:
Gareth (26.10.2014)
  #3  
Старый 26.10.2014, 03:53
Gareth Gareth вне форума
Активный
 
Регистрация: 21.03.2013
Адрес: Приднестровье
Сообщения: 202
Версия Delphi: Delphi 7
Репутация: 10
Вопрос

Цитата:
Сообщение от Alegun
А что, сохранение через потоковый WriteComponent вам не подходит разве?
Тогда действительно, при завершении работы сборки можно всё сохранить в ini-файле, посредством циклического перебора компонентов на форме, их класс, размер, позицию, название etc., гимора особого не будет, поскольку это всё автоматом происходит, а при старте по этим данным их воссоздавать - проблема лишь в динамически подключаемых процедурах обработки сообщений, но это тоже не очень сложно, при грамотной разработке их содержимого, и если не ошибаюсь, то пример подобного я вам уже приводил ранее
У вас не остался еще тот проэктик, который вы мне давали, в той теме?
Есть несколько нюансов, которые я не могу понять, а проэкт уже удален с файлообменника, да и у меня его нету уже.

Почитал про WriteComponent / ReadComponent, посмотрел примеры, попробовал, и ничего не понял. Всё потому что примеры не на runtime компонентах, а на обычных..
Куда сохраняется вся инфа ? В ини мы делаем сам файлик .ini, а с Filestream куда они кладутся ?

Мне бы тот ваш проэкт, который вы мне давали... ImgIni.rar, возможно оттуда я бы вычерпнул нужную информацию для себя (по крайней мере сейчас, когда хоть немного начал понимать).

Не затруднит ли вас написать небольшой пример, с использованием динамического компанента ?

Вот допустим на кнопку я создаю до 50 панелей и 50 image (1 клик - 1 панель, 1 image), не понимаю как всё это сохранить, с учетом того, что это создано в runtime, а может и не создано.

Код:
var
  Form1: TForm1;
  panel: array [1..50] of TsPanel;

....
procedure TForm1.sButton1Click(Sender: TObject);
var 
  nPanel:=nPanel+1;
  toppanel:=toppanel+47;
  leftpanel:=0;
  widthpanel:=ClientWidth;
  heightpanel:=45;

begin
panel[nPanel]:=TsPanel.Create(form1);   
panel[nPanel].Parent:=form1;
panel[nPanel].Top:=toppanel;
panel[nPanel].Left:=leftpanel;
panel[nPanel].Width:=widthpanel;
panel[nPanel].Height:=heightpanel;
//-----------
{-----------------IMG--------------------}
img[nPanel]:=TImage.Create(panel[npanel]);
img[nPanel].Parent:=panel[npanel];
img[npanel].Stretch:=true;
img[nPanel].Top:=2;
img[nPanel].Left:=20;
img[nPanel].Width:=60;
img[npanel].Height:=40;
end;

В крайнем случае, может подкинете статью о том как работать с Writecomponent именно для Runtime ?

Извиняюсь за свою назойливость и тупизм...
Ответить с цитированием
  #4  
Старый 26.10.2014, 04:20
Аватар для Alegun
Alegun Alegun вне форума
LMD-DML
 
Регистрация: 12.07.2009
Адрес: Богородское
Сообщения: 3,025
Версия Delphi: D7E
Репутация: 1834
По умолчанию

Да нету у вас тупизма, всё нормально Без разницы какие компоненты сохранять, хоть статически созданные ещё во время разработки, хоть динамически появляющиеся в рантайме - смысл такой: сохраняется сразу вся форма, со всеми принадлежащими ей (на момент сэйва) элементами. Запись происходит в формате текстового файла, проще говоря тот же *.ini, только не нужно много букофф выстукивать, всё за нас сделает среда. К сожалению тот пример не сохранился, так что вот вам выжимки из подобного рабочего проекта:

Добавьте в ваш код это
Код:
var
fn: string = 'Form.txt';
procedure TForm1.FormCreate(Sender: TObject);
var
  FStr: TFileStream;
  MemStr: TMemoryStream;
begin
 if FileExists(fn) then
   begin
    Form1.DestroyComponents;
    FStr:= TFileStream.Create(fn, fmOpenRead);
    MemStr:= TMemoryStream.Create;
    ObjectTextToBinary(FStr, MemStr);
    MemStr.Position:= 0;
    MemStr.ReadComponent(Form1);
    MemStr.Free;
    FStr.Free;
   end;
end;
и это
Код:
procedure TForm1.FormDestroy(Sender: TObject);
var
  FStr: TFileStream;
  MemStr: TMemoryStream;
  i: integer;
  begin
  FStr:= TFileStream.Create(fn, fmCreate);
  MemStr:= TMemoryStream.Create;
  MemStr.WriteComponent(form1);
  MemStr.Position:= 0;
  ObjectBinaryToText(MemStr, FStr);
  MemStr.Free;
  FStr.Free;
 end;
Всё, теперь форма будет сохраняться со всем её содержимым и грузиться при старте программы.
С нативными процедурами немного сложнее - они должны быть заданы заранее, но это уже другая песня, нужно этот момент разбирать отдельно и с конкретикой, попробуйте сначала просто сохранку освоить
Ответить с цитированием
Этот пользователь сказал Спасибо Alegun за это полезное сообщение:
Gareth (26.10.2014)
  #5  
Старый 26.10.2014, 04:50
Gareth Gareth вне форума
Активный
 
Регистрация: 21.03.2013
Адрес: Приднестровье
Сообщения: 202
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию

Цитата:
Сообщение от Alegun
Код:
procedure TForm1.FormDestroy(Sender: TObject);
var
  FStr: TFileStream;
  MemStr: TMemoryStream;
  i: integer;
  begin
  FStr:= TFileStream.Create(fn, fmCreate);
  MemStr:= TMemoryStream.Create;
  MemStr.WriteComponent(form1);
  MemStr.Position:= 0;
  ObjectBinaryToText(MemStr, FStr);
  MemStr.Free;
  FStr.Free;
 end;
Всё, теперь форма будет сохраняться со всем её содержимым и грузиться при старте программы.
С нативными процедурами немного сложнее - они должны быть заданы заранее, но это уже другая песня, нужно этот момент разбирать отдельно и с конкретикой, попробуйте сначала просто сохранку освоить
Извиняюсь, вставил код, ругается на переменную i, мол она объявлена, но не используется. Я её удалил, и так же подсвечивается красным строка MemStr.Free;, но никакой ошибки в окошке кода не пишет. Проэкт отказывается компилироваться, выдает окошко с ошибкой "Class TacProvider not found"

Код:
procedure TForm1.FormDestroy(Sender: TObject);
var
  FStr: TFileStream;
  MemStr: TMemoryStream;
  i: integer;
  begin
  FStr:= TFileStream.Create(fn, fmCreate);
  MemStr:= TMemoryStream.Create;
  MemStr.WriteComponent(form1);
  MemStr.Position:= 0;
  ObjectBinaryToText(MemStr, FStr);
  MemStr.Free;  // подсвечивается  красным
  FStr.Free;
 end;

Последний раз редактировалось Gareth, 26.10.2014 в 04:54.
Ответить с цитированием
  #6  
Старый 26.10.2014, 05:05
Аватар для Alegun
Alegun Alegun вне форума
LMD-DML
 
Регистрация: 12.07.2009
Адрес: Богородское
Сообщения: 3,025
Версия Delphi: D7E
Репутация: 1834
По умолчанию

Упс, не заметил переменную i, правильно что выкинули. TacProvider я тоже такого класса не знаю, - видимо какой-то сторонний компонент. У меня это работает без ошибок. А файл Form.txt в директории сборки появился?
Ответить с цитированием
Этот пользователь сказал Спасибо Alegun за это полезное сообщение:
Gareth (26.10.2014)
  #7  
Старый 26.10.2014, 06:16
Gareth Gareth вне форума
Активный
 
Регистрация: 21.03.2013
Адрес: Приднестровье
Сообщения: 202
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию

Цитата:
Сообщение от Alegun
Упс, не заметил переменную i, правильно что выкинули. TacProvider я тоже такого класса не знаю, - видимо какой-то сторонний компонент. У меня это работает без ошибок. А файл Form.txt в директории сборки появился?
Сразу не ответил - проблемы с интернетом были.
Да, Form.txt появился в директории программы.
Я использую в своем проэкте компоненты alphaskins, может проблема(TacProvider) кроется в этом?

Погуглил, оказывается TacProvider, это вроде sSkinProvider из alphaskins. вот тут человек пишет об этом, во втором посте.
Я решил кинуть этот SkinProvider на форму - ничего не изменилось (( что не срачка то болячка

Последний раз редактировалось Gareth, 26.10.2014 в 06:53.
Ответить с цитированием
  #8  
Старый 26.10.2014, 06:27
Аватар для Alegun
Alegun Alegun вне форума
LMD-DML
 
Регистрация: 12.07.2009
Адрес: Богородское
Сообщения: 3,025
Версия Delphi: D7E
Репутация: 1834
По умолчанию

Сейчас повторил ваш вариант создания с массивом панелек (правда нету TsPanel, поэтому тестил обычные) : работает, но только оказалось, что ещё нужно кинуть одну панельку на форму явно (с Visible = false) - отсюда ошибка вылазит, что нет такого класса. Причину пока не нашёл, видимо отсутствует описание этого класса. И удалите txt-файл перед пуском.
Ответить с цитированием
Этот пользователь сказал Спасибо Alegun за это полезное сообщение:
Gareth (26.10.2014)
  #9  
Старый 26.10.2014, 07:10
Gareth Gareth вне форума
Активный
 
Регистрация: 21.03.2013
Адрес: Приднестровье
Сообщения: 202
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию

Цитата:
Сообщение от Alegun
Сейчас повторил ваш вариант создания с массивом панелек (правда нету TsPanel, поэтому тестил обычные) : работает, но только оказалось, что ещё нужно кинуть одну панельку на форму явно (с Visible = false) - отсюда ошибка вылазит, что нет такого класса. Причину пока не нашёл, видимо отсутствует описание этого класса. И удалите txt-файл перед пуском.
Я просто в шоке, проблема за проблемой)))
Спасибо, проблема запуска решилась, но сохранение работает не так. она сохраняет только панели, а то что на панелях, тоже созданное в runtime - нет сохраняет.
И, если создать несколько панелей, потом закрыть программу и открыть вновь, остаются только панели без image, так вот, если начать добавлять еще панели, то они ложаться по верх существующих. А должны появляться ниже, одна за другой)

Последний раз редактировалось Gareth, 26.10.2014 в 07:15.
Ответить с цитированием
  #10  
Старый 26.10.2014, 07:22
Аватар для Alegun
Alegun Alegun вне форума
LMD-DML
 
Регистрация: 12.07.2009
Адрес: Богородское
Сообщения: 3,025
Версия Delphi: D7E
Репутация: 1834
По умолчанию

Добавил динамически на эти панельки всякого-разного хламу типа кнопок, имеджей etc. - оно всё сохраняется на-ура.

З.Ы. Если хотите, то пжлст, через файлообменник типа rghost.ru закиньте мне в личку ваш проект, бум разбираться

З.Ы.З.Ы. Скачал, разбираюсь - но не обещаю, что это быстро будет, нужно время

Последний раз редактировалось Alegun, 26.10.2014 в 07:47.
Ответить с цитированием
Этот пользователь сказал Спасибо Alegun за это полезное сообщение:
Gareth (26.10.2014)
  #11  
Старый 26.10.2014, 07:36
Gareth Gareth вне форума
Активный
 
Регистрация: 21.03.2013
Адрес: Приднестровье
Сообщения: 202
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию

Цитата:
Сообщение от Alegun
Добавил динамически на эти панельки всякого-разного хламу типа кнопок, имеджей etc. - оно всё сохраняется на-ура.

З.Ы. Если хотите, то пжлст, через файлообменник типа rghost.ru закиньте мне в личку ваш проект, бум разбираться
Спасибо вам за помощь!!!
http://rghost.ru/58718050
В архиве 2 папки, первая с alphaskins, вторая с проектом.
Ответить с цитированием
  #12  
Старый 26.10.2014, 12:38
Аватар для Alegun
Alegun Alegun вне форума
LMD-DML
 
Регистрация: 12.07.2009
Адрес: Богородское
Сообщения: 3,025
Версия Delphi: D7E
Репутация: 1834
По умолчанию

Вот что получилось, пришлось от массивов компонентов отказаться из-за "альфашкурки": оно не совместимо, но вроде работает, посмотрите пжлст
Ответить с цитированием
Этот пользователь сказал Спасибо Alegun за это полезное сообщение:
Gareth (26.10.2014)
  #13  
Старый 26.10.2014, 13:02
Gareth Gareth вне форума
Активный
 
Регистрация: 21.03.2013
Адрес: Приднестровье
Сообщения: 202
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию

Цитата:
Сообщение от Alegun
Вот что получилось, пришлось от массивов компонентов отказаться из-за "альфашкурки": оно не совместимо, но вроде работает, посмотрите пжлст
Alegun, вы просто гений))) Огромное спасибо вам! Извлек из данной темы много полезного! Тему можно считать закрытой.
Еще раз спасибо!!!
Ответить с цитированием
  #14  
Старый 26.10.2014, 14:54
Gareth Gareth вне форума
Активный
 
Регистрация: 21.03.2013
Адрес: Приднестровье
Сообщения: 202
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию

Блин)

Ваш код для меня немного необычен.
Я еще создаю компонент TUpDown на каждой панельке. его позицию хочу внести в еще 1 созданный edit, тоже на тех же панелях.
Сделал процедуру Onchanging для TUpDown, и в ней(процедуре) нужно передавать position в edit.
Обычно это edit1.text:= и так далее.. А тут так не получится) Так как нужно обратится к конкретному edit`у, а я не знаю как это сделать. Если бы проект был с массивом, я бы сделал так edit[переменная].text и тд..
Каким образом можно по клику TUpDown передать его position в edit

Вопрос снят! Нужно было еще и с имеджами играться. Понял как)
(Sender as TImage).picture

Не устаю говорить вам спасибо)

Последний раз редактировалось Gareth, 26.10.2014 в 16:17.
Ответить с цитированием
  #15  
Старый 26.10.2014, 16:17
Аватар для Alegun
Alegun Alegun вне форума
LMD-DML
 
Регистрация: 12.07.2009
Адрес: Богородское
Сообщения: 3,025
Версия Delphi: D7E
Репутация: 1834
По умолчанию

Попробуйте бросить один статический апдаун на форму, а дальше примерно так
Код:
...
// при создании 
 with TUpDown.Create(self) do
  begin
  Parent:= tp;
  Name:= 'UpDown'+ IntToStr(nPanel);
  Tag:= nPanel;

  ... // что-то ещё нужно добавить, напр. Left или Top, вам виднее

  OnChanging:= UpDwnChanging;
  end;
вот и эта общая для всех остальных "верхонизов" процедура
Код:
procedure TForm1.UpDwnChanging(Sender: TObject; var AllowChange: Boolean);
var 
 upd: TUpDown absolute Sender;
begin
 (FindComponent('Edit' + IntToStr(upd.Tag)) as TEdit).Text:= Inttostr(upd.Position);
end;
надеюсь, что по образцам других нативок вы сможете это дело прикрутить самостоятельно :-)

З.Ы. Кстати, комбинация UpDown + Edit очень похожа на SpinEdit со вкладки Samples

Последний раз редактировалось Alegun, 26.10.2014 в 18:27. Причина: правка кода
Ответить с цитированием
Этот пользователь сказал Спасибо Alegun за это полезное сообщение:
Gareth (27.10.2014)
Ответ


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 09:54.


 

Сайт

Форум

FAQ

RSS лента

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2023

ВКонтакте   Facebook   Twitter