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

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

Уничтожение объекта из "своего" события.


noviceman ©   (2008-05-14 09:01:00) 

Возникла проблема с ошибкой: <Access violation at address 00000000. Read of address 0000000>. А происходит это в случае, если я уничтожаю компонент из своего события.
Код:

var
 Edit: TEdit;
 Grid: TStringGrid;

...

procedure TGridForm.CreateEdit;
begin
 Edit := TEdit.Create(Grid);
 Edit.Parent := Grid;
 Edit.OnKeyPress := EditKeyPress;
end;

...

procedure TGridForm.EditKeyPress(Sender: TObject; var Key: Char);
begin
 ...
 if Key = #27 then FinishEdit;
end;  // <= А вот после выхода из процедуры происходит ошибка

...

procedure TGridForm.FinishEdit;
begin
 ...
 Edit.OnKeyPress := nil; // <= наличи/отсутствие не влияете на выход сообщения
 FreeAndNill(Edit);
end;


Если я вызываю процедуру FinishEditиз события не пренадлежащего Edit, тогда все ок.
А как уничтожить "сомого себя" из собственной процедуры?


noviceman   (2008-05-14 10:14:00) [1]

В общем спасибо за ответы.
В итоге переделал немного логику...
Но решение понятно и может еще пригодится.


noviceman   (2008-05-14 09:58:00) [2]

Palladin ©   (14.05.08 9:53) [12]
тебе ж черным по серому написано, ошибся я, не SendMessage, а PostMessage


Ну ступил немного... сори...


noviceman   (2008-05-14 09:56:00) [3]

Palladin ©   (14.05.08 9:45) [10]
ты после [5] читал вообще?


Прочитал, спасибо...

p.s. Пора отдыхать )))))


Palladin   (2008-05-14 09:53:00) [4]

тебе ж черным по серому написано, ошибся я, не SendMessage, а PostMessage


noviceman   (2008-05-14 09:52:00) [5]

Вот код тестового проекта:

...
var
 Form1: TForm1;
 Edit: TEdit;
...

procedure TForm1.Button1Click(Sender: TObject);
begin
 CreateEdit;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
 DestroyEdit;
end;

procedure TForm1.CreateEdit;
begin
 Edit := TEdit.Create(Self);
 Edit.Parent := Self;
 Edit.OnKeyPress := EditKeyPress;
end;

procedure TForm1.DestroyEdit;
begin
 SendMessage(Form1.Handle, UWM_InputEditDestroy, 0, 0);
end;

procedure TForm1.EditKeyPress(Sender: TObject; var Key: Char);
begin
 if (Key = #27) then
   begin
     DestroyEdit;
   end;
end;

procedure TForm1.MSGInputEditDestr(var msg: TMessage);
begin
 FreeAndNil(Edit);
end;


При уничтожении Edit нажатием кн.2 все отлично.
А при уничтожении по "ESC", все плохо :-).

Access violation at address 00146108. Write of address 00880040.

Ну я блин намудрил с логикой. Теперь вот приходится расхлебывать...


Palladin   (2008-05-14 09:45:00) [6]

ты после [5] читал вообще?


noviceman   (2008-05-14 09:44:00) [7]

Пересал немного код

var
Edit: TEdit;
Grid: TStringGrid;

...

const
 UWM_InputEditDestroy = WM_USER + $0001;

...

procedure TGridForm.CreateEdit;
begin
Edit := TEdit.Create(Grid);
Edit.Parent := Grid;
Edit.OnKeyPress := EditKeyPress;
end;

...

procedure TGridForm.EditKeyPress(Sender: TObject; var Key: Char);
begin
...
if Key = #27 then FinishEdit;
end;  // <= А вот после выхода из процедуры происходит ошибка

...

procedure TGridForm.FinishEdit;
begin
...
SendMessage(Parent.Handle, UWM_InputEditDestroy, 0, 0);
end;

{procedure MSGInputEditDestr(var msg: TMessage); message UWM_InputEditDestroy;}

procedure TGridForm.MSGInputEditDestr(var msg: TMessage);
begin
 FreeAndNil(Grid.Edit);
end;


Ощибка не "ушла". Нифига не могу понять. Сделал проект для проверки, пустой, только Edit создаваемый на форме динамически, и кнопка для создания Edit. Та же ситуация ошибка повторяется...


Palladin   (2008-05-14 09:40:00) [8]

хотя в принципе можно извернуться и поступить так

PostMessage(GridFormInstance.Handle,UWM_EditБольшеНеНужен,Integer(Sender),0);


Palladin   (2008-05-14 09:38:00) [9]

а вот придется как то дать знать о его существовании, хранить экземпляры... массивы, списки, классы-коллекции... столько всего придумано... зря чтоли?


noviceman   (2008-05-14 09:36:00) [10]

А форма "не знает" о существовании объекта Edit(TEdit). Во всяком случае его нет в секции public/publishedописания объекта Grid(TStringGrid). Edit(Tedit)создается динамически, в процессе работы приложения.


Palladin   (2008-05-14 09:24:00) [11]


> Reindeer Moss Eater ©   (14.05.08 09:22) [4]

да, верно... PostMessage... и главное, никаких Application.ProcessMessages после Post :)


Reindeer Moss Eater   (2008-05-14 09:22:00) [12]

C sendmessage будет все точно так же, как если бы здесь же вызвали free


Palladin   (2008-05-14 09:19:00) [13]

SendMessage(GridFormInstance.Handle,UWM_EditБольшеНеНужен,0,0);

в форме его поймать и написать FreeAndNil

как ловить сообщения написано в справке по ключевому слову в index, message (directive)


noviceman   (2008-05-14 09:14:00) [14]

А по-подробней про "послать сообщение главной форме" можно?


Palladin   (2008-05-14 09:07:00) [15]


>  Edit.OnKeyPress := nil; // <= наличи/отсутствие не влияете
> на выход сообщения

и не будет... бо никакого отношение простое значение поля, фактически ординал типа, к освобождению объекта не имеет...


> А как уничтожить "сомого себя" из собственной процедуры?

послать сообщение главной форме о том, что ты уже не нужен и тебя можно удалить...


Наверх

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