На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
! ПРАВИЛА РАЗДЕЛА · FAQ раздела Delphi · Книги по Delphi
Обязательно выделяйте текст программы тегом [сode=pas] ... [/сode]. Для этого используйте кнопку [code=pas] в форме ответа или комбобокс, если нужно вставить код на языке, отличном от Дельфи/Паскаля.

Этот раздел предназначен для вопросов, посвященных разработке компонентов, а также для тестирования собственных бесплатных компонентов с открытым исходным кодом.

Здесь запрещается:
1. Размещать ссылки на какие-либо коммерческие компоненты, реализующие требуемую функциональность.
2. Обсуждать и тестировать коммерческие компоненты или компоненты с закрытым кодом.
3. Давать ссылки на сайты с исходным кодом компонентов. Все тестируемые исходные коды должы быть размещены на сайте ИСХОДНИКИ.RU.
Модераторы: Rouse_, DimaBr
  
> "Чужие" события , Можно ли обработать
    Добрый день.
    Подскажите, можно ли реализовать реакцию своего компонента на события других компонентов.
    Идея такова: в DataSet происходит событие AfterScroll а мой компонент подменяет назначеный обработчик своим, который в свою очередь вызывает назначеный.
    При создании компонента динамически все отработало как нужно, но при размещении его в Дизайн тайме, обработчик не заменяется, потому что мой компонент создается раньше ДатаСета.

    Отсюда возникает вопрос, как реализовать "отложеное" присваивание свойств?
    Или есть другие методы?
      Вообще можно решить вопрос каковым его ставишь:
      Цитата TCrash @
      Подскажите, можно ли реализовать реакцию своего компонента на события других компонентов.
      Идея такова: в DataSet происходит событие AfterScroll а мой компонент подменяет назначеный обработчик своим, который в свою очередь вызывает назначеный.

      Но поясни то, откуда он у тебя возник:
      Цитата TCrash @
      При создании компонента динамически все отработало как нужно, но при размещении его в Дизайн тайме, обработчик не заменяется, потому что мой компонент создается раньше ДатаСета.

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

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

        В отладке выяснено, что мой компонент подменяет обраоботчик датасета, но потом, очевидно, датасету назначается обработчик, прописаный в дизайн тайме.

        Морочить голову с очередностью создания объектов (IMHO) не правильно.
        Есть ли готовые методы (алгоритмы) для подобной подмены обработчиков?
          А зачем всё так усложнят, а не писать код прямо в обработчике датасета?

          Добавлено
          Да и конечного пользователя запутывать.
          Вот например создаст обработчик события датасета а его перекроет твой и получится кака.
          Или может я ошибаюсь?
            код моего обработчика

            ExpandedWrap disabled
              // my code
              if assigned(OldDSetAfterScroll) then OldDSetAfterScroll(DataSet);


            А прописывать вызов методов компонента в событии датасета.... тогда зачем компонент?
            Сообщение отредактировано: TCrash -
              TCrash, кажись ты чего-то намудрил в своем компоненте.
              У меня вроде все работает, по крайней мере не смог добиться чтобы не работало :unsure:
              Для теста создал вот такую заготовку компонента насколько смог тебя понять:
              ExpandedWrap disabled
                unit UCatcher;
                 
                interface
                 
                uses
                  Classes, DB;
                 
                type
                  TDataSetEventsCatcher = class(TComponent)
                  strict private
                    FDataSet: TDataSet;
                    FOldAfterScroll: TDataSetNotifyEvent;
                    FOwnAfterScroll: TDataSetNotifyEvent;
                  strict protected
                    procedure SetDataSet(DataSet: TDataSet);
                    procedure SetAfterScroll(AfterScroll: TDataSetNotifyEvent);
                    procedure CatchAfterScroll(DataSet: TDataSet);
                  published
                    property DataSet: TDataSet read FDataSet write SetDataSet;
                    property AfterScroll: TDataSetNotifyEvent read FOwnAfterScroll write SetAfterScroll;
                  end;
                 
                procedure Register();
                 
                implementation
                 
                procedure Register();
                begin
                  RegisterComponents('Doubtful Components', [TDataSetEventsCatcher]);
                end;
                 
                { TDataSetEventsCatcher }
                 
                procedure TDataSetEventsCatcher.SetDataSet(DataSet: TDataSet);
                begin
                  if (FDataSet <> DataSet) then
                  begin
                    if (FDataSet <> nil) then
                      FDataSet.AfterScroll := FOldAfterScroll;
                    FDataSet := DataSet;
                    FOldAfterScroll := nil;
                    if ((DataSet <> nil) and (not (csDesigning in DataSet.ComponentState))) then
                    begin
                      FOldAfterScroll := DataSet.AfterScroll;
                      if (@FOwnAfterScroll <> nil) then
                      begin
                        if (@DataSet.AfterScroll = nil) then
                          DataSet.AfterScroll := FOwnAfterScroll
                        else
                          DataSet.AfterScroll := CatchAfterScroll;
                      end;
                    end;
                  end;
                end;
                 
                procedure TDataSetEventsCatcher.SetAfterScroll(AfterScroll: TDataSetNotifyEvent);
                begin
                  FOwnAfterScroll := AfterScroll;
                  if ((DataSet <> nil) and (not (csDesigning in DataSet.ComponentState))) then
                  begin
                    if (@FOwnAfterScroll <> nil) then
                    begin
                      if (@DataSet.AfterScroll = nil) then
                        FDataSet.AfterScroll := FOwnAfterScroll
                      else
                        FDataSet.AfterScroll := CatchAfterScroll;
                    end
                    else
                      FDataSet.AfterScroll := FOldAfterScroll;
                  end;
                end;
                 
                procedure TDataSetEventsCatcher.CatchAfterScroll(DataSet: TDataSet);
                begin
                  if (@FOwnAfterScroll <> nil) then
                    FOwnAfterScroll(DataSet);
                  if (@FOldAfterScroll <> nil) then
                    FOldAfterScroll(DataSet);
                end;
                 
                end.

              Проверял так:
              ExpandedWrap disabled
                procedure TForm1.ADODataSet1AfterScroll(DataSet: TDataSet);
                begin
                  ShowMessage('Я обработчик, назначенный ДатаСету в инспекторе объектов!');
                end;
                 
                procedure TForm1.DataSetEventsCatcher1AfterScroll(DataSet: TDataSet);
                begin
                  ShowMessage('Я обработчик, назначенный ЛовцуСобытий!');
                end;



              Ну а по честному VahaC прав.
              Решение так себе. Потому как против динамического переприсваивания AfterScroll'a ДатаСету оно бессильно. И однажды даже ты сам можешь наступить на эти грабли. Я уж не говорю о том, что такой компонент нельзя распространять среди других разработчиков, собственно по озвученной причине - чтобы не подставить их под битье головой об стену в непонятках "а что же тут не работает-то?... :wall:"

              Да и вообще не понятно, зачем потребовалось хранить по сути две части одного и того же кода в разных местах (обработчиках)? :wacko:
              Есть другие способы добиться твой цели, но те что я знаю тоже за гранью стандартности и универсальности. Компонент, на основе любого из них, я бы использовать не стал.
              Сообщение отредактировано: arj99 -
                Цитата arj99 @
                Отсюда возникает вопрос, как реализовать "отложеное" присваивание свойств?

                Перекрыть метод Loaded
                0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                0 пользователей:


                Рейтинг@Mail.ru
                [ Script execution time: 0,0266 ]   [ 16 queries used ]   [ Generated: 3.05.24, 04:16 GMT ]