Вниз
Скачать: 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 вся ветка

Скачать: CL | DM;



Память: 0.48 MB
Время: 0.017 c
2-1211132859
lewka-serdceed
2008-05-18 21:47
2008.06.08
переход с одного Edit на другой edit при нажатии на Enter


15-1208941436
Гость1468
2008-04-23 13:03
2008.06.08
Нанесение идентефикационной информации на документ. Как?


2-1210824339
brother
2008-05-15 08:05
2008.06.08
сколько строк в TstringList


15-1209325537
No_Dead
2008-04-27 23:45
2008.06.08
Есть ли такие проги или это уже ИИ?%>


15-1209135932
@!!ex
2008-04-25 19:05
2008.06.08
Принудительная перекомпиляция модуля.




   Наверх