6>У меня есть панель на ней з edit'a и button. 6>Хочу эту штуку отдельным классом сделать 6>Помогите сделать конструктор и деструктор ко всей єтой фигне... плз..
constructor Texample.Create(AOwner:TComponent);
begin
inherited;
Button1:=TButton.Create(self); //Владелец - наша панельwith Button1 do
begin
Parent:=self;
BoundsRect:=Rect(...); //координаты контрола и его размер
Caption:='MyButton';
//Еще не мешало бы Name установить, но я не в курсе, как сгенерировать уникальное имя
//Впрочем, это, как правило, не нужно, если не используется поиск компонента по имени
//или сохранение объекта в потокend;
//Такая же ерунда для edit'овend;
Деструктор можно не переписывать: так как наша панель — владелец этих контролов, то они автоматически уничтожаются при уничтожении панели.
6>и вообще верно то , что я предком указал Tpanel ?
Ну, это зависит от того, как тебе удобнее ее использовать. Если везде, где может использоваться панель, то тогда наследуйся от панели. Если же нужно, чтобы объекты этого нового класса можно было использовать везде, где используется некий твой собственный класс TMyObject, который от панели не отнеследован, то рекомендую создать для TExample И TMyObject общего предка (т.е. чтобы оба наследовались от него), а в TExample тогда придется еще и саму панель, на которой кнопки лежат, внести. Или вместо общего предка можно в обоих классах реализовать один и тот же общий interface (пусть даже при этом TExample все еще наследуется от TPanel), а общую обработку для TExample и TMyData организовывать через этот inteface (например, array [1..10] of IMyCommonInterface).
Slicer
Специалист — это варвар, невежество которого не всесторонне :)
Здравствуйте, Slicer [Mirkwood], Вы писали:
SM>constructor Texample.Create(AOwner:TComponent);
.. SM> Parent:=self;
Вообще, так не очень здорово.
IMHO, такое лучше делать где-нибудь в SetParent; override.
SM>Деструктор можно не переписывать: так как наша панель — владелец этих контролов, то они автоматически уничтожаются при уничтожении панели.
Даже если у них не будет Owner, то их уничтожит Parent.
6>>и вообще верно то , что я предком указал Tpanel ? SM>Ну, это зависит от того, как тебе удобнее ее использовать. Если везде, где может
Если нужна граница — TPanel/TGroupBox, иначе — TWinControl
Здравствуйте, Leonid Troyanovsky, Вы писали:
SM>>constructor Texample.Create(AOwner:TComponent); LT>.. SM>> Parent:=self; LT> Вообще, так не очень здорово. LT> IMHO, такое лучше делать где-нибудь в SetParent; override.
1) Почему?
2) Тогда SetBounds тоже придется делать в SetParent. То есть до SetParent я не смогу опросить Bounds и еще много чего сделать.
LT> Даже если у них не будет Owner, то их уничтожит Parent.
Вот за это спасибо!
Никогда бы не подумал, но
destructor TWinControl.Destroy;
var
I: Integer;
Instance: TControl;
begin
Destroying;
if Parent <> nil then RemoveFocus(True);
if FHandle <> 0 then DestroyWindowHandle;
I := ControlCount;
while I <> 0 do
begin
Instance := Controls[I - 1];
Remove(Instance);
Instance.Destroy;
I := ControlCount;
end;
FBrush.Free;
if FObjectInstance <> nil then FreeObjectInstance(FObjectInstance);
inherited Destroy;
end;
А исключение двойного удаления родителем и владельцем — через destructor TComponent.Destroy;
Slicer
Специалист — это варвар, невежество которого не всесторонне :)
Здравствуйте, Slicer [Mirkwood], Вы писали:
SM>>>constructor Texample.Create(AOwner:TComponent); LT>>.. SM>>> Parent:=self; LT>> Вообще, так не очень здорово. LT>> IMHO, такое лучше делать где-нибудь в SetParent; override. SM>1) Почему?
Скажем, потому, что контролы иногда создают с Owner = nil.
Или, представим, что в дизайнтайм мы сначала разместили его на TWinControl,
а затем переместив его куда-либо, удаляем этот TWinControl.
SM>2) Тогда SetBounds тоже придется делать в SetParent. То есть до SetParent я не смогу опросить Bounds и еще много чего сделать.
А почему бы и не сделать?
Некоторые вещи иногда приходится делать даже, скажем, в CreateWnd или CreateParams.
Конечно, вместо локальных переменных для контролов, видимо, потребуются (приватные)
поля, но, вполне вероятно, что они и еще для чего-нибудь пригодятся.
--
С уважением, LVT
--
С уважением, LVT
Re[5]: классы: конструктор и деструктор
От:
Аноним
Дата:
30.11.03 21:16
Оценка:
Здравствуйте, Leonid Troyanovsky, Вы писали:
Не понял Вашей аргументации на счет
constructor Texample.Create(AOwner:TComponent);
begin
...
Button1:=TButton.Create(self); //Владелец - наша панельwith Button1 do
beginParent:=self;
...
end;
...
end;
SM>>1) Почему? LT> Скажем, потому, что контролы иногда создают с Owner = nil.
Ну и что??? Чему это противоречит?
Если у панели нет Owner'a, то чем это может помешать ей стать Parent'ом?
LT> Или, представим, что в дизайнтайм мы сначала разместили его на TWinControl, LT> а затем переместив его куда-либо, удаляем этот TWinControl.
???
Если этот TWinControl имеет флаг csAcceptsControls (т.е. способен стать родителем),
то переместить переместить наш компонент за его пределы не удастся.
И при уничтожении TWinControl наш компонент благополучно уничтожится со
своим парентом и уничтожит свои дочерние компоненты.
Тут есть другой момент.
При создании TExample окно не создаётся.
И при создании Button1 окно тоже не создаётся.
Тем не менее TExample в своём конструкторе способен стать
парентом Button1.
Окно создаётся про только обращении к Handle —
function TWinControl.GetHandle: HWnd;
begin
HandleNeeded;
Result := FHandle;
end;
procedure TWinControl.HandleNeeded;
begin
if FHandle = 0 then
begin
if Parent <> nil then Parent.HandleNeeded;
// Для CreateHandle, точнее CreateWnd требуется,
// чтобы парент уже имел Handle. До этого момента парент контрола вполне имеет право не иметь его
//Но если при этом у самого парент в CreateParams Params.ParentWnd = 0, то будет эксепшн.
//Грубо говоря, если каждый парент должен иметь своего парента.
//Этот замкнутый круг заканчивается на TCustomForm,
//которая устанавливает Params.WndParent := Application.Handle;
//или на контроле, созданном через CreateParented
CreateHandle;
end;
end;
Что всё это значит? —
То, что мы имеем полное право
в конструкторе TExample установить Button1.Parent := Self;
Тем не менее, не смотря на то, что у Button1 теперь есть парент,
мы не можем обращаться к тем методам кнопки, которые вызовут GetHandle,
до тех пор, пока TExample сам не получит парента.
Для кнопки я что-то сразу таких методов не припомню
(упоминаемый SetBoundsRect к ним не относится, по крайней мере
в моей версии Дельфи)
Но для ListBox'а, например, нельзя обращяться к Items.
Здравствуйте, Аноним, Вы писали:
LT>> Скажем, потому, что контролы иногда создают с Owner = nil.
А>Если у панели нет Owner'a, то чем это может помешать ей стать Parent'ом?
LT>> Или, представим, что в дизайнтайм мы сначала разместили его на TWinControl, LT>> а затем переместив его куда-либо, удаляем этот TWinControl.
А>??? А>Если этот TWinControl имеет флаг csAcceptsControls (т.е. способен стать родителем), А>то переместить переместить наш компонент за его пределы не удастся. А>И при уничтожении TWinControl наш компонент благополучно уничтожится со А>своим парентом и уничтожит свои дочерние компоненты.
Согласен, моя аргументация не к месту.
А>Тут есть другой момент.
А>При создании TExample окно не создаётся.
..
Возможно, что именно это и побудило меня говорить о "не есть хорошо".
Свои же доводы беру назад, sorry.
Здравствуйте, Diouzshev, Вы писали:
D>А не проще ли эдиты и кнопку на фрейм покидать? Будет тебе класс — наследник от TFrame
D>Или тебе компонент все таки нужен?
не знаю , я с ООП только начинаю разбираться , поэтому и спрашиваю ,..
Задача такова..
Есть БД, предприятия и их магазины... склад — мастер-таблица,магазины — подчиненные...
Если в предприятие нужно добавить ещё один магазин (их может быть N шутук),
появляется форма для заполнения данных о магазине ...
Вот я и хочу сделать эту форму для заполнения отдельным классом ...
А действовать это будет так : если на вопрос "Сколько магазинов у предприятия" вы отвечаете "5",
то создаются 5 потомков этого класса и располагаются на форме
Hello, 6str!
You wrote on Wed, 03 Dec 2003 09:19:10 GMT:
s> Задача такова..
s> Есть БД, предприятия и их магазины... склад — мастер-таблица,магазины s> — подчиненные...
s> Если в предприятие нужно добавить ещё один магазин (их может быть N s> шутук), появляется форма для заполнения данных о магазине ...
s> Вот я и хочу сделать эту форму для заполнения отдельным классом ...
s> А действовать это будет так : если на вопрос "Сколько магазинов у s> предприятия" вы отвечаете "5", то создаются 5 потомков этого класса s> и располагаются на форме
TDBCtrlGrid спасет отца русской демократии.
Замечу только, что, на мой взгляд, лучше делать малость по другому:
В верхней части формы группа контролов в которой можно редактировать данные предприятия,
в нижней Grid с магазинами, магазины добавлять-редакт. прямо в гриде или при добавлении-редакт. выводить модальную форму.