![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Уничтожение объекта из "своего" события.
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; // <= наличи/отсутствие не влияете
> на выход сообщения
и не будет... бо никакого отношение простое значение поля, фактически ординал типа, к освобождению объекта не имеет...
> А как уничтожить "сомого себя" из собственной процедуры?
послать сообщение главной форме о том, что ты уже не нужен и тебя можно удалить...