|
|
Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны |
|
Опции темы | Поиск в этой теме | Опции просмотра |
#1
|
|||
|
|||
Сохранение динамических компонентов
Здравствуйте.
Для своих нужд пишу программу, в ней динамически (runtime) создаются много компонентов, штук 50 панелей, 150 label`ов, 50 edit`ов и тд..в общем не мало компонентов. Вот открыл я прогу, понасоздавал компонентов сколько мне надо, а при следующем открытии их же не будет). Подскажите, коим образом можно это дело сохранить? В начале думал ini, но что-то мне подсказывает, что через ini, это будет жесть... Ранее я уже озвучивал данный вопрос, в этой теме клац, Но мой мозг не совсем понял) разжуйте пожалуйста. Последний раз редактировалось Gareth, 25.10.2014 в 13:27. |
#2
|
||||
|
||||
А что, сохранение через потоковый WriteComponent вам не подходит разве?
Тогда действительно, при завершении работы сборки можно всё сохранить в ini-файле, посредством циклического перебора компонентов на форме, их класс, размер, позицию, название etc., гимора особого не будет, поскольку это всё автоматом происходит, а при старте по этим данным их воссоздавать - проблема лишь в динамически подключаемых процедурах обработки сообщений, но это тоже не очень сложно, при грамотной разработке их содержимого, и если не ошибаюсь, то пример подобного я вам уже приводил ранее Я не понял Вашего вопроса, но всё же Вам на него отвечу! |
Этот пользователь сказал Спасибо Alegun за это полезное сообщение: | ||
Gareth (26.10.2014)
|
#3
|
|||
|
|||
Цитата:
Есть несколько нюансов, которые я не могу понять, а проэкт уже удален с файлообменника, да и у меня его нету уже. Почитал про 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
|
||||
|
||||
Да нету у вас тупизма, всё нормально Без разницы какие компоненты сохранять, хоть статически созданные ещё во время разработки, хоть динамически появляющиеся в рантайме - смысл такой: сохраняется сразу вся форма, со всеми принадлежащими ей (на момент сэйва) элементами. Запись происходит в формате текстового файла, проще говоря тот же *.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
|
|||
|
|||
Цитата:
Код:
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
|
||||
|
||||
Упс, не заметил переменную i, правильно что выкинули. TacProvider я тоже такого класса не знаю, - видимо какой-то сторонний компонент. У меня это работает без ошибок. А файл Form.txt в директории сборки появился?
Я не понял Вашего вопроса, но всё же Вам на него отвечу! |
Этот пользователь сказал Спасибо Alegun за это полезное сообщение: | ||
Gareth (26.10.2014)
|
#7
|
|||
|
|||
Цитата:
Да, Form.txt появился в директории программы. Я использую в своем проэкте компоненты alphaskins, может проблема(TacProvider) кроется в этом? Погуглил, оказывается TacProvider, это вроде sSkinProvider из alphaskins. вот тут человек пишет об этом, во втором посте. Я решил кинуть этот SkinProvider на форму - ничего не изменилось (( что не срачка то болячка Последний раз редактировалось Gareth, 26.10.2014 в 06:53. |
#8
|
||||
|
||||
Сейчас повторил ваш вариант создания с массивом панелек (правда нету TsPanel, поэтому тестил обычные) : работает, но только оказалось, что ещё нужно кинуть одну панельку на форму явно (с Visible = false) - отсюда ошибка вылазит, что нет такого класса. Причину пока не нашёл, видимо отсутствует описание этого класса. И удалите txt-файл перед пуском.
Я не понял Вашего вопроса, но всё же Вам на него отвечу! |
Этот пользователь сказал Спасибо Alegun за это полезное сообщение: | ||
Gareth (26.10.2014)
|
#9
|
|||
|
|||
Цитата:
Спасибо, проблема запуска решилась, но сохранение работает не так. она сохраняет только панели, а то что на панелях, тоже созданное в runtime - нет сохраняет. И, если создать несколько панелей, потом закрыть программу и открыть вновь, остаются только панели без image, так вот, если начать добавлять еще панели, то они ложаться по верх существующих. А должны появляться ниже, одна за другой) Последний раз редактировалось Gareth, 26.10.2014 в 07:15. |
#10
|
||||
|
||||
Добавил динамически на эти панельки всякого-разного хламу типа кнопок, имеджей etc. - оно всё сохраняется на-ура.
З.Ы. Если хотите, то пжлст, через файлообменник типа rghost.ru закиньте мне в личку ваш проект, бум разбираться З.Ы.З.Ы. Скачал, разбираюсь - но не обещаю, что это быстро будет, нужно время Я не понял Вашего вопроса, но всё же Вам на него отвечу! Последний раз редактировалось Alegun, 26.10.2014 в 07:47. |
Этот пользователь сказал Спасибо Alegun за это полезное сообщение: | ||
Gareth (26.10.2014)
|
#11
|
|||
|
|||
Цитата:
http://rghost.ru/58718050 В архиве 2 папки, первая с alphaskins, вторая с проектом. |
#12
|
||||
|
||||
Вот что получилось, пришлось от массивов компонентов отказаться из-за "альфашкурки": оно не совместимо, но вроде работает, посмотрите пжлст
Я не понял Вашего вопроса, но всё же Вам на него отвечу! |
Этот пользователь сказал Спасибо Alegun за это полезное сообщение: | ||
Gareth (26.10.2014)
|
#13
|
|||
|
|||
Цитата:
Еще раз спасибо!!! |
#14
|
|||
|
|||
Блин)
Ваш код для меня немного необычен. Я еще создаю компонент 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
|
||||
|
||||
Попробуйте бросить один статический апдаун на форму, а дальше примерно так
Код:
... // при создании 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)
|