Форум: "Начинающим";
Текущий архив: 2008.06.08;
Скачать: [xml.tar.bz2];
ВнизУничтожение объекта из "своего" события. Найти похожие ветки
← →
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;
Скачать: [xml.tar.bz2];
Память: 0.48 MB
Время: 0.056 c