Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2002.08.29;
Скачать: [xml.tar.bz2];

Вниз

Помогите разобраться   Найти похожие ветки 

 
Андрусь   (2002-08-13 20:34) [0]

Привет всем ещё раз!Такая вот непонятка:есть 2 переменные
var1,var2:TMyObject;Нужно сделать так,чтобы можно было работать с var1, выделяя память var2.Когда мы работаем с var1 о var2 не знаем. При работе с var2 нам известен указатель на var1. Может немного путано,сейчас поясню как делал я - может чего прояснится. Я рассуждал так:переменная var1 есть указатель на адрес А1,я пихаю эту переменную в List:TList - массив указателей;Затем читаю из List - var2:=List[0];Сейчас я думаю,что var1 и var2 казывают на А1,выделяю память var2:=MyObject.Create; Далее хочу обратиться к var1,думая что адрес,на который он указывает проинициализирован....
Что я делаю неправильнобо не работает).Зараннее всем благодарен.


 
TTCustomDelphiMaster   (2002-08-13 20:59) [1]

Андрусь © (13.08.02 20:34)
Все работает без проблем. Скорее всего ты так упростил описание проблеммы, что ошибка то сюда и не попала.


 
Юрий Зотов   (2002-08-13 21:48) [2]

После

var2 := TMyObject.Create // именно TMyObject

переменная var2 меняет свое значение - теперь она указывает на адрес в динамической памяти, по которому разместился только что созданный объект. А переменная var1 и элемент массива List[0] остались прежними. Вы же их не меняли? Нет. А сами меняться они не могут, они не волшебные.

Вообще, зачем такие накрутки? Какие-то var1, var2 - зачем они нужны? Почему не написать просто List[0] := TMyObject.Create и спокойно работать с массивом, без всяких лишних переменных. В чем изначальная задача?


 
Андрусь   (2002-08-14 11:03) [3]

Как это говорится - хочешь как проще,а получается как всегда :-{
Чего я хотел сделать - есть МДИ с подгружаемыми пакетами(я уже не раз про эту штуку спрашивал). Переменная MyForm(var1) - переменная, объявленная в модуле,который в пакете,BaseForm(var2(TMyForm=class(TBaseForm)) ) - переменная, объявленная в главном модуле(делаю всё по примеру со статьи про подгружаемые пакеты из "Королевства Дельфи"). При подгрузке пакета(секция initialization) в манагер классов(TList)загоняю класс и переменную MyForm:

initialization
Begin
ClassManager.Add(MyForm);
ClassManager.Add(TMyForm);
End;

В главном модуле хочу проинициализировать переменную MyForm через BaseForm.

Procedure TMainForm.MakeFormFromPackage(PackageName:string);
var BaseFormClass: TComponentClass;
BaseForm: TBaseForm;
PackageHandle : HMODULE;
begin
PackageHandle := LoadPackage(PackageName);
BaseFormClass := ClassManager[ClassManager.Count-1];
BaseForm := ClassManager[ClassManager.Count-2];
Application.CreateForm(BaseFormClass,BaseForm);
end;

В самом подгружаемом пакете есть ещё модули,в которых идёт обращение к MyForm. При просмотре под дебагером - там nil. Так вот чё я делаю не так и как исправить ситуацию.Зараннее всем балгодарен.


 
Андрусь   (2002-08-14 13:36) [4]

Товарищи,что сразу в кусты...


 
Андрусь   (2002-08-14 20:44) [5]

Алё...


 
Андрусь   (2002-08-14 21:13) [6]

Тут ошибку просёк - у меня var1 указывает в никуда. Я его в List, затем присваиваю пустой var2,инициализирую var2. И пытаюсь обратиться к var1,которая в nil.


 
Юрий Зотов   (2002-08-15 01:17) [7]

Насколько я понял, ClassManager - это TList. То есть, при подгрузке пакета фактически выполняется TList.Add(MyForm).

Хорошо, а чему же в этот момент равна переменная MyForm? Она глобальная, поэтому компилятор проинициализировал ее nil"ом и после этого ее никто не менял. В итоге - при подгрузке пакета мы добавили в список указатель с номером Count-2 и со значением nil. Сама переменная MyForm тоже осталась равной nil. ОК, запомним это и пойдем дальше.

А дальше непонятно зачем идет строка
BaseForm := ClassManager[ClassManager.Count-2];

Почему "непонятно зачем"? Потому что сразу за ней идет строка
Application.CreateForm(BaseFormClass,BaseForm);
которая, если сработает нормально, должна создать форму и поместить ее адрес в BaseForm. Тогда зачем нужна предыдущая строка? А ни зачем, ее можно просто убрать, и ничего не изменится. ОК, идем еще дальше.

Предположим, что все прошло нормально, форма создалась и в локальной переменной BaseForm теперь сидит ее адрес. А изменилась ли при этом переменная MyForm?

Нет. С какой такой радости она должна была измениться? Как там был nil, так он и остался. Что и показывает дебаггер.

Хорошо, а изменился ли элемент списка под номером Count-2?

Тоже нет. С какой такой радости он должен был измениться? Как там был все тот же nil, так он же и остался.

ОК, идем дальше.

А дальше мы выходим из процедуры MakeFormFromPackage и переменная BaseForm исчезает. Вместе с ней исчезает и единственная имеющаяся у нас ссылка на созданную форму (если не считать списка Application.Components). Почти приплыли - теперь, чтобы работать с этой формой надо снова искать ссылку на нее.

Разве этого Вы хотели? Думаю, что нет.

Вот пример.
var
A, B, C: integer;
begin
A := 0;
B := A; // Теперь B=0
C := A; // Теперь C=0
A := 5; // Чему теперь равны B и C?
end;

И Вы скажете: "Как были равны 0, так и остались, их же никто не менял, а сами они меняться не умеют, они не волшебные".

Хорошо, теперь представьте, что A, B и С имеют тип Pointer, а 0 и 5 - это адреса в памяти (причем 0=nil). Разве от этого что-то изменилось?

Ничего. Переменные не умеют меняться сами по себе, хоть они integer, хоть pointer. Изменив A, мы меняем только A, а B и C остаются прежними. Так почему же Вы, получив адрес формы в переменной BaseForm считаете, что он теперь должен содержаться и в переменной MyForm, и в элементе списка Count-2? Откуда он там возьмется?


> чё я делаю не так

Увы, практически все (см. выше).


> и как исправить ситуацию

Самое лучшее - на время забыть о классах и объектах и написать несколько учебных программ на тему "указатели и динамическая память". Нужно досконально разобраться с New и Dispose, GetMem и FreeMem, с типизированными и нетипизированными указателях.

А потом вернуться к объектам и понять, что работа с ними - это, по сути, та же самая работа с типизированными указателями и динамической памятью. Что MyForm - это аналог pointer, Create - аналог New/GetMem, а Free - аналог Dispose/FreeMem.

И исчезнут все вопросы. Кстати, и насчет PChar тоже, если они были.


 
Андрусь   (2002-08-15 12:58) [8]

>Юрий Зотов!
Спасибо за лекцию,но это я и сам понял,я просил помочь с решением, а не читать нотации....
Извините,если слишком резко.


 
Юрий Зотов   (2002-08-15 15:03) [9]

> я просил помочь с решением

С решением ЧЕГО? Чтобы предложить решение, надо знать задачу.
С самого начала я именно это и спрашивал - В ЧЕМ ИСХОДНАЯ ЗАДАЧА? Простыми русскими словами - ЧТО ВЫ ХОТИТЕ СДЕЛАТЬ

Только не надо про пакеты и переменные. Они относятся уже не к задаче, а к ее реализации.


> а не читать нотации....

Где Вы нашли нотации? Вы просили указать (цитирую) "чё я делаю не так". Я указал, конкретно и подробно. Между прочим, потратив на это совсем не 3 минуты своего времени. И что получил в ответ? Хорошо хоть, что извинились, и на том спасибо.


 
Андрусь   (2002-08-15 17:44) [10]

Извините,мастер,ещё раз,но то о чём вы писали я понял сам,а если насчет исходной задачи - чё хочу сделать:
нужно сделать приложение,ипользуя интерфейс МДИ. Далее желательно,чтобы приложение,будучи установлено у заказчика могло легко переживать небольшие апгрейды на уровне дочерних форм(логично использовать пакеты).Далее переходим уже к реализации.


 
Игорь Шевченко   (2002-08-15 17:53) [11]

http://www.delphikingdom.com/mastering/plugins.htm


 
Андрусь   (2002-08-15 18:01) [12]

>Игорь Шевченко ©
CСпасибо,большое. Внимательнее читайте,изложенное выше(Андрусь © (14.08.02 11:03),3-я строка).Извините,если нагрубил опять.


 
Игорь Шевченко   (2002-08-15 18:12) [13]

Мы же вроде раньше долго и плодотворно беседовали на эту тему...?


 
Юрий Зотов   (2002-08-15 19:37) [14]

Вот это другое дело, в ближайшие дни попробую набросать простой пример (простой - это чтобы не маскировать суть деталями). Только нужно еще немного информации.

1. Я правильно понял, что главная проблема - создание, показ и работа с дочерними формами, хранящимися в BPL?

2. Все дочерние формы - одного класса, или разных? Если второе, то допустима ли иерархия классов дочерних форм (когда все они разные, но все - потомки одного базового класса)?


 
Андрусь   (2002-08-15 20:07) [15]

Юрий,большое вам спасибо,что на меня не обижаетесь.
1 - да.
2 - все формы в пакетах идут от TBaseForm,о котором знает главная форма.
P.S. Может не стоит засорять "эфир",а по мылу.
Всё равно пасибо. Приятно иметь дело с понимающим человеком.


 
IronHawk   (2002-08-15 22:32) [16]


> Андрусь © (15.08.02 20:07)

Узнаю стиль .....


 
Андрусь   (2002-08-16 11:18) [17]

А в чём проблемы то...


 
Юрий Зотов   (2002-08-16 19:12) [18]

Еще несколько уточняющих вопросов.

1. Как планируется осуществлять эти "небольшие апгрейды на уровне дочерних форм"? Допускается ли такой вариант - старый файл BPL просто заменяется новым, в котором зашита форма того же самого класса, что и в старом, но уже с обновленной функциональностью. Если планируется иной вариант апгрейда, то какой именно?

2. MDI-форма знает только класс TBaseForm, или ей известен ВЕСЬ набор классов дочерних форм (и имен их пакетов). Если весь набор классов и весь состав пакетов заранее неизвестен, то допускается ли их формирование, скажем, по составу BPL, лежащих в заранее определенном каталоге?

3. Предположим, в какой-то момент работы MDI-форме потребовалось создать дочернюю форму. Ее класс заранее известен? Если нет, то по каким признакам может быть определен этот нужный в данный момент класс?



 
Юрий Зотов   (2002-08-18 15:03) [19]

Обещанный пример лежит в кладовке.
http://delphi.mastak.ru/download/other.html

На последние три уточняющих вопроса пришлось отвечать самому себе. Я сделал это так.

1. Да, такой вариант допускается.
2. MDI-форма знает только класс TBaseForm. Все плагины лежат в отдельном и заранее известном подкаталоге.
3. Класс создаваемой формы выбирается юзером в диалоговом окошке (поскольку для примера сгодится и такой вариант).



Страницы: 1 вся ветка

Форум: "Основная";
Текущий архив: 2002.08.29;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.51 MB
Время: 0.007 c
14-95974
FLIZ_
2002-08-05 13:32
2002.08.29
Чем просмотреть *.WMV файлы?


1-95746
Kif
2002-08-16 20:14
2002.08.29
Как программно узнать длину (в пикселях) Sys Tray’а?


3-95713
oleg_d
2002-08-09 11:31
2002.08.29
Результат запроса в DBGrid


14-95977
daan_m
2002-08-05 12:41
2002.08.29
WinAPI для WinXP


1-95857
lensky
2002-08-17 20:02
2002.08.29
Algoritm proverki povtorov





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский