Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > Компоненты и классы
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 25.05.2023, 22:12
Аватар для Uniq!
Uniq! Uniq! вне форума
Местный
 
Регистрация: 29.09.2010
Сообщения: 539
Версия Delphi: Delphi XE3
Репутация: 374
По умолчанию Два фрейма собранных в Designtime и две функции

Здравствуйте.

Стандартная (в каком-то смысле) задача: выбирая очередную запись из combobox меняется интерфейс программы. Аля выбрали в списке "редактирование справочника А", ниже прогрузился фрейм с полями этого справочника. Выбрали редактирование справочника Б - второй фрейм подгрузился. Оба фрейма созданы и упакованы в соответствующие юниты в режиме design-time.

Аля модуль обработки данных под названием А привязан к фрейму и его классу TFrameA, а обработка B так же к TFrameB. Оба унаследованы от TFrame

Создавая фреймы так же были созданы две функции с одинаковыми именами EditAndSave(): integer, которые выполняют РАЗНЫЕ преобразования с данными на фреймах, но возвращают однотипный результат в виде кода ошибки (статуса)

Архитектурно в голове сидит мысль о том, что надо завести переменную, в которой я буду хранить экземпляр текущего активного фрейма, и обращаясь через неё к функции. НО!

Во-первых, какой тип этой переменной должен быть? Ведь фреймы разных классов. Один от TFrameA, второй от TFrameB.
Во-вторых, функция имея одно и тоже название должна быть ... virtual? abstract? overload?

Найдутся тут сеньёоры, понимающие весь этот глубокий мир ООП?

Последний раз редактировалось Uniq!, 25.05.2023 в 23:10.
Ответить с цитированием
  #2  
Старый 26.05.2023, 19:09
lmikle lmikle вне форума
Модератор
 
Регистрация: 17.04.2008
Сообщения: 8,015
Версия Delphi: 7, XE3, 10.2
Репутация: 49089
По умолчанию

Думаешь в правильном направлении. У этих фреймов должен быть общий предок, в котором данная фунция должна быть virtual; abstract;
Код:
unit frmEditFrameBase;

type
  TEditFrameBase = class(TFrame)
  ...
  public
    function EditAndSave() : Boolean; virtual; abstract;
Код:
unit frmEditFrameA;

uses frmEditFrameBase;

type
  TEditFrameA = class(TEditFrameBase)
  ...
  public
    function EditAndSave() : Boolean; override;
  ...

function TEditFrameA.EditAndSave() : Boolean;
begin
  // Do for FrameA
  // Do not call inherited here due to this method is abstract in the parent
end;
Код:
unit frmEditFrameB;

uses frmEditFrameBase;

type
  TEditFrameB = class(TEditFrameBase)
  ...
  public
    function EditAndSave() : Boolean; override;
  ...

function TEditFrameB.EditAndSave() : Boolean;
begin
  // Do for FrameB
  // Do not call inherited here due to this method is abstract in the parent
end;
Теперь в основной программе можно создать переменную типа базового фрейма:
Код:
var
  myFrame : TEditFrameBase;
begin
  myFrame := TEditFrameA.Create(Nil);
  myFrame.EditAndSave;
  myFrame.Free;
  ...
  myFrame := TEditFrameB.Create(Nil);
  myFrame.EditAndSave;
  myFrame.Free;

PS. Для того, что бы не мучаться с ручным редактированием предка для фрейма (а его надо указать и в .pas и в .dfm файлах), есть визуальное наследование. Когда создаешь новую форму/фрейм, там в диалоге есть раздел с именем твоего приложения, в нем все формы и фреймы, которые ты уже создал. Просто кликаешь на нужной форме/фрейме и Delphi сама отнаследует от выбраного элемента. Кстати, так и контролы будут наследоваться, так что если у тебя на фрейме есть общая часть, ее можно отдизайнить на общем предке и в потомках добавлять только различия.

Последний раз редактировалось lmikle, 26.05.2023 в 19:14.
Ответить с цитированием
Этот пользователь сказал Спасибо lmikle за это полезное сообщение:
Uniq! (26.05.2023)
  #3  
Старый 31.05.2023, 01:30
Аватар для Uniq!
Uniq! Uniq! вне форума
Местный
 
Регистрация: 29.09.2010
Сообщения: 539
Версия Delphi: Delphi XE3
Репутация: 374
По умолчанию

Странное поведение наследуемого фрейма. См изображение с ошибкой.

Видимо IDE не понимает VCL или FMX фрейм я унаследовал у TFrame к своему типу TBaseFrame.

В dfm файле при этом все свойства есть, естественно, т.к. сама IDE их же и создаёт. Погуглил. Говорят мол "если вы создавали свой фрейм в более новой версии то... в старой ..." но я создаю всё в одной и той же версии
https://delphisources.ru/forum/attac...d=168548578 9

Код:
object fDateEditFrame: TfDateEditFrame
  Left = 0
  Top = 0
  ClientHeight = 201
  ClientWidth = 304
  Color = clAppWorkSpace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'Tahoma'
  Font.Style = []
  OldCreateOrder = True
  PixelsPerInch = 96
  TextHeight = 13

Ругается на ClientHeight ClientWidth OldCreateOrder PixelsPerInch TextHeight.
Удаляя эти свойства я теряю структуру фрейма) и видимость компонент, зато запускается без ошибок

Куда подскажите копать?
Изображения
Тип файла: png изображение_2023-05-31_012731527.png (7.5 Кбайт, 4 просмотров)

Последний раз редактировалось Uniq!, 31.05.2023 в 01:34.
Ответить с цитированием
  #4  
Старый 31.05.2023, 02:25
lmikle lmikle вне форума
Модератор
 
Регистрация: 17.04.2008
Сообщения: 8,015
Версия Delphi: 7, XE3, 10.2
Репутация: 49089
По умолчанию

А как ты наследуешь?
Перечисли по шагам.
Ответить с цитированием
Этот пользователь сказал Спасибо lmikle за это полезное сообщение:
Uniq! (31.05.2023)
  #5  
Старый 31.05.2023, 10:20
Аватар для Uniq!
Uniq! Uniq! вне форума
Местный
 
Регистрация: 29.09.2010
Сообщения: 539
Версия Delphi: Delphi XE3
Репутация: 374
По умолчанию

Вчера удалось "завести" путём следующих итераций:
1) New - Other - Frame - именуем его как TBaseFrame
2) Добавляем в его паблик нужное виртуальное абстрактное
3) Создаём ещё два через New - Other - Frame, руками меняю TFrame на TBaseFrame
4) Переопределяем нужное
5) в dfm файлах в первой строчке меняю object на inherited
...
6) Profit

А изначально было: вместо 1го пункта, я просто создал unit и в нём определил TBaseFrame. Т.е. у такого варианта не было dfm части.

Переспал с проблемой и понял, о чём был ваш комментарий по поводу наследования через IDE, а не руками... Если TBaseFrame создать тоже через IDE со своим dfm, то при создании наследников в п.3 этот TBaseFrame появится в качестве опции для наследования. И inherited в dfm прописывается самостоятельно...

Так что в целом вопрос решён.) Спасибо, ещё раз!

Последний раз редактировалось Uniq!, 31.05.2023 в 10:30.
Ответить с цитированием
  #6  
Старый 31.05.2023, 17:50
lmikle lmikle вне форума
Модератор
 
Регистрация: 17.04.2008
Сообщения: 8,015
Версия Delphi: 7, XE3, 10.2
Репутация: 49089
По умолчанию

Вот!!!
Надо делать правильно
Ну работает - и хорошо.
Ответить с цитированием
Ответ


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 00:09.


 

Сайт

Форум

FAQ

RSS лента

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2023

ВКонтакте   Facebook   Twitter