Страница 2 из 2
Добавлено: 19 ноя 2005, 01:03
Игорь Акопян
Код: Выделить всё
When you call Free for a component, it calls Free for all components that it owns, that is, all components in its component list.
Т.о. если компонент был создан к примеру так:
Код: Выделить всё
procedure TMyButton.Click(Sender: TObject);
begin
with TBevel.Create(MyPanel) do
begin
...
end;
end;
то экземпляр класса TBevel добавляется в коллекцию Components объекта MyPanel, и при вызове MyPanel.Free будет корректно убит.
Если же код такой:
Код: Выделить всё
procedure TMyButton.Click(Sender: TObject);
begin
with TBevel.Create(nil) do
begin
...
end;
end;
Тады освобождать придётся вручную
Добавлено: 19 ноя 2005, 09:43
Blood_Magic
создаю:
Код: Выделить всё
Result:=TPanel.Create(pnButton);
With Result do
begin
Name:='BrowserButton'+IntToStr(pnButton.ComponentCount);
Parent:=pnButton;
Caption:=ButtonCaptions[I];
BevelOuter:=bvNone;
Color:=$DEDEDE;
Top:=0;
Height:=ButtonHeight;
Width:=MinButtonWidth;
ShowHint:=True;
PopupMenu:=ButtonPopupMenu;
OnMouseDown:=BrowserButtonMouseDown;
Tag:=pnButton.ComponentCount;
end;
sp:=TShape.Create(Result);
With sp do
begin
Name:='ShapeBrowserButton'+IntToStr(pnButton.ComponentCount);
Parent:=Result;
Brush.Style:=bsClear;
Align:=alClient;
end;
If pnButton.ComponentCount>1 then
begin
im:=TImage.Create(Result);
With im do
begin
Name:='imCloseButtonBrowserButton'+IntToStr(pnButton.ComponentCount);
Parent:=Result;
Transparent:=True;
imCloseButtons.GetBitmap(0,im.Picture.Bitmap);
AutoSize:=True;
Left:=sp.Width-Width-Delta-1;
Top:=(sp.Height-Height) shr 1;
Anchors:=[akTop,akRight];
OnMouseClick:=imCloseButtonClick;
end;
end;
Убиваю:
Код: Выделить всё
//Обрабботка нажатия на Image
procedure Tfm.imCloseButtonClick(Sender: TObject);
begin
TImage(Sender).Parent.Free;
end;<<------ Ошибка после выполнения этой строки
В результате ошибка при выходе из процедуры, сама строка TImage(Sender).Parent.Free; выполняется нормально, причем все убивается хорошо.
Добавлено: 21 ноя 2005, 14:29
Игорь Акопян
блин... вот она лень-матушка... до конца то я не дочитал... сорри
Warning: Never explicitly free a component within one of its own event handlers or free a component from the event handler of a component it owns or contains. For example, don’t free a button in its OnClick event handler or free the form that owns the button from the button's OnClick event.
Добавлено: 21 ноя 2005, 16:16
Blood_Magic
кто знает что делать?
Добавлено: 21 ноя 2005, 17:15
Eugie
Попробуй так:
Код: Выделить всё
PostMessage((Sender as TImage).Parent.Handle, WM_CLOSE, 0, 0);
Добавлено: 25 ноя 2005, 20:43
Blood_Magic
Eugie писал(а):Попробуй так:
Код: Выделить всё
PostMessage(][/quote]
Мне надо именно уничтожить. То что Вы написали это (Sender as TImage).Parent.Visible:=Flase;
Добавлено: 25 ноя 2005, 21:51
Eugie
Тогда такой вариант:
Код: Выделить всё
const WM_MYDESTROYPANEL = WM_USER + $100;
procedure TForm1.Image1Click(Sender: TObject);
begin
PostMessage(Self.Handle, WM_MYDESTROYPANEL, 0, 0);
end;
procedure TForm1.WndProc(var Message: TMessage); // ! override !
begin
if WM_MYDESTROYPANEL = Message.Msg then
Image1.Parent.Free
else
inherited;
end;
Суть в том, чтобы развести по времени запрос на удаление и само уничтожение родительского контрола, т.е. вынести из обработчика Image1Click() - там некорректно.
Добавлено: 25 ноя 2005, 23:53
Blood_Magic
уряяяяяяяяяяяя! спасибо что натолкнул на мысль! это проще делается но смысл тот же:
Код: Выделить всё
const
WM_DestroyPanelButton = WM_USER + $200;
....................
private
procedure DestroyPanelButton(var Msg: TMessage); message WM_DestroyPanelButton;
.....................
procedure Tfm.DestroyPanelButton(var Msg: TMessage);
begin
Image1.Parent.Free;
end;
в этом случаи никакого override не надо и inherited не надо