Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2015.12.06;
Скачать: CL | DM;

Вниз

Как удалить динамически созданный контрол   Найти похожие ветки 

 
Sakipiel   (2014-06-05 15:52) [0]

Есть панель, на нее программно создаются контролы.
Задача:
при нажатии на кнопку Delete удалить активный контрол с панели и вообще удалить.

Проблема:
Событие OnkeyDown активизируется в том самом контроле. В панели на которую он ложится OnkeyDown нет вообще. ну и когда мы из самого контрола, а именно события OnKeyDown вызываем


if Key = VK_DELETE  then
    If Assigned(ActiveControl) Then
       ActiveControl.RemoveControl(ActiveControl);


то получаем ошибку, вообщем отказывается он удалять самого себя, а что делать?


 
Sakipiel   (2014-06-05 16:09) [1]

if Key = VK_DELETE  then
   If Assigned(ActiveControl) Then
       (Sender as TControl).Owner.RemoveComponent(ActiveControl);


и так ниале


 
mfender ©   (2014-06-05 16:09) [2]


     if Assigned(TControl(Sender)) then
       TControl(Sender).Parent.RemoveControl(TControl(Sender));


 
Sakipiel   (2014-06-05 16:17) [3]

спс )


 
Sakipiel   (2014-06-07 03:11) [4]

Вопрос на засыпку, а что делать с контролами у которых OnKeyDown нет? Tlabel например...


 
Leonid Troyanovsky ©   (2014-06-07 08:25) [5]


> Sakipiel   (05.06.14 15:52)

Во-первых, RemoveControl - это не "вообще удалить",
а удалить из списка контролов. See also: InsertControl.

Во-вторых, OnKeyDown у панели есть, просто оно protected.

В-третьих, удалять контрол из его же обработчика - не очень
хорошая идея.

Я бы сделал HitList: TObjectList и очищал его (Clear),
скажем, в Application.OnIdle (See TApplicationEvents).
Т.е., если контрол стал не нужен, то добавим его в список.

--
Regards, LVT.


 
Leonid Troyanovsky ©   (2014-06-07 08:29) [6]


> Sakipiel   (07.06.14 03:11) [4]

Ну, можно, например, у панели сделать контекстное меню,
с помощью которого можно удалить (добавить, переместить, ..) контрол. See also: HotKey, TAction &etc.

--
Regards, LVT.


 
Юрий Зотов ©   (2014-06-07 13:47) [7]

Безопасный вариант.

Из обработчика контрола посылаем форме (через PostMessage) юзерское сообщение, передавая контрол через параметры. Получив это сообщение, форма удаляет контрол.


 
Sakipiel   (2014-06-19 17:27) [8]

да, но из какого обработчика? в Tlabel нет OnKeyDown, не модифицировать же мне теперь все контролы


 
Германн ©   (2014-06-19 17:35) [9]


> в Tlabel нет OnKeyDown

Значит для TLabel и не существует проблемы описанной в топике.


 
Dimka Maslov ©   (2014-06-19 17:40) [10]

Ставим форме KeyPreview (или как там оно называется) в true и спокойно обрабатываем удаление контролов в OnKeyDown формы.

Что же касается TLabel, то в силу определённых причин оно не может быть активным контролом. Никогда.


 
Sakipiel   (2014-06-19 19:54) [11]

непонятная ботва,


 LastSelectedControl.Parent.RemoveControl(LastSelectedControl);
 LastSelectedControl.free;


делаю я, где LastSelectedControl это переменная в которой хранится указатель на компонент, все проходит, но есть еще 1 переменная в которой также хранится указатель на этот компонент, и вот после того что я сделал, что должно остаться в той переменной? Ибо она проходит проверку


if not Assigned(C) then
   exit;


т.е. получается что оно вполне себе Assigned после удаления. Причем можно посмотреть его ClassName, как так то? что делать?


 
Inovet ©   (2014-06-19 20:27) [12]

> [11] Sakipiel   (19.06.14 19:54)
> как так то?

Во-первых, кто ж за тебя её будет обниливать. Во-вторых, надо проверить - всё ли в порядке с логикой, если после удаления надо проверять на удалённость.


 
Sakipiel   (2014-06-19 20:51) [13]

