Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Общие вопросы > как удалить компонент


Автор: chikistbuch 26.5.2012, 17:21
Хочу сделать чтобы при нажатии на Enter в Edit'е он исчезал, да не просто исчезал, а вообще удалялся из формы. Edit'ы созданы в run-time (MyEdit1, MyEdit2, и т.д.)

К примеру в MyEdit1 нажали Enter, вот код:

Код

procedure TForm1.EditKeyPress(Sender: TObject; var Key: Char);//когда нажали клавишу на edit
begin
  if Key = #13 then begin //если нажат enter
    Key := #0;//чтобы не звенело
    DestroyComponent('MyEdit1', form1.GroupBox4);//удаляем edit
  end;
end;


а вот и сама процедура удаления DestroyComponent:

Код

procedure DestroyComponent(name: string; gde: TComponent);//удаляет компонент
var
  i: Word;
begin
  i:=gde.ComponentCount;

  while i>0 do begin
    i:=i-1;
    if gde.Components[i].Name=name then begin
      gde.Components[i].Destroy;
      i:=0;
    end;
  end;
end;


Вопрос в том, что после завершения процедуры TForm1.EditKeyPress, выскакивает ошибка. Как я понимаю, приложение не может завершить выполнение процедуры несуществующего компонента
http://s2.ipicture.ru/

При выполнении этого же кода в TForm1.EditExit, вызываемое как onExit, все ок
Код

procedure TForm1.EditExit(Sender: TObject);//когда теряет фокус edit
begin
  DestroyComponent('MyEdit1', form1.GroupBox4);//удаляем edit
end;

Подскажите, как удалить edit при нажатии в нем enter

Автор: northener 26.5.2012, 17:58
Посылайте форме ваше собственное сообщение с помощью PostMessage. В обработчике этого сообщения и уничтожайте компонент.

Автор: chikistbuch 26.5.2012, 18:12
расскажи, пожалуйста конкретнее: как именно послать сообщение и написать свой обработчик.
Вот что я нашел в нете
Код

PostMessage(FindWindow(nil,PWideChar(form1.Caption)),WM_KEYDOWN,$00000031,$00020001);

Автор: kami 26.5.2012, 18:13
Почти оффтоп:
northener, да, статья нужна smile

Добавлено @ 18:23
Расшифровка ответа northener:
http://forum.vingrad.ru/index.php?showtopic=253299&view=findpost&p=1826869
Настоятельно рекомендую прочитать пост БелАмор-а

Автор: northener 26.5.2012, 18:30
Код

const
  WM_FreeMyEdit = WM_USER + 100;

type
  TForm1 = class(TForm)
  ...
  procedure WMFreeMyEdit(var Mess: TMessage); message WM_FreeMyEdit;
  ...
end;

...
 procedure TForm1.WMFreeMyEdit(var Mess: TMessage);
 begin
   MYEdit1.Free;
 end;

procedure TForm1.MyEdit1KeyPress(Sender: TObject; var Key: Char);//когда нажали клавишу на edit
begin
  if Key = #13 then begin //если нажат enter
    Key := #0;//чтобы не звенело
    PostMessage(Handle,WM_FreeMyEdit,0,0);
  end;
end;

Автор: chikistbuch 26.5.2012, 18:45
kami, northener, да вы просто боги!!! СПС smile 

Автор: Akella 26.5.2012, 23:16
chikistbuch, а ты сомневался? ;)

Автор: northener 27.5.2012, 02:41
Цитата(kami @  26.5.2012,  18:13 Найти цитируемый пост)
northener, да, статья нужна 

Вот ещё раз полазил по нашим форумам и по всемирной помойке. Но так и не нашел статью, в которой подробно и с объяснениями было бы описано как правильно уничтожать объекты!
И не только из обработчиков их событий. Но и вообще. Нет нормальной (и не только нормальной - просто никакой) статьи, где бы описывалось различие между методами Free, Destroy, Release. 

Автор: Akella 27.5.2012, 09:57
Цитата(northener @  27.5.2012,  02:41 Найти цитируемый пост)
 где бы описывалось различие между методами Free, Destroy, Release. 

так можно в исходниках посмотреть

Автор: northener 27.5.2012, 17:39
Цитата(Akella @  27.5.2012,  09:57 Найти цитируемый пост)
так можно в исходниках посмотреть

Так их "жевать" надо smile

Автор: MetalFan 27.5.2012, 22:37
Цитата(northener @  27.5.2012,  02:41 Найти цитируемый пост)
Нет нормальной (и не только нормальной - просто никакой) статьи, где бы описывалось различие между методами Free, Destroy, Release. 

А зачем статья? там же в двух предожениях можно описать, если глянуть исходники.

Free = проверка Self <> nil + Destroy;
Код

procedure TObject.Free;
begin
  if Self <> nil then
    Destroy;
end;


Release относится только к форме и равно "отложенному" Free. т.е. форме отправляется сообщение (CM_RELEASE), при обработке которого форма и прибивается.
Код

procedure TCustomForm.Release;
begin
  PostMessage(Handle, CM_RELEASE, 0, 0);
end;
procedure TCustomForm.CMRelease;
begin
  Free;
end;



Цитата(northener @  26.5.2012,  18:30 Найти цитируемый пост)
WM_FreeMyEdit

А можно написать еще более универсальный вариант, в котором передавать указатель на компонент, который надо "пришибить".

Автор: northener 27.5.2012, 23:58
Цитата(MetalFan @  27.5.2012,  22:37 Найти цитируемый пост)
А можно написать еще более универсальный вариант, в котором передавать указатель на компонент, который надо "пришибить".

По ссылке которую дал kami именно так и сделано.

Автор: northener 28.5.2012, 01:00
Цитата(MetalFan @  27.5.2012,  22:37 Найти цитируемый пост)
А зачем статья? там же в двух предожениях можно описать, если глянуть исходники.

Ну хорошо. Пусть не статья. Пусть ссылка на FAQ.
Лично для меня проще иметь под рукой готовую ссылку на то, где автор вопроса сможет получить подробную информацию о том как решить его задачу, чем всякий раз "набивать" пример в своём ответе. (Пальцы чай не казённые, а мои собственные. smile

Автор: Akella 28.5.2012, 09:25
Цитата(MetalFan @  27.5.2012,  22:37 Найти цитируемый пост)
 if Self <> nil then
    Destroy;


тут может быть проблема, если несколько раз создаешь и уничтожаешь объект

если уничтожаешь просто Obj.Free, то потом при проверке
if obj <> nil результат будет True

поэтому лучше уничтожать так
Код

FreeAndNil(Obj);

или
Код

Obj.Free;
Obj := nil;


Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)