Конференция "Основная" » Разрушение объекта при двойном щелчке на объекте
 
  • Дмитрий Белькевич (15.02.10 16:02) [0]
    Возникла потребность разрушить визуальный объект, когда на нём сделали двойной щелчок. Пытаюсь разрушать в обработчике OnDblClick - ничего хорошего из этого не получается. Как такое поведение можно корректно реализовать?
  • oldman © (15.02.10 16:09) [1]
    По двойному щелчку меняешь флаг.
    В событии "смена флага" дестроишь объект.
    :)))

    Тупо, но сработает, наверное.
  • Anatoly Podgoretsky © (15.02.10 16:11) [2]
    Лучше так не делать.
  • Дмитрий Белькевич (15.02.10 16:19) [3]
    >В событии "смена флага" дестроишь объект.

    Понятно, что на худой конец можно и таймер повесить. Но - опять же - лучше так не делать. Пока не могу придумать как по-другому.
  • Игорь Шевченко © (15.02.10 16:27) [4]

    > Как такое поведение можно корректно реализовать?


    через PostMessage послать сообщение владельцу объекта - разрушь меня
  • Дмитрий Белькевич (15.02.10 16:44) [5]

    > через PostMessage послать сообщение владельцу объекта -
    > разрушь меня


    Вот это интересно. Спасибо, попробую.
  • Дмитрий Белькевич (15.02.10 19:02) [6]
    It works :) Спасибо еще раз.
  • Германн © (16.02.10 02:16) [7]

    > Дмитрий Белькевич   (15.02.10 19:02) [6]
    >
    > It works :)

    Сей способ должен был быть выучен ещё в детском саду. Ибо он - единственный способ "разрушить" объект из метода "этого самого объекта".
  • Германн © (16.02.10 02:30) [8]
    Токмо в [4] есть маленькая ошибка. В терминологии.
    Примите и прочь. :)
  • Омлет © (17.02.10 13:15) [9]
    Странно. Я в обработчике OnExit объекта успешно разрушаю этот объект.
  • Вася (17.02.10 13:59) [10]

    > Германн ©   (16.02.10 02:16) [7]
    >
    >


    > Ибо он - единственный способ "разрушить" объект из метода
    > "этого самого объекта".


    Да ладно. Как насчет метода Free ?
  • DVM © (17.02.10 15:02) [11]

    > Вася   (17.02.10 13:59) [10]


    > Да ладно. Как насчет метода Free ?

    Не с каждым объектом прокатит.
  • TStas (17.02.10 17:25) [12]
    Этот вопрос описан в книге Григорьева. Всё очень просто.
    const WM_HARAKIRI = WM_USER + 1; //Определили новое сообщение.

    А у окна, которому принадлежит Ваш объект, определяем обработчик сообщений, который и будет убивать объект.
    procedure WMHarakiri(var Msg: TMessage); message WM_HARAKIRI;

    procedure TMainForm.WMHarakiri(var Msg: TMessage);
    var
     HappilessObj: THappilessObj; //Переменная типа убиваемого объекта
    begin
     HappilessObj := THappilessObj(Msg.wParam); //Привели тип
     HappilessObj.Free; //И убили
    end;

    //А теперь в обработчике двойного щелчка пишем
    SendMessage(
     Handle, //Handle окна, которое и убъёт компонент
     WM_HARAKIRI, //Само сообщение
     Integer(Sender), //Указатель на убиваемый объект
     0
    );

    Этот способ хорош по двум причинам:
    1) Он "взрослый", а не с таймером.
    2) Можно убивать не один, а много объектов одного класса или даже разных классов, во втором случае вместо нуля передавать число, идентифицируещее класс.
  • Игорь Шевченко © (17.02.10 17:31) [13]

    > SendMessage(


    PostMessage
  • oxffff © (17.02.10 21:40) [14]

    > TStas   (17.02.10 17:25) [12]
    > Этот вопрос описан в книге Григорьева. Всё очень просто.
    >  
    > const WM_HARAKIRI = WM_USER + 1; //Определили новое сообщение.
    >  
    >
    > А у окна, которому принадлежит Ваш объект, определяем обработчик
    > сообщений, который и будет убивать объект.


    Этот способ не является стопроцентным решением. Несложно написать контрпример, в котором этот пример даст сбой.
    Например достаточно просто перекрыть Tobject.Dispatch в наследнике  котором дополнительно логировать часть сообщений после обработки сообщений.
    Или создать каскад обработчиков сообщений в котором после обработки идет обращение к объекту.
    Местом где нет сообщений и они находятся не в каскаде является onIdle.

    Я бы предложил зацепиться за Application.OnIdle
  • Игорь Шевченко © (17.02.10 21:42) [15]
    oxffff ©   (17.02.10 21:40) [14]

    Несложно сделать веревку достаточной длины, чтобы выстрелить себе в ногу. Только зачем ?
  • oxffff © (17.02.10 21:52) [16]

    > Игорь Шевченко ©   (17.02.10 21:42) [15]
    > oxffff ©   (17.02.10 21:40) [14]
    >
    > Несложно сделать веревку достаточной длины, чтобы выстрелить
    > себе в ногу. Только зачем ?


    Вечер добрый.
    У решения есть очевидные недостатки, почему нельзя просто указать на них?
    И тем более предложив более безопасное решение, но возможно не окончательное?
    Что плохого в поиске самого refine решения?
  • Игорь Шевченко © (17.02.10 22:21) [17]
    oxffff ©   (17.02.10 21:52) [16]

    Добрый вечер. В случае необходимости уничтожения объекта из собственного обработчика идеального решения не существует, существует только тот или иной набор костылей. Я не вижу смысла расширять этот набор костылей сверх необходимости, и, соответственно, усложнять процедуру уничтожения объекта иначе как попросить владельца уничтожить объект. Если у кого-то что-то перекрыто, то не обращаться в перекрытом к уничтоженному объекту будет гораздо проще.
  • oxffff © (17.02.10 22:30) [18]

    > Игорь Шевченко ©   (17.02.10 22:21) [17]


    Так и с Вами согласен.
    Собственно я и сам не всегда стремлюсь к идеалам и в местах где запас не нужен обхожусь без него. Я так понимаю участники форума предлагают решения а уж задача вопрошающего выбрать себе нужный размер. :))

    Собственно если и в предложенном мною решении кто-то найдет ошибку.
    Я только рад буду, поскольку буду знать где он не сработает и будет предложено(возможно найдено сообща) более refine решение. От этого все выграют. Одна голова хорошо, а две лучше.
  • Плохиш © (18.02.10 00:54) [19]

    > Вася   (17.02.10 13:59) [10]


    > Как насчет метода Free ?

    Ответ приведён в сообщении автора [0]
  • Германн © (18.02.10 01:29) [20]

    > oxffff ©   (17.02.10 21:52) [16]
    >
    >
    > > Игорь Шевченко ©   (17.02.10 21:42) [15]
    > > oxffff ©   (17.02.10 21:40) [14]
    > >
    > > Несложно сделать веревку достаточной длины, чтобы выстрелить
    > > себе в ногу. Только зачем ?
    >
    >
    > Вечер добрый.
    > У решения есть очевидные недостатки, почему нельзя просто
    > указать на них?
    > И тем более предложив более безопасное решение, но возможно
    > не окончательное?

    Зачем в ответе на простой вопрос искать слишком сложное решение, если есть решение простое, пригодное в большинстве случаев?
  • oxffff © (18.02.10 01:41) [21]

    > Германн ©   (18.02.10 01:29) [20]


    Попробую ответить :)

    Если бы Вы заметили дефект, который может привести к сложностям у невнимательных(не утруждающих себя деталями) потребителей(но эти потребители "ездят" на одной с Вами марки средства) Вы бы промолчали? Это человечно? :)
  • Германн © (18.02.10 01:49) [22]

    > oxffff ©   (18.02.10 01:41) [21]
    >
    >
    > > Германн ©   (18.02.10 01:29) [20]
    >
    >
    > Попробую ответить :)


    > но эти потребители "ездят" на одной с Вами марки средства

    Попробуй.
    Я "езжу" на марке, в которой ничего не "перекрыто". То бишь (в рамках форума), стандартные компоненты Дельфи. И большинство тоже ездят на ней.
  • oxffff © (18.02.10 02:07) [23]

    > Германн ©   (18.02.10 01:49) [22]
    >
    > > oxffff ©   (18.02.10 01:41) [21]
    > >
    > >
    > > > Германн ©   (18.02.10 01:29) [20]
    > >
    > >
    > > Попробую ответить :)
    >
    >
    > > но эти потребители "ездят" на одной с Вами марки средства
    >
    > Попробуй.
    > Я "езжу" на марке, в которой ничего не "перекрыто". То бишь
    > (в рамках форума), стандартные компоненты Дельфи. И большинство
    > тоже ездят на ней.


    Отлично. Но Вас это обяжет описать обработку сообщения по удалению корректным образом у наследников ваших компонентов и может сильно стеснять их. И грубо говоря можете зависить от версий библиотеки. Поскольку потенциально никто не запрещает изменить библиотеку VCL под новые возможности внутреннего устройства языка(хотя по возможности они этого избегают).То есть вынудить совершать Вам излишние дополнительные усилия. Зачем?

    Если вы просто скрываете объект и добавляете его в очередь на удаление, а объект фактически удаляется в момент простоя приложения. Вы можете удалять из очереди частями размазав на больший интервал времени. И отдать приложению драгоценные такты(ведь компоненты разные бывают в общем виде).
  • Германн © (18.02.10 02:15) [24]

    > Отлично. Но Вас это обяжет описать обработку сообщения по
    > удалению корректным образом у наследников ваших компонентов

    Ну не обяжет это меня! Ну как ты не понимаешь!
    Какие наследники?
    См. Игорь Шевченко ©   (17.02.10 22:21) [17]
    Пусть ИШ отдувается. :)
  • oxffff © (18.02.10 02:23) [25]

    > Германн ©   (18.02.10 02:15) [24]
    >
    > > Отлично. Но Вас это обяжет описать обработку сообщения
    > по
    > > удалению корректным образом у наследников ваших компонентов
    >
    > Ну не обяжет это меня! Ну как ты не понимаешь!
    > Какие наследники?
    > См. Игорь Шевченко ©   (17.02.10 22:21) [17]
    > Пусть ИШ отдувается. :)


    Классы наследники Ваших компонентов, а не Ваши наследники. :)
    ИШ отдуваться не в чем. Представлено два решения.
    Посетители сами определятся с решением, а может предложат свое.
  • Германн © (18.02.10 02:46) [26]

    > Классы наследники Ваших компонентов, а не Ваши наследники.
    >  :)

    Ух её моё. А в где в сабже речь шла о наследниках каких-то компонент?

    Я не в праве  отнять значек (голубой).
    Но ты рискуешь его потерять!
  • oxffff © (18.02.10 03:04) [27]

    > Германн ©   (18.02.10 02:46) [26]
    >
    > > Классы наследники Ваших компонентов, а не Ваши наследники.
    >
    > >  :)
    >
    > Ух её моё. А в где в сабже речь шла о наследниках каких-
    > то компонент?


    Может внимательнее посмотреть мой пост [14].

    P.S.

    Я собственно слежу за этой темой давно (как и за многими другими мне потенциально интересными) и специально не высказывался поскольку автора темы устроил вариант решения.
    Но позже была приведена ссылка на решение из книге в общем виде.
    На нее я и отреагировал указав на возможные проблемы.

    По остальной части поста [25] без комментариев.
  • Германн © (18.02.10 03:19) [28]

    > ffff ©   (18.02.10 03:04) [27]
    >
    >
    > > Германн ©   (18.02.10 02:46) [26]
    > >
    > > > Классы наследники Ваших компонентов, а не Ваши наследники.
    >
    > >
    > > >  :)
    > >
    > > Ух её моё. А в где в сабже речь шла о наследниках каких-
    >
    > > то компонент?
    >
    >
    > Может внимательнее посмотреть мой пост [14].
    >
    > P.S.
    >
    > Я собственно слежу за этой темой давно (как и за многими
    > другими мне потенциально интересными) и специально не высказывался
    > поскольку автора темы устроил вариант решения.
    > Но позже была приведена ссылка на решение из книге в общем
    > виде.

    Ну и зря отреагировал. :)
    Кстати. Могу процитировать советского классика журналистики.
  • oxffff © (18.02.10 03:34) [29]

    > Германн ©   (18.02.10 03:19) [28]


    Есть общие решения одни, а есть общие решения корректные.
  • oxffff © (18.02.10 03:48) [30]

    > Германн ©  


    Обычно людям проще применить доступное им решение.
    И потом невдумываясь в различия применять это решение налево и направо(как повторно используемый код). Это мина замедленного действия.
    Я не упрекаю ИШ и АГ (более того я не совмеваюсь в их профессионализме при решении с теми подводными камнями).
    Но форум читают(и студенты бездумно берут решения налево и направо, потом вырастают и тиражируют себе подобных). Потом идут работать.

    Я с этим сталкиваюсь постоянно, и понимаю что люди поверхностно представляют  себе вообще что происходит в их программе или более того вообще не правильно представляют. И от этого становится грустно.
    Но это пройдет.
  • Sha © (18.02.10 09:47) [31]
    > Я с этим сталкиваюсь постоянно, и понимаю что люди поверхностно
    > представляют  себе вообще что происходит в их программе или более того
    > вообще не правильно представляют. И от этого становится грустно.

    +1
  • Вася (18.02.10 10:36) [32]

    > Плохиш ©   (18.02.10 00:54) [19]


    > DVM ©   (17.02.10 15:02) [11]
    >
    >


    Я имел в виду, что если мы посмотрим реализацию метода Free, мы увидим ,что оказывается можно разрушить объект, находясь внутри его метода непосредственно вызовом деструктора.
    А Германн утверждает в [7], что единственный способ - через PostMessage
  • Плохиш © (18.02.10 11:41) [33]

    > Вася   (18.02.10 10:36) [32]

    > Я имел в виду, что если мы посмотрим реализацию метода Free,
    >  мы увидим ,что оказывается можно разрушить объект, находясь
    > внутри его метода

    Вообще-то здесь речь идёт о разрущении объекта в обработчике его событий.
  • Игорь Шевченко © (18.02.10 12:11) [34]
    oxffff ©   (18.02.10 03:48) [30]


    > Я с этим сталкиваюсь постоянно, и понимаю что люди поверхностно
    > представляют  себе вообще что происходит в их программе
    > или более того вообще не правильно представляют. И от этого
    > становится грустно.


    Поддерживаю.

    Но может пусть пока начнут представлять с относительно простых вещей (типа нотификации через PostMessage), а после уже и до перекрытых методов Dispatch (if any) дойдут.

    И кстати, вопрос к владельцам книги Антона Григорьева - там действительно написано так, как в посте [12] ?
  • Riply © (18.02.10 13:17) [35]
    > [34] Игорь Шевченко ©   (18.02.10 12:11)
    > И кстати, вопрос к владельцам книги Антона Григорьева - там действительно написано так, как в посте [12] ?

    Если я нашла именно то место, что имеется ввиду, то нет.
    Основные отличия:
    1. PostMessge, а не SendMessage (с подробным объяснением почему именно так, кстати)
    2. Большое дополнение, обясняющее в каких случаях данный метод не работает,
      вместе с резюме "Общих решений таких проблем, по видимому не существует"
  • Riply © (18.02.10 13:21) [36]
    > [35] Riply ©   (18.02.10 13:17)
    > Если я нашла именно то место, что имеется ввиду, то нет.

    Глава 1.2.6 Листинг 1.33
  • Leonid Troyanovsky © (18.02.10 13:26) [37]

    > Riply ©   (18.02.10 13:21) [36]

    А объяснения с Application.ProcessMessages и/или диалогом есть?

    --
    Regards, LVT.
  • Riply © (18.02.10 13:34) [38]
    >  [37] Leonid Troyanovsky ©   (18.02.10 13:26)
    > А объяснения с Application.ProcessMessages и/или диалогом есть?

    С Application.ProcessMessages есть.

    Там много (более трех страниц посвещено этому вопросу) - долго все перепечатывать.
    Sorry.
  • Leonid Troyanovsky © (18.02.10 13:37) [39]

    > Riply ©   (18.02.10 13:34) [38]

    > Sorry.

    Да чего там :)
    В свое время наобсуждались.

    --
    Regards, LVT.
  • Leonid Troyanovsky © (18.02.10 14:34) [40]

    > Riply ©   (18.02.10 13:17) [35]

    >  вместе с резюме "Общих решений таких проблем, по видимому
    > не существует"

    Мы тут как-то не очень давно с ИШ обсуждали похожую тему,
    и я предлагал примерно такой вариант, во многом свободный от
    недостатков PostMessage:

    type
     EForceFreeException = class(Exception)
     private
       DestroyedObject: TObject;
       function This: EForceFreeException;
     end;

    function EForceFreeException.This;
    begin
     Result := Self;
    end;

    procedure TForm1.Button1Click(Sender: TObject);
    begin
     with EForceFreeException.Create('Free: '+(Sender as TButton).Caption) do
       begin
         DestroyedObject := Sender;
         raise This;
       end;
     Application.ProcessMessages;
    end;

    procedure TForm1.ApplicationEvents1Exception(Sender: TObject;
     E: Exception);
    begin
     if E is EForceFreeException then
       begin
         EForceFreeException(E).DestroyedObject.Free;
         Application.ShowException(E);
       end;
    end;


    Про не гуевы приложения особо не задумывался.

    --
    Regards, LVT.
  • oxffff © (18.02.10 15:09) [41]

    > procedure TForm1.Button1Click(Sender: TObject);
    > begin
    >  with EForceFreeException.Create('Free: '+(Sender as TButton).
    > Caption) do
    >    begin
    >      DestroyedObject := Sender;
    >      raise This;
    >    end;
    >  Application.ProcessMessages;
    > end;


    Что это?
    Назначение строчки не раскрыто.
  • Leonid Troyanovsky © (18.02.10 15:20) [42]

    > oxffff ©   (18.02.10 15:09) [41]

    > Назначение строчки не раскрыто.

    У Post*Message/Release на этом месте возникают проблемы.
    А, во-ще, что там стоит уже не важно.

    Вот и то обсуждение:
    http://www.delphimaster.net/view/2-1192180654/40-79

    Как оказалось, что кроме ИШ там многие поучаствовали ;)

    --
    Regards, LVT.
  • oxffff © (18.02.10 15:28) [43]

    > Leonid Troyanovsky ©   (18.02.10 15:20) [42]
    >
    > > oxffff ©   (18.02.10 15:09) [41]
    >
    > > Назначение строчки не раскрыто.
    >
    > У Post*Message/Release на этом месте возникают проблемы.
    >


    Я не понял о каких проблемах. Ведь это недостижимый код.

    >А, во-ще, что там стоит уже не важно.
    И я про это. :)
  • Leonid Troyanovsky © (18.02.10 15:34) [44]

    > oxffff ©   (18.02.10 15:28) [43]

    > Я не понял о каких проблемах. Ведь это недостижимый код.

    Ну, чего там непонятного. Сначало было

    procedure TForm1.Button1Click(Sender: TObject);
    begin
      Release;
      Application.ProcessMessages;
    end;


    Потом я вспоминал, что должно быть вместо Release.
    А строчка так и осталась. Считай, для сравнения.

    --
    Regards, LVT.
  • Leonid Troyanovsky © (18.02.10 16:09) [45]

    > oxffff ©   (18.02.10 15:28) [43]

    > И я про это. :)

    А..вот, еще кое-что вспомнил.
    Чтобы корректно обработать еще пару объектов:

    procedure TForm1.ApplicationEvents1Exception(Sender: TObject; E: Exception);
    begin
     if E is EForceFreeException then
       with  EForceFreeException(E) do
         if (DestroyedObject = Application.MainForm) or
            (DestroyedObject = Application) then
           Application.Terminate
         else
           DestroyedObject.Free;
     Application.ShowException(E);
    end;


    --
    Regards, LVT.
 
Конференция "Основная" » Разрушение объекта при двойном щелчке на объекте
Есть новые Нет новых   [134469   +12][b:0.001][p:0.002]