2015-01-28 8 views
2

Мне интересно, можно ли в Delphi определить базовый класс формы, полученный из TForm с общим. Приложение, над которым я работаю, взаимодействует с различными аппаратными устройствами (через последовательный порт, usb, ethernet и т. Д.), И я хочу, чтобы каждое устройство могло отображать форму свойства, содержащую свойства, специфичные для этого устройства.Delphi - TForm и generics

До сих пор у меня есть следующий код ...

// DEVICE MODEL... 

// Interface defining a device 
IDevice = interface 
    procedure ShowPropertyForm; 
    // ... Other procedures and functions 
end; 

// Abstract base device class 
TDevice = class(IDevice) 
    protected 
     // Override this function to show their property form 
     procedure DoShowPropertyForm; virtual; abstract; 

    public 
     // Calls Self.DoShowPropertyForm; 
     procedure ShowPropertyForm; 
end; 

TSerialDevice = class(TDevice) 
    protected 
     // Creates and shows the TSerialDeviceForm below 
     procedure DoShowPropertyForm; override; 
end; 

// Represents a device capable of providing positioning information 
TGpsDevice = class(TSerialDevice) 
    protected 
     // Creates and shows the TGpsDeviceForm below 
     procedure DoShowPropertyForm; override; 
end; 

// FORM MODEL... 

// Represents a base form, with skinning functionality, etc 
TBaseForm = class(TForm) 

end; 

// Base device properties form, allows the form to access a strongly-typed 
// version of the IDevice 
TDeviceForm<T : IDevice> = class(TBaseForm) 

    private 
     FDevice : T; 

    public 
     // Accessor for the associated IDevice 
     property Device : T read FDevice write FDevice; 
end; 

// Property form for a TSerialDevice, has controls for controlling port name 
// baud rate, stop/start bits, etc 
TSerialDeviceForm = class(TDeviceForm<TSerialDevice>) 

end; 

// Property form for a TGpsDevice, has controls in addition to what is 
// provided by the TSerialDeviceForm 
TGpsDeviceForm = class(TSerialDeviceForm) 

end; 

Проблема возникает, когда пытаются получить доступ дизайнера форм. Например, TBaseForm содержит кнопку «ОК» и «Отмена». Я хочу добавить дополнительные функции в TDeviceForm, однако, когда я пытаюсь открыть конструктор, появляется следующая ошибка ...

Ошибка создания формы: Класс корня не найден: "".

Точно так же, если я пытаюсь открыть дизайнер TGpsDeviceForm, я получаю следующее сообщение об ошибке ...

Ошибка создания формы: Предок для «TSerialDeviceForm» не найден.

Я предполагаю, что разработчик форм Delphi не может обрабатывать дженерики, но может ли быть лучший способ решить эту проблему?

В файлах DFM, за все, кроме TBaseForm, я изменил первую линию от:

объекта DeviceForm: TDeviceForm к унаследованной DeviceForm: TDeviceForm

Однако это кажется, не имеет значения.

Пожалуйста, можете предложить любой совет? Спасибо заранее!

+0

Насколько я знаю, наследование визуальной формы не может использоваться с родовыми типами. –

+0

Спасибо за ваш ответ. У меня было ощущение, что это могло быть так, хотя вчера я дошел до того, что смог получить доступ к разработчикам форм таких вещей, как TSerialDeviceForm и TGpsDeviceForm, но сегодня утром он не играет в мяч - должно быть, чистое везение! – weblar83

+0

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

ответ

0

В настоящий момент Delphi не поддерживает наличие дженериков в файлах DFM. Однако, учитывая то, что вы объяснили в некоторых комментариях, я понял, что у вас проблема, похожая на ту, что у меня была в прошлом.

В моем случае, что я сделал, было сочетание наследования визуальной формы и использования фреймов. Будучи более конкретным, мне приходилось создавать иерархию форм и иерархию фреймов и использовать их вместе, чтобы иметь конкретную форму, которая должна быть способна работать с определенным объектом. Формы не очень сильно работали над определенным конкретным объектом, кадры отвечали за эту специфическую обработку.

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

Возможно, эта модель будет соответствовать вашим потребностям.

+0

Спасибо за ваши комментарии. Если я правильно понял, это были ваши фреймы, которые имели функциональность для работы с конкретными объектами? Я придумал решение, которое, похоже, работает, за вычетом дженериков, поэтому нет проверки типов. Не совсем уверен, как опубликовать его здесь, так как это не «ответ», а достаточно хороший для того, что мне нужно. – weblar83

+0

Правильно, фреймы предназначены для работы с определенными объектами. Внутри кода кадров проверка типов гарантируется компилятором. Снаружи, в коде форм, проверка типов должна была быть во время выполнения, и в конечном итоге мне пришлось генерировать исключения. – AlexSC