2016-12-18 2 views
2

У меня есть проект, имеющий две формы с одинаковым именем. Мне нужно использовать тот или иной. Я предположил, что могу использовать IFDEF, чтобы различать их, но я считаю, что не могу добавить их обоих в проект без жалобы компилятора. Предложение my uses выглядит так.Правильный способ использования форм с тем же именем

uses 
uFileManager, uMount, uSkyMap, uAntenna, 
{$IFDEF SDR} 
uSDR, 
{$ENDIF} 
{$IFDEF R7000Serial} 
uR7000, 
{$ENDIF} 
uDatabase; 

{$R *.dfm} 

И «uSDR» и единицы в «uR7000» имеют форму с именем «Получатель» в них. Когда я пытаюсь добавить модуль «uR7000», я получаю: «Проект уже содержит форму или модуль с именем Receiver»

Как добавить оба устройства в проект?

+8

Дайте им разные названия –

+4

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

+3

Вы просто создаете проблему для себя, пытаясь использовать две формы с тем же именем. Хотя вы могли бы использовать IFDEF свой код в блоке sanme, вы не сможете сделать это с помощью своих файлов DFM. – MartynA

ответ

5

Прежде всего, это не компилятор, жалующийся, но IDE.

Компилятор все равно, если у вас есть формы или другие типы - с тем же именем, если они находятся в разных единицах. Известным примером из VCL было наличие двух типов TBitmap, один в Графика другая в Windows. Если вам когда-либо понадобится быть явным в отношении того, какой тип вы имеете в виду, вы просто квалифицируете имя типа в коде и компилятор делает, как сказано.

bmpA: Graphics.TBitmap; // bmpA is a TBitmap as defined in the Graphics unit 
bmpB: Windows.TBitmap; // bmpB is a TBitmap as defined in the Windows unit 

Проблем нет.

Однако рамки сохранения в Delphi делает помощи, если у вас есть постоянных классов с таким же именем, так как структура живучести определяет типы только их неквалифицированного имени.

Именно поэтому каждая сторонняя структура компонента для Delphi использует префикс для своих имен классов. Это не просто тщеславие или мода. Это гарантирует, что компонент в одной библиотеке нельзя путать (с помощью механизмов сохранения Delphi) с другим из другой библиотеки, если обе библиотеки используются в одном проекте.

Итог: Придерживайтесь уникальных имен для ваших форм и найдите другой способ различать или переключаться между ними, если это необходимо.

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

Например (и это только иллюстративный эскиз, не является рекомендацией или полностью работал раствор):

// Define the interface that your Receiver implementations 
// must satisfy. This might include returning a reference to the implementing form. 
// 
// e.g. in a unit "uiReceiver" 

type 
    IReceiver = interface 
    function Form: TForm; // returns the form using the common base type, not the specific implementation class 
    end; 


// in unit uSDR 
TfrmSDRReceiver = class(TForm, IReceiver) 
    ..implements IReceiver as well as your SDR specific needs 
end; 

// in unit u7000 
TfrmR7000SerialReceiver = class(TForm, IReceiver) 
    ..implements IReceiver as well as your R7000 Serial specific needs 
end; 


// In uReceiver (some unit to "resolve" the receiver) 
interface 

uses 
    uSDR, 
    uR7000; 

    type 
    TReceiver = class 
     class function GetReceiver: IReceiver; 
    end; 

implementation 

    class function TReceiver.GetReceiver: IReceiver; 
    begin 
    {$ifdef SDR} 
    result := frmSDRReceiver; 
    {$endif} 
    {$ifdef R7000} 
    result := frmR7000SerialReceiver; 
    {$endif} 
    end; 

end. 

Ваш код приложения затем использует uReceiver блок (и uiReceiver если вы хотите обратиться к типу интерфейса, например, в объявлении переменной) и обращается к конкретному приемнику через статический класс, например:

uses 
    uReceiver; 


implementation 

    uses 
    uiReceiver; 


    .. 
    var 
    rcvr: IReceiver; 
    begin 
    rcvr := TReceiver.GetReceiver; 

    rcvr.... // work with your receiver through the methods/properties on the interface 

    // You can also work with the receiver form, accessing all aspects 
    // common to any TForm via the Form function on the interface (assuming 
    // you chose to provide one): 

    rcvr.Form.Show; 

    .. 
    end; 
+0

Спасибо за этот ответ. Это проясняет недоразумение, которое у меня было очень долгое время. –