Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2008.06.08;
Скачать: CL | DM;

Вниз

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

 
noviceman ©   (2008-05-14 09:01) [0]

Возникла проблема с ошибкой: <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, тогда все ок.
А как уничтожить "сомого себя" из собственной процедуры?


 
Palladin ©   (2008-05-14 09:07) [1]


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

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


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

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


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

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


 
Palladin ©   (2008-05-14 09:19) [3]

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

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

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


 
Reindeer Moss Eater ©   (2008-05-14 09:22) [4]

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


 
Palladin ©   (2008-05-14 09:24) [5]


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

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


 
noviceman ©   (2008-05-14 09:36) [6]

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


 
Palladin ©   (2008-05-14 09:38) [7]

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


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

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

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


 
noviceman ©   (2008-05-14 09:44) [9]

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

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:45) [10]

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


 
noviceman ©   (2008-05-14 09:52) [11]

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

...
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:53) [12]

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


 
noviceman ©   (2008-05-14 09:56) [13]

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


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

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


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

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


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


 
noviceman ©   (2008-05-14 10:14) [15]

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



Страницы: 1 вся ветка

Текущий архив: 2008.06.08;
Скачать: CL | DM;

Наверх




Память: 0.5 MB
Время: 0.018 c
15-1209278624
БарЛог
2008-04-27 10:43
2008.06.08
Христос воскрес!!


15-1208979144
Loginov Dmitry
2008-04-23 23:32
2008.06.08
Многопоточность и Delphi


2-1209999304
TStas
2008-05-05 18:55
2008.06.08
Что такое class of ?


15-1209129036
Пробегал2...
2008-04-25 17:10
2008.06.08
Универсальная COM / UDP передача


2-1210954730
Alexander
2008-05-16 20:18
2008.06.08
Динамическое создание объектов