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

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

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

    Столкнулся с интересным фактом.

    После создания и загрузки всех компонентов произвожу подмену сплиттеров расширенным классом с дополнительным событием.
    При этом создается расширенный класс, переписываются все свойства и уничтожается старый.
    ExpandedWrap disabled
      procedure TAutoSavedForm.InitSplitters;
      var
        i: Integer;
      begin
        for i := ComponentCount - 1 downto 0 do
        begin
          if Components[i] is TSplitter then
          begin
            if not (Components[i] is TKvSplitter) then
              TKvSplitter.Replace(Components[i] as TSplitter).OnStopMoved := SplittersMoved;
          end;
        end;
       
      end;

    ExpandedWrap disabled
      class function TKvSplitter.Replace(ASplitter: TSplitter): TKvSplitter;
      var
        aParent : TWinControl;
        aName: TComponentName;
      begin
        Result := nil;
        if ASplitter = nil then
          Exit;
       
        Result := TKvSplitter.Create(ASplitter.Owner);
        aParent := ASplitter.Parent;
        if aParent <> nil then
          aParent.DisableAlign;
        try
          aName := ASplitter.Name;
          Result.Assign(ASplitter);
          ASplitter.Free;
          Result.Name := aName;
        finally
          if aParent <> nil then
            aParent.EnableAlign;
        end;
       
      end;


    Предполагал что после этого в формах наследниках обращение к сплитерам через переменные будет невозможно
    ExpandedWrap disabled
      type
        TMainSavedForm = class(TAutoSavedForm)
          Panel1: TPanel;
          Splitter1: TSplitter;
          Panel2: TPanel;
          Panel3: TPanel;
          Splitter2: TSplitter;
          procedure Splitter2Moved(Sender: TObject);
        private
          { Private declarations }
        public
          { Public declarations }
        end;
       
      //.....
       
      procedure TMainSavedForm.Splitter2Moved(Sender: TObject);
      begin
        inherited;
        Splitter2.Color := clGreen;
        Caption := Splitter2.Name + ' - ' + Splitter2.ClassName;
      end;


    Однако оказалось что все прекрасно работает.

    Вопрос знатокам - почему работает TMainSavedForm.Splitter2Moved после замены Сплиттеров?
    ( код прилагается - если будет какая-то критика - заранее благодарю )
    Прикреплённый файлПрикреплённый файлdelphiTools.zip (14.17 Кбайт, скачиваний: 168)
      Цитата sCreator @
      почему работает TMainSavedForm.Splitter2Moved после замены Сплиттеров?

      Цитата sCreator @
      ExpandedWrap disabled
        class function TKvSplitter.Replace(ASplitter: TSplitter): TKvSplitter;
        var
          aParent : TWinControl;
          aName: TComponentName;
        begin
           //...
            aName := ASplitter.Name;
           //..
            Result.Name := aName;
           //...
        end;

      Борланд предусмотрел эту ситуацию и при присвоении компоненту имени, ссылка в связанном с ним поле заменяется.
      Цитата Classes.pas
      ExpandedWrap disabled
        procedure TComponent.SetName(const NewName: TComponentName);
        begin
          if FName <> NewName then
          begin
            if (NewName <> '') and not IsValidIdent(NewName) then
              raise EComponentError.CreateResFmt(@SInvalidName, [NewName]);
            if FOwner <> nil then
              FOwner.ValidateRename(Self, FName, NewName) else
              ValidateRename(nil, FName, NewName);
            SetReference(False);
            ChangeName(NewName);
            SetReference(True);
          end;
        end;
         
        procedure TComponent.SetReference(Enable: Boolean);
        var
          Field: ^TComponent;
        begin
          if FOwner <> nil then
          begin
            Field := FOwner.FieldAddress(FName);
            if Field <> nil then
              if Enable then Field^ := Self else Field^ := nil;
          end;
        end;



      Цитата sCreator @
      если будет какая-то критика - заранее благодарю

      as после уже выполненной проверки is неэффективно, быстрее прямое приведение.
      но это мелочь.
      Сообщение отредактировано: arj99 -
        sCreatorа TJvFormStorage хуже?
          Цитата Frees @
          Борланд предусмотрел эту ситуацию и при присвоении компоненту имени, ссылка в связанном с ним поле заменяется.

          Вот так бродишь по исходам, а всего не увидишь. Спасибо большое за оперативную подсказку.
          Цитата arj99 @
          as после уже выполненной проверки is неэффективно, быстрее прямое приведение.

          Да это у меня такая привычка, никак не избавлюсь.
          Цитата Frees @
          sCreator а TJvFormStorage хуже?

          Может и не хуже, может лучше. Как-то ставил эту библиотеку компонентов, ну очень громоздкая. И возможно из-за нее D2009 у меня глючила ( а может просто дистрибутив такой попался ).
          Вообще не очень люблю пользоваться сторонними компонентами, тем более такими большими библиотеками - зачем добавлять в проекты чужие ошибки, когда можно создать свои ( и ошибки тоже ).
          Не хочется скатиться до уровня - "дайте компонент и я напишу самую крутую программу".
          Но идеи и опыт всегда воспринимаю и беру отдельные модули или участки ( легче избежать копирования чужих ошибок ).
          Обязательно посмотрю TJvFormStorage, исходники библиотеки на диске еще не стер.
          Смотрел PropStorageEh из EhLib - мне показалось тяжеловат для малых проектов в виду использования TypInfo.

          Всем большое спасибо.
            Немного осмысливаю информацию.

            Т.е. у нас получается тривиальный способ подмены стандартных компонентов?
            В отличии от оригинальных с подменой модулей и подстановкой расширенного компонента одноименного подменяемому.

            Единственное, что расширенный компонент должен уметь копировать published свойства подменяемого.
              Цитата sCreator @
              Может и не хуже, может лучше.

              мне просто кажется что возможности маловато..

              в TJvFormStorage (кстати еще такой же в RxLib) можно сохранить любое публичное свойство любого компонента... - оооочень удобно, даже в мелких проектах

              зы jde тоже не люблю...
              Сообщение отредактировано: Frees -
                Цитата Frees @
                мне просто кажется что возможности маловато..

                в TJvFormStorage (кстати еще такой же в RxLib) можно сохранить любое публичное свойство любого компонента... - оооочень удобно, даже в мелких проектах

                Возможности дело наживное - это я еще такого постепенно допишу туда, что как-бы самому не заблудиться ( это типа шутки - сильно спешить не буду ).

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

                Зато у меня фишка есть запоминание в двух позициях - в нормальном состоянии окна и развернутом на весь экран - способствует быстрому переключению. Правда, похоже еще не до конца додуманная, но это практика покажет и при необходимости домыслим.
                  там наворочено потому что тонкостей много... и то они не хотят на 100% правильно работать.
                    Цитата Frees @
                    там наворочено потому что тонкостей много... и то они не хотят на 100% правильно работать.

                    Вот это меня и пугает в таких библиотеках-монстрах.
                    0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                    0 пользователей:


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