Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Незакрываються динамически созданные Panel [Win2k, WinXP]


Страницы:   1 2

OlegM ©   (2007-08-07 14:37:00) 

Привет всем
Есть форма, на ней динамически создаются TPanel, и на каждой из них TButton, в которую на событие OnClick вешаеться код

(Form1.Components[i] as TPanel).Free;

Но иногда все работает, иногда выдает Abstract Error иногда выдает
Ассес вилатион. Подскажите как правильно закрывать динамически созданные компоненты.


OlegM   (2007-08-09 12:29:00) [1]

Ой люди спасибо огромное за терпение и помощь, все работает )


Юрий Зотов   (2007-08-09 12:24:00) [2]

> OlegM   (09.08.07 12:20) [23]

Перед словом type. Только лучше напишите WM_USER+ 100.


OlegM   (2007-08-09 12:20:00) [3]

> Юрий Зотов , сенк.

Только не бейте )


type
 TForm1 = class(TForm)
   ...
   procedure DelPanel(var mes: TMessage); message DEL_PAN ;
 private
   { Private declarations }
 public
   { Public declarations }
 end;

const DEL_PAN = WM_USER+1;


Куда эту константу вписать ???


Юрий Зотов   (2007-08-09 11:56:00) [4]

PostMessage( (Sender as TButton).Handle, ...

Вы сообщение КОМУ должны послать? Тому, кто его примет, поймет и обработает. Все это делает ФОРМА (потому что обработчик сообщения - это метод ФОРМЫ). А сообщение Вы почему-то посылаете КНОПКЕ.

Выкиньте подчеркнутый кусок. Хэндл ФОРМЫ, а не КНОПКИ надо указывать.


MetalFan   (2007-08-09 11:47:00) [5]

в интерфейсной части класса укажи
> procedure DelPanel(var mes: TMessage); message DEL_PAN;


OlegM   (2007-08-09 11:38:00) [6]

> Юрий Зотов
Дак конешно все это читал но очень давно. последние несколько лет только с базами.

Но что то опять я туплю короче.

это объявлено в глобальных
const
 DEL_PAN = WM_USER+1;

Так описано процедурка
procedure TForm1.DelPanel(var mes: TMessage);
begin
 TPanel(mes.WParam).Free;
end;

Такое я посылаю
PostMessage((Sender as TButton).Handle, DEL_PAN, Integer((Sender as TWInControl).Parent), 0);

Но ничего не происходит


sergeyst   (2007-08-09 10:19:00) [7]


> Юрий Зотов ©   (09.08.07 09:59) [18]

Ага, спасибо, ясно.


Юрий Зотов   (2007-08-09 09:59:00) [8]

> OlegM   (09.08.07 08:35) [16]
TPanel(mes.WParam).Free;

Олег, Вы бы посмотрели все же в справке, что такое сообщения...

> sergeyst ©   (09.08.07 09:36) [17]

Если в цепочке обработки события не происходит обращения к полям уничтоженного объекта (и тех, которые уничтожаются вместе с ним), то AV, естественно, не будет. Если происходит - будет. Зависит это от и кода VCL, и от прикладного кода  (мы же не знаем, что там еще и на какие события навешено). В любом случае правильным будет отложенное удаление (через PostMessage), которое гарантирует, что перед удалением обработка события будет завершена. Для примера посмотрите метод Release формы (его код и описание в справке).

PS
Хотя я потихоньку начинаю подозревать, что эта ошибка была далеко не единственной и даже не главной.


sergeyst   (2007-08-09 09:36:00) [9]


> Обработчик щелка по кнопке уничтожает панель, на которой
> лежит ЭТА САМАЯ кнопка. Вместе с панелью уничтожается и
> сама кнопка. А обработка  события уже уничтоженной кнопки
> еще не завершилась.

Хм.. а:
TForm1.Button1Click(Sender: TObject);
begin
 Free;
end;
никаких AV. И в чем разница?


OlegM   (2007-08-09 08:35:00) [10]

Что то я совсем спекся, ругаетцо на TPanel(WParam).Free;
[Error] Unit1.pas(49): '(' expected but ')' found


{RASkov}   (2007-08-08 09:27:00) [11]

> [14] OlegM   (08.08.07 09:21)

Нечто примерно так:

const DEL_PAN = WM_USER+ 666; // :) Можно и +1
....
procedure DelPanel(var mes: TMessage); message DEL_PAN;

procedure TForm.DelPanel(var mes: TMessage);
begin
 TPanel(WParam).Free;
end;

procedure TForm.ButtonClick();
begin
 PostMessage(Handle, DEL_PAN, Integer((Sender as TWInControl).Parent), 0);
end;


OlegM   (2007-08-08 09:21:00) [12]

Что ? )


MBo   (2007-08-08 09:07:00) [13]

>А какое сообщение ?
пользовательское, например
WM_MY_FREE = WM_USER + 666;


OlegM   (2007-08-08 08:58:00) [14]

> Решение: обработчик кнопки через PostMessage шлет форме сообщение
А какое сообщение ?
WM_DESTROY неробит


MBo   (2007-08-08 07:55:00) [15]

в [8] все уже написано.


OlegM   (2007-08-08 07:07:00) [16]

Щас опишу задачу поподробнее.
нужно на экран выдавать типа сообщения, используя для этого TPanel, различные Showmessage и child формы не подходят, уже их пробовал.
Т.е выдавать эти сообщения но,  и закрывать эти сообщения нужно кнопкой на этих панелях, но закрывать только ту панел на которой нажата кнопка и причем закрывать в такой последовательности, 1,2,3,4 т.е в какой последовательности выдались эти сообщения в такой их и закрывать и не давать закрывать например 2,1,3,4

в свойстве Tag храниться какая панелька в какой последователности была открыта.

код такой и вот на нем все и ломится

procedure TForm1.BtnClose(Sender: TObject);
var
 i,j,min:integer;
begin
 for i:=0 to Form1.ComponentCount-1 do
 begin
   if Form1.Components[i].ClassType = TPanel then
   begin
     min:=Form1.Components[i].Tag;
     for j:=0 to Form1.ComponentCount-1 do
     begin
       if Form1.Components[j].ClassType = TPanel then
       begin
         if Form1.Components[j].Tag <= min then min:=Form1.Components[j].Tag;
       end;
     end;
   end;
 end;

 for i:=0 to Form1.ComponentCount-1 do
 begin
   if Form1.Components[i].ClassType = TPanel then
   begin
     if Form1.Components[i].Tag = min then
     begin
       (Form1.Components[i] as TPanel).Free;
       Exit;
     end;
   end;
 end;
end;


хотя тотже самый код работает когда я вешаю попуп меню на панели. И работает как надо.
PS Это типа не я мозг парю это начальство дало вот такое задание в точности.


Loginov Dmitry   (2007-08-07 21:42:00) [17]

> Но иногда все работает, иногда выдает Abstract Error иногда
> выдает


Попробуй после Free сделать Abort


Юрий Зотов   (2007-08-07 21:08:00) [18]

О чем речь идет? Какие-такие FindComponent? Не о том говорим.

Обработчик щелка по кнопке уничтожает панель, на которой лежит ЭТА САМАЯ кнопка. Вместе с панелью уничтожается и сама кнопка. А обработка  события уже уничтоженной кнопки еще не завершилась.

Что будет? Access Violation будет. Это и есть корень зла, а вовсе никакие не FindComponent.

Решение: обработчик кнопки через PostMessage шлет форме сообщение, передавая в его параметрах Sender (то есть, кнопку). Получив сообщение, форма уничтожает Parent'а этой кнопки.

И никаких FindComponent.


MetalFan   (2007-08-07 17:49:00) [19]

...OnButtonClick( Sender: TObject );
begin
if Sender is TButton then
  if TButton(Sender).Parent is TPanel then
     TButton(Sender).Parent.Free;
end;

не очень хороший конечно вариант))) предлагаю доработать мозгами


{RASkov}   (2007-08-07 15:05:00) [20]

> [0] OlegM   (07.08.07 14:37)

Ты более подробнее задавай вопрос, а то получается из [0]:
Мы создали несколько панелей с кнопками, а потом всего лишь одним нажатием на одну любую кнопку убили все что было на форме или только все панели в том числе и статически созданные....
В Components находяться все компоненты формы
а в Controls находятся все контролы принадлежащие тому контролу которому принадлежит этот самый список Controls
Т.е.
Controls или Form1.Controls содержит все контролы, в том числе и динамич созданные панели, если родитель этих панелей есть сама форма, а вот
Panel.Controls содержит контролы, которые находятся на панеле Panel, в том числе и те самые кнопки....


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо