Проблем с Create на TForm наследник
11 отговора
208 прегледа
Проблем с Create на TForm наследник
Значи имам един обект за визуализиране на форми. Той държи лист с формите и коя как трябва да се показва :
TShow = record
Form: TForm;
FormClass: TFormClass;
Position: TWinPos;
end;
Има метод за добавяне на форми както и един за паказването им. Проблема възниква, когато си пускам една вътрешна процедура за създаване на формата, ако не е създадена (CreatIfNil) (все едно се пуска Application.CreateForm).
Ето каква е последователността...
Значи трябва ми при добавяне на форма да задавам и променливата за достъп до формата. Пример:
AddForm(Form1, TForm1, wpTop);
Тъй като имам няколко форми, с които се занимава обекта за визуализация, ми трябва да ги съхранявам и аз го правя с масив от TShow записи. Но тук явно си изгубвам Form1 като променлива. А на мен ми трябва да мога да си променям от обекта за визуализация. Затова като извикам процедурата CreatIfNil, дава грешка (access violation).
Въпроса ми е как да си държа Form1, Form2 и т.н , така че да мога да ги подавам на CreatIfNil и всичко да работи ок.
ПП Цялата работа е малко замотана и незнам дали успях да опиша добре проблема. Надявам се, че ще има идеи...
by Waz Gaa
[email protected]
TShow = record
Form: TForm;
FormClass: TFormClass;
Position: TWinPos;
end;
Има метод за добавяне на форми както и един за паказването им. Проблема възниква, когато си пускам една вътрешна процедура за създаване на формата, ако не е създадена (CreatIfNil) (все едно се пуска Application.CreateForm).
Ето каква е последователността...
Значи трябва ми при добавяне на форма да задавам и променливата за достъп до формата. Пример:
AddForm(Form1, TForm1, wpTop);
Тъй като имам няколко форми, с които се занимава обекта за визуализация, ми трябва да ги съхранявам и аз го правя с масив от TShow записи. Но тук явно си изгубвам Form1 като променлива. А на мен ми трябва да мога да си променям от обекта за визуализация. Затова като извикам процедурата CreatIfNil, дава грешка (access violation).
Въпроса ми е как да си държа Form1, Form2 и т.н , така че да мога да ги подавам на CreatIfNil и всичко да работи ок.
ПП Цялата работа е малко замотана и незнам дали успях да опиша добре проблема. Надявам се, че ще има идеи...
by Waz Gaa
[email protected]
Re: Проблем с Create на TForm наследник
значи нещо не те разбирам - хем имаш масив, хем имаш и известен брой скалари, като един елемент на масива и един скалар сочат към един и същ обект?
нещо не ми се връзва...
нещото което е удобно за пазене на "масив" от обекти е TObjectList.
обектите който ще пазиш вътре може да са наследници на TForm с едно допълнително поле, TWinPos, което да си ползваш както и където ти трябва. Обръщението към форма е TMyForm(MyObjectList[j]).ShowForm, даречем
Полето TFormClass е излишно, обекта може да си каже всичко по въпроса, без много бой :-)
--------------------------------------
Започва Път от моят праг...
нещо не ми се връзва...
нещото което е удобно за пазене на "масив" от обекти е TObjectList.
обектите който ще пазиш вътре може да са наследници на TForm с едно допълнително поле, TWinPos, което да си ползваш както и където ти трябва. Обръщението към форма е TMyForm(MyObjectList[j]).ShowForm, даречем
Полето TFormClass е излишно, обекта може да си каже всичко по въпроса, без много бой :-)
--------------------------------------
Започва Път от моят праг...
Re: Проблем с Create на TForm наследник
Мда, ще се опитам да се изясня малко.
Значи, трябва ми да държа списък с обектите (променливите) или може би пък указатели към тях, които са от тип там някаква форма. Искам да си създам форма от тяхния тим и след това да им я assign-а.
TFormClass не е излишно защо в началото е сигурно, че променливите ми са nil и ще сбозяса
Да ви питам, може ли да си държа по някакъв начин лист с указатели към променливите (има си по една FormX за всеки TFormX), за да мога по късно да си assign-вам към тях. Пробвах с указатели, но нещо не ми се получи. Ако някой ги разбира, моля да ми обясни как ще стане.
Проблема е, че минавам през много обекти и тяхни методи, та не мога направо да си дам FormX от тип TFormX на някой от тях и да си създам обекта за нея.
Може би така ще прозвучи по-добре: Не искам да работя с нов указател към обект, ами с вече съществуващ (декларираната в unit-а на самия клас променлива), защото всички достъпват до обекта чрез него.
> обектите който ще пазиш вътре може да са наследници на TForm с едно допълнително поле, TWinPos
Не ми е удобно да добавям нови полета. Не ми пречи обаче да си държа един лист (TObjectList) с формите и един масив (елементите си отговарят по индекс) с TWinPos стойностите.
by Waz Gaa
[email protected]
Значи, трябва ми да държа списък с обектите (променливите) или може би пък указатели към тях, които са от тип там някаква форма. Искам да си създам форма от тяхния тим и след това да им я assign-а.
TFormClass не е излишно защо в началото е сигурно, че променливите ми са nil и ще сбозяса
Да ви питам, може ли да си държа по някакъв начин лист с указатели към променливите (има си по една FormX за всеки TFormX), за да мога по късно да си assign-вам към тях. Пробвах с указатели, но нещо не ми се получи. Ако някой ги разбира, моля да ми обясни как ще стане.
Проблема е, че минавам през много обекти и тяхни методи, та не мога направо да си дам FormX от тип TFormX на някой от тях и да си създам обекта за нея.
Може би така ще прозвучи по-добре: Не искам да работя с нов указател към обект, ами с вече съществуващ (декларираната в unit-а на самия клас променлива), защото всички достъпват до обекта чрез него.
> обектите който ще пазиш вътре може да са наследници на TForm с едно допълнително поле, TWinPos
Не ми е удобно да добавям нови полета. Не ми пречи обаче да си държа един лист (TObjectList) с формите и един масив (елементите си отговарят по индекс) с TWinPos стойностите.
by Waz Gaa
[email protected]
Re: Проблем с Create на TForm наследник
жега е, та не вдявам... ама сепак май почвам да... стоплям /на къде повече?!? :-)/
май проблема е от сорта:
имаш декларирани променливи, по обичайния начин, и искаш да ги създаваш динамично, ама мноо динамично...
мхм
--------------------------------------
Започва Път от моят праг...
май проблема е от сорта:
имаш декларирани променливи, по обичайния начин, и искаш да ги създаваш динамично, ама мноо динамично...
мхм
--------------------------------------
Започва Път от моят праг...
Re: Проблем с Create на TForm наследник
Ахъм, и така може да се каже.
Искам да ги подам (променливите) на един клас и той да се грижи, кога да ги създава. А иначе останалия код си ги ползва без да се интересува дали са създадени.
by Waz Gaa
[email protected]
Искам да ги подам (променливите) на един клас и той да се грижи, кога да ги създава. А иначе останалия код си ги ползва без да се интересува дали са създадени.
by Waz Gaa
[email protected]
Re: Проблем с Create на TForm наследник
Така значи.
Да видим дали съм те разбрал.
1. Ти имаш декларирани променливи в унита на всяка форма. (Всъщност декларацията и се записва автоматично в дизайнтиме при File|New|Form
)
2. Формите си ги креатваш динамично, когато ти потрябват. Приемам, че не ги създаваш в *.dpr-а (т.е. в Project|Options|Forms си ги прехвърлил от AutoCreate в Available Forms)
3. При креатването на екземпляр (instance) от някаква форма, ти записваш този екземпляр (м/у нас казано това си е указател) в някаква структура. Такива екземпляри от всеки клас (напр. TForm1) можеш да си създадеш колкото си искаш.
Питам те тогава:
Към кой от екземплярите ти сочи автоматично декларираната променлива (напр. Form1)
Можеш да ми/си отговориш на този въпрос само, ако намериш къде в кода си извършваш присвояване на Form1.
И ако съм те разбрал правилно, това май не става никъде
Извода: Тази автоматична
променлива (Form1), не е инициализирана и можеш да я използваш само за класс функции
Дано да сме се разбрали

Да видим дали съм те разбрал.
1. Ти имаш декларирани променливи в унита на всяка форма. (Всъщност декларацията и се записва автоматично в дизайнтиме при File|New|Form
2. Формите си ги креатваш динамично, когато ти потрябват. Приемам, че не ги създаваш в *.dpr-а (т.е. в Project|Options|Forms си ги прехвърлил от AutoCreate в Available Forms)
3. При креатването на екземпляр (instance) от някаква форма, ти записваш този екземпляр (м/у нас казано това си е указател) в някаква структура. Такива екземпляри от всеки клас (напр. TForm1) можеш да си създадеш колкото си искаш.
Питам те тогава:
Към кой от екземплярите ти сочи автоматично декларираната променлива (напр. Form1)
Можеш да ми/си отговориш на този въпрос само, ако намериш къде в кода си извършваш присвояване на Form1.
И ако съм те разбрал правилно, това май не става никъде
Извода: Тази автоматична
Дано да сме се разбрали
Вместо да гадаем...
Waz публикувай малко код - едва ли е пове4е от 50-60 реда (?)
Другия вариант е да кажеш не решението на проблема ами самия проблем (т.е. това което като цяло искаш да постигнеш) - може да изникнат и други варианти.
---
Е т'ва е живот!
Другия вариант е да кажеш не решението на проблема ами самия проблем (т.е. това което като цяло искаш да постигнеш) - може да изникнат и други варианти.
---
Е т'ва е живот!
Re: Проблем с Create на TForm наследник
>3. При креатването на екземпляр (instance) от някаква форма, ти записваш
>този екземпляр (м/у нас казано това си е указател) в някаква структура.
>Такива екземпляри от всеки клас (напр. TForm1) можеш да си създадеш
>колкото си искаш.
Не, имам само един екземпляр от всяка форма. И не ми трябва да записвам екземпляра в някаква структура, ами в някаква структура да си държа указатели към Form1, Form2 и т.н така че напрамо да си записвам в тях. Това, последното нещо не става.
ОК. Ще пусна и малко код, ако мислите, че ще помогне (Phantom, целия код си е към 200-300 реда
, но така става като приложиш някой и друг pattern + допълнителни обекти.
by Waz Gaa
[email protected]
>този екземпляр (м/у нас казано това си е указател) в някаква структура.
>Такива екземпляри от всеки клас (напр. TForm1) можеш да си създадеш
>колкото си искаш.
Не, имам само един екземпляр от всяка форма. И не ми трябва да записвам екземпляра в някаква структура, ами в някаква структура да си държа указатели към Form1, Form2 и т.н така че напрамо да си записвам в тях. Това, последното нещо не става.
ОК. Ще пусна и малко код, ако мислите, че ще помогне (Phantom, целия код си е към 200-300 реда
procedure TWinMan.CreateIfNil(var AForm; AFormClass: TFormClass);
var
bError: Boolean;
Instance: TComponent;
begin
bError := false;
if not Assigned(TComponent(AForm)) then
try
Instance := TComponent(AFormClass.NewInstance);
TComponent(AForm) := Instance;
Instance.Create(FParentForm);
except
if Assigned(TComponent(AForm)) then
try
TComponent(AForm).Free;
except
bError := true;
end;
TComponent(AForm) := nil;
if bError then
raise ECreateError.Create(Err301)
else
raise ECreateError.Create(Err302);
end;
end;//CreateIfNil
Това е нещо като смесица между
стар код от програмата + Application.CreateForm = това което ми трябва.
Целта e да се създаде форма от даден клас и да се assign-не към подадената променлива.
Как се работи класа с TWinMan. Добавяш му layout-и :
procedure TWinMan.AddLayout(var AForm; AFormClass: TFormClass;
APosition: TWinPos; ADoBeforeShow: TBeforeShowProc);
Пример :
WinMan.AddLayout(frmMyClientForm, TfrmMyClientForm, wpClient, nil);
Като свършиш ги визуализираш :
procedure TWinMan.ShowLayouts;
Именно тук трябва да се извика CreateIfNil на всяка форма.
E, как според вас може да се осъществи това? Декларацията на AddLayout
може би ще претърпи промени. Най-важното е да се подаде променливата за
тази форма и после като се пусне ShowLayouts, WinMan да може да си я
създаде и аssign-не, ако трябва.
by Waz Gaa
[email protected]
Re: Проблем с Create на TForm наследник
Здравей , незнам дали съм те разбрал правилно но все пак ще искажа мнение :)
Според мен кода ти трябжа да изглежда така :
if not Assigned(TComponent(AForm)) then begin
Instance := TComponent(AFormClass.NewInstance);
TComponent(AForm) := Instance;
try
Instance.Create(FParentForm);
//FParentForm, дали си я инициализирал???????
except
// bError = ???? tova sam si go znae6
FreeAndNil(AForm);
if bError then
raise ECreateError.Create(Err301)
else
raise ECreateError.Create(Err302);
end;
end;//CreateIfNil
Освен това за запазжането ето един примерен код които не сам го проверил но би трябвало да работи
TShow = class(TObject)
Form: TForm;
FormClass: TFormClass;
Position: TWinPos;
DoBeforeShow: TBeforeShowProc; //това може да е тук
end;
var FormList : TObjectList;
constructor TWinMan.Create(??);
begin
FormList:=TFormList.Create;
//saotvetno free pri destroy
end;
procedure TWinMan.AddLayout(var AForm; AFormClass: TFormClass;
APosition: TWinPos; ADoBeforeShow: TBeforeShowProc);
var aShow:TShow;
begin
// според мен AForm e по-логично да е само Create а не CreateIfNil, ако ще
// има само по един обект. Но от друга страна ако ще ги създаваш и
//освобождаваш по няколко пъти, тогава си прав.
CreateIfNil(AForm, AformClass);
try
aShow := TShow.Create;
except
//ne6to si
raise
end;
With aShow do begin
Form:= AForm;
FormClass: AFormClass;
Position: APosition;
DoBeforeShow: ADoBeforeShow;
end;
FormList.Add(aShow);
end;
posle pri tarsene pravi6 slednoto
function GetForm(aFormClass:TFormClass):TForm;
var i:integer;
begin
result:=nil;
for i := 0 to FormList.Count -1 do
if TShow(FormList).FormClass = aFormClass then begin
result:=TForm(FormList);
break;
end;
Assert(result <> nil,'Проверката е майка на доверието :)');
end;
//за запазването става и TList но там има повече хамалогия, плюс това TObjectList при Free сам освобождава всички елемнти. От друга страна ще трябва да включиш още един unit , от което програмата ти ще стане малко по-голяма.
Надявам се че сам ти помогнал
Според мен кода ти трябжа да изглежда така :
if not Assigned(TComponent(AForm)) then begin
Instance := TComponent(AFormClass.NewInstance);
TComponent(AForm) := Instance;
try
Instance.Create(FParentForm);
//FParentForm, дали си я инициализирал???????
except
// bError = ???? tova sam si go znae6
FreeAndNil(AForm);
if bError then
raise ECreateError.Create(Err301)
else
raise ECreateError.Create(Err302);
end;
end;//CreateIfNil
Освен това за запазжането ето един примерен код които не сам го проверил но би трябвало да работи
TShow = class(TObject)
Form: TForm;
FormClass: TFormClass;
Position: TWinPos;
DoBeforeShow: TBeforeShowProc; //това може да е тук
end;
var FormList : TObjectList;
constructor TWinMan.Create(??);
begin
FormList:=TFormList.Create;
//saotvetno free pri destroy
end;
procedure TWinMan.AddLayout(var AForm; AFormClass: TFormClass;
APosition: TWinPos; ADoBeforeShow: TBeforeShowProc);
var aShow:TShow;
begin
// според мен AForm e по-логично да е само Create а не CreateIfNil, ако ще
// има само по един обект. Но от друга страна ако ще ги създаваш и
//освобождаваш по няколко пъти, тогава си прав.
CreateIfNil(AForm, AformClass);
try
aShow := TShow.Create;
except
//ne6to si
raise
end;
With aShow do begin
Form:= AForm;
FormClass: AFormClass;
Position: APosition;
DoBeforeShow: ADoBeforeShow;
end;
FormList.Add(aShow);
end;
posle pri tarsene pravi6 slednoto
function GetForm(aFormClass:TFormClass):TForm;
var i:integer;
begin
result:=nil;
for i := 0 to FormList.Count -1 do
if TShow(FormList).FormClass = aFormClass then begin
result:=TForm(FormList);
break;
end;
Assert(result <> nil,'Проверката е майка на доверието :)');
end;
//за запазването става и TList но там има повече хамалогия, плюс това TObjectList при Free сам освобождава всички елемнти. От друга страна ще трябва да включиш още един unit , от което програмата ти ще стане малко по-голяма.
Надявам се че сам ти помогнал
Re: Проблем с Create на TForm наследник
Ами при пробването на няколко варианти и аз стигнах да изваждането на Creat-а в AddLayout (имам направо достъп до променливата, която накрая трябва да е assign-ната). Видях, че пак излиза грешка.
Тогава изкарах един Application.CreateForm(frmMyForm, TfrmMyForm) и направо премахнах употребата на допълнителния обект. Видях , че пак дава грешка. Еми значи проблема е другаде.
Направих си нов и всичко вървеше нормално.
Въпроса е интересен : лист с променливите на формите, които се създават по някое време и се assign-ват, но незнам дали реално ще възникне проблем. Най-вероятно има нещо друго, което се опитва да вземе достъп до променливата, която още не съм прикачил и затова излиза грешката.
Благодаря ви за коментарите. Извинявам се, че съм изгубил част от времето ви, но се видях в чудо с тази грешка.
Поздрави
by Waz Gaa
[email protected]
Тогава изкарах един Application.CreateForm(frmMyForm, TfrmMyForm) и направо премахнах употребата на допълнителния обект. Видях , че пак дава грешка. Еми значи проблема е другаде.
Направих си нов и всичко вървеше нормално.
Въпроса е интересен : лист с променливите на формите, които се създават по някое време и се assign-ват, но незнам дали реално ще възникне проблем. Най-вероятно има нещо друго, което се опитва да вземе достъп до променливата, която още не съм прикачил и затова излиза грешката.
Благодаря ви за коментарите. Извинявам се, че съм изгубил част от времето ви, но се видях в чудо с тази грешка.
Поздрави
by Waz Gaa
[email protected]
Re: Проблем с Create на TForm наследник
Това което ме съмнява е, точно този списък с променливите - не видях явно как го правиш в кода , но имам чуството че бъркаш някъде там - реално те са указатели към обекти - и ти трябва да пазиш не самата променлива ами указател към нея за да я промениш - ако съм разбрал правилно. Това май е най голямата ти разлика от стандартния метод - CreateForm - той си създава формата и assign -ва директно на подадената променлива - докато при теб минаваш през междинна такава - което предизвиква гршката - пробвай да трасираш добре като следиш точно Form1 променливите - декларирани в модулите с формите - за да си сигурен, че не подаваш грешен указател.
---
Е т'ва е живот!
---
Е т'ва е живот!