мде, чо ж оно не обниливаецо само, а то удаляешь удаляешь, удаляешь, удаляешь, а ничего не удаляется. с логикой все в порядке, просто я не люблю делать компоненты которые в каждой непонятной ситуации (как то неназначеная ссылка на компонент) будет вываливать Аксесс виалейшн, и чтобы я потом долго размышлял, и что же это за беда то такая. У меня есть мой компонент, который вокруг этого рисует рамку и в нем на него ссылка, и ее он и проверяет, перед тем как перерисовать рамку, и получается, если я удаляю компонент, то мне придется вручную обниливать все ссылки..нет их конечно не много, но все равно обидно чо та.


 
Sakipiel   (2014-06-19 20:58) [14]


procedure TDesForm.FormKeyDown(Sender: TObject; var Key: Word;
 Shift: TShiftState);
 //var
 //  s:string;
begin

 if Key = VK_DELETE then
   if Assigned(LastSelectedControl) then
   begin
     //s := TControl(Sender).Name;
     MarkControlAsDeleted(LastSelectedControl.Name);
     DeleteSelectedComponentFromPointerList;
     LastSelectedControl.Parent.RemoveControl(LastSelectedControl);
     LastSelectedControl.free;
     LastSelectedControl := nil;
     SetFocus(LastSelectedControl);
   end;

end;


мде вот она и случилась непонятная ситуация. весь код проходит, останавливаемся отладчиком на последнем end, жмем F7 и получаем ошибку чтения памяти...я чета без идей )


 
brother ©   (2014-06-19 21:00) [15]

1.
>     LastSelectedControl.free;
>     LastSelectedControl := nil;

freeandnil
2.

> SetFocus(LastSelectedControl);

он уже мертв!


 
brother ©   (2014-06-19 21:04) [16]

ps. используйте отладчик и точки останова чтобы выловить причину и точное место AV


 
Sakipiel   (2014-06-19 21:04) [17]

LastSelectedControl.free; а если не делать этого, то эта ошибка не появляется


> он уже мертв!


это моя процедура и она рисует рамку вокруг компонента, а если он уже мертв, то она ее стирает.


 
Sakipiel   (2014-06-19 21:06) [18]


> ps. используйте отладчик и точки останова чтобы выловить
> причину и точное место AV


так я именно это и делал, я же говорю весь код проходит без ошибок, вылет происходит на выходе из FormKeyDown, причем я жму F7 т.е. отладчик туда где ошибка меня не пускает.


 
Sakipiel   (2014-06-19 21:18) [19]

может он после FormKeyDown пытается вызвать OnkeyDown компонента? а компонента уже нет? и вот результат...


 
Sakipiel   (2014-06-19 21:20) [20]

в подтверждение моей теории TLabel удаление таким образом не вызывает ошибки, т.к. у него нет OnkeyDown события. Так что метод че то дал сбой) как удалить контрол? ))


 
Плохиш ©   (2014-06-19 21:38) [21]

Ещë один горе-кодер, за которым пушкин подчищать ссылки.

Запомни: это программирование, здесь тебе никто и ничего не должен, всë что накодил, должен сам и подчистить за собой.


 
Германн ©   (2014-06-19 22:00) [22]


> с логикой все в порядке

Как раз наоборот. Класс не может знать в каких переменных содержатся ссылки на него и сколько их вообще этих переменных.


 
Sakipiel   (2014-06-19 22:59) [23]

уже начал изучать TApplicationEvents, как вдруг пришло гениальное решение. Сделать это не  в кейдауне,  а в кейапе, тогда косяка нет.


 
Юрий Зотов ©   (2014-06-19 23:11) [24]

> Sakipiel   (19.06.14 22:59) [23]
> Сделать это не  в кейдауне,  а в кейапе, тогда косяка нет.


Необнуленная ссылка на уже уничтоженный компонент - это скрытый косяк. И корень зла. Если Вы это корень не уберете, то рано или поздно он себя все равно проявит. И никакие кейдауны тогда уже не помогут. Исправлять надо саму причину, а не ее следствие.


 
Sakipiel   (2014-06-19 23:54) [25]

омг, я уже давно все обнулил, я же сказал ошибка не в моем коде вылазила, свои соображения по поводу того что происходило я выше написал, что я сделаю то с этим?


 
Inovet ©   (2014-06-20 00:41) [26]

> [25] Sakipiel   (19.06.14 23:54)
> я же сказал ошибка не в моем коде вылазила

А, Снова Билл Гейтс? Или про него уже не помнят?


 
Inovet ©   (2014-06-20 00:43) [27]

> [25] Sakipiel   (19.06.14 23:54)
> я уже давно все обнулил

Перечитать

> [12] Inovet ©   (19.06.14 20:27)
> Во-вторых, надо проверить - всё ли в порядке с логикой,
> если после удаления надо проверять на удалённость.


 
Sakipiel   (2014-06-20 04:08) [28]

ну может вы сначала попробуете удалить компонент так, а потом расскажете как у вас это получилось ) мою процедуру можно вообще закомментировать, она ничего не меняет.


 
Inovet ©   (2014-06-20 04:27) [29]

> [28] Sakipiel   (20.06.14 04:08)

Да пожалуйста

procedure TForm1.Button1Click(Sender: TObject);
begin
 if Assigned(ActiveControl) then
 begin
   RemoveControl(ActiveControl);
 end;
end;

И не надо, чтобы он самоудалялся. Удалять должен тот, кто создал, или владелец.


 
Sakipiel   (2014-06-20 05:04) [30]

хе хе, тута нету Free, это раз, т.к. в этом вся фишка, контрол должен удалятся по кейдауну, а не по нажатии кнопки, из кейдауна формы. При этом фокус должен быть на удаляемом контроле в этот момент, чтобы он тоже получил кейдаун, вернее получать его будет уже не кому и вылезет ошибка о которой я говорил.

А делать Free научили меня вы. А создал я его програмно. Я ж начинающий я не знаю удалит его владелец и когда или нет


 
Sakipiel   (2014-06-20 05:06) [31]

а то понимаешь, ссылки удаляй, чо как не программист, а контролы не удаляй, чо как не программист )


 
brother ©   (2014-06-20 05:35) [32]

[29] Вы еще не устали с ним спорить? Ну уперся на кейдауне, пусть грабли ловит...
зы. автор, еще раз [24] + удаление объекта "из себя" ЗАПРЕЩАЮ! и [25] вызывает улыбку...


 
brother ©   (2014-06-20 05:39) [33]

меня так и тянет спросить: какое условие должно произойти, чтобы TLabel (если их несколько,то какой именно) нужно было удалять? ибо он не может быть в фокусе!


 
Sakipiel   (2014-06-20 06:19) [34]

согласитесь это очень удобно, нажать делит, и чтобы все было. более того даже в делфи так оно и работает. Вот от этого я и пляшу. А раз так, то что же еще обрабатывать, как не онКейДаун? Хотя кейАп тоже нормально.

К каждому контролу при создании у меня прикрепляется онКлик, который записывает в отдельное поле владельца компонента ссылку на него, на котором кликнули, поэтому я всегда удаляю тот лабел, я не удаляю на данный момент активный контрол. Так что все пучком, довольно пессимизма.


 
Sakipiel   (2014-06-20 06:33) [35]


> Во-первых, RemoveControl - это не "вообще удалить",а удалить
> из списка контролов. See also: InsertControl.


вы мне писали.....после чего я начал делать Free, до этого я этого не делал, если владелец удалит, так я не против) не надо так не надо, я что против что ли )


 
Inovet ©   (2014-06-20 06:48) [36]

> [35] Sakipiel   (20.06.14 06:33)

Подожди насчёт Free. Сначала расскажи, что хочешь получить, а не сразу о том, как это делаешь. Делаешь ты что-то не то, а что надо пока не ясно. Кто там кого и зачем должен удалять? Насовсем или как?


 
Sakipiel   (2014-06-20 07:27) [37]

хочу получить дизайнер форм, для этого берем форму, кладем на нее панель - форма владелец всего, панель эмулирует ту форму которую мы разрабатываем и является родителем всех контролов. пользователь из списка выбирает контрол который он хочет добавить, он программно создается и появляется на панели. Если пользователь решил, что контрол не нужен, он его выделяет и жмет делит и контрол удаляется, вот что нужно ) в принципе все уже работает...



Страницы: 1 вся ветка

Текущий архив: 2015.12.06;
Скачать: CL | DM;

Наверх




Память: 0.56 MB
Время: 0.007 c
6-1277274057
night_light
2010-06-23 10:20
2015.12.06
передача нескольких изображений по сети


2-1398337114
Who_are_you?
2014-04-24 14:58
2015.12.06
Замена Chart - графика для слабых компьютеров?


15-1428519178
Dennis I. Komarov
2015-04-08 21:52
2015.12.06
Delphi, CGI, IIS (просто интересно)


15-1428528989
Кто б сомневался
2015-04-09 00:36
2015.12.06
Как такие ярлыки делать?: MyProgram://MyID


15-1428874204
Юрий
2015-04-13 00:30
2015.12.06
С днем рождения ! 13 апреля 2015 понедельник