gpt4 book ai didi

delphi - 使用同名表单的正确方法

转载 作者:行者123 更新时间:2023-12-03 18:20:53 25 4
gpt4 key购买 nike

我有一个项目,有两个同名的表单。我需要使用其中之一。我以为我可以使用 IFDEF 来区分它们,但我发现我无法将它们添加到项目中而不引起编译器的提示。我的 use 子句如下所示。

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

{$R *.dfm}

“uSDR”和“uR7000”设备中都有一个名为“接收器”的表单。当我尝试添加“uR7000”单元时,我得到的项目: “该项目已包含名为 Receiver 的表单或模块”

如何将两个单元添加到项目中?

最佳答案

首先,提示的不是编译器,而是 IDE。

编译器不关心您是否有具有相同名称的表单或其他类型,只要它们位于不同的单位即可。 VCL 的一个著名例子是存在两种 TBitmap 类型,一种在 Graphics 中,另一种在 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 持久性机制)与不同库中的另一个组件混淆。

底线:坚持为您的表单使用唯一的名称,并根据需要寻找其他方法来区分或在它们之间切换。

如果没有有关您的项目的更多详细信息,很难准确地建议如何管理对正在使用的特定表单的引用。您可以从一个公共(public)基类派生这两个类,也可以为每个类定义一个接口(interface)来实现。

例如(这只是一个说明性草图,不是建议或完整的解决方案):

// 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 单元(如果您想引用接口(interface)类型,例如在变量声明中,则使用 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;

关于delphi - 使用同名表单的正确方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41212631/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com