Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 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.047 c
2-1210832368
troyan_81
2008-05-15 10:19
2008.06.08
Преобразование типов


11-1189516515
vampir_infernal
2007-09-11 17:15
2008.06.08
MHToolTip и GRush


2-1211215467
assassin8899
2008-05-19 20:44
2008.06.08
QuickReport


6-1188851972
Aibolit
2007-09-04 00:39
2008.06.08
в терминальном сервере


2-1210970505
Woohoo
2008-05-17 00:41
2008.06.08
Автоматическое обновление поля таблицы





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский