gpt4 book ai didi

delphi - 调用不同形式的类函数

转载 作者:行者123 更新时间:2023-12-01 21:59:44 26 4
gpt4 key购买 nike

我有一个应用程序,其中包括“主”表单以及其他四个表单(formA、formB、formC、formD)。四种形式中的每一种都有一个唯一的类函数execute()

现在,在 formD 中,我放置了一个编辑框和一个按钮。在按钮的 OnClick 事件上,根据我在编辑框中传递的表单名称,我想运行适当的类函数。

我尝试通过创建一个 TDictionary 来实现此任务,在其中添加 3 对值,但它不起作用。具体来说,我做了以下工作:

unit FormDU;

interface

type
TFormD = class(TForm)
Edit1: TEdit;
fcShapeBtn1: TfcShapeBtn;
.............
.............
public
class function execute:boolean;
..........
..........
end;

var
FormD: TFormD;
MyList:TDictionary<string,TForm>;


implementation

class function TFormD.execute:boolean;
begin
FormD:= TFormD.Create(nil);
MyList:= TDictionary<string,TForm>.create;
MyList.Add('FormA',TFormA);
MyList.Add('FormB',TFormB);
MyList.Add('FormC',TFormC);
FormD.showmodal;
end;

procedure TFormD.fcShapeBtn1Click(Sender: TObject);
begin
// Here I check whether the text in Edit1 box has the value of one of the
// keys that are included in the MyList dictionary and if yes I want to
// trigger the class function execute of the appropriate form...

if MyList.ContainsKey(Edit1.text) then // suppose that text= formA
MyList.Items[Edit1.text].execute // which doesn't work....

// I thought that the 'Items' method of the dictionary would return back
// to me the appropriate form type - which is connected to the specific
// key - and thus I could call each form's class function execute()
end;

我不知道如何解决这个问题。

最佳答案

您的方法有两个问题:

  1. 您的 TDictionary 被声明为保存 TForm 对象指针,但您的代码尝试插入 TForm 派生类类型。那不会编译。

  2. 您的 Form 类并非派生自具有可供重写的 Execute() 方法的公共(public)基类。因此,您不能只从 TDictionary 中检索值并直接调用 Execute。您将不得不求助于使用 RTTI 来查找并调用 Execute()

有一些可能的方法来解决这个问题:

  1. 从公共(public)基类派生您的 Form 类,并将该基类的派生存储在您的 TDictionary 中:

    unit FormBaseU;

    interface

    uses
    Forms;

    type
    TFormBase = class(TForm)
    public
    class function Execute: Boolean; virtual;
    end;

    TFormBaseClass = class of TFormBase;

    implementation

    class function TFormBase.Execute: Boolean;
    begin
    Result := False;
    end;

    end.

    unit FormDU;

    interface

    uses
    ..., FormBaseU;

    type
    TFormD = class(TFormBase)
    Edit1: TEdit;
    fcShapeBtn1: TfcShapeBtn;
    ...
    public
    class function Execute: Boolean; override;
    ...
    end;

    var
    FormD: TFormD;
    MyList: TDictionary<string, TFormBaseClass>;

    implementation

    uses
    FormAU, FormBU, FormCU;

    class function TFormD.Execute: Boolean;
    begin
    MyList := TDictionary<string, TFormBaseClass>.Create;

    // make sure TFormA, TFormB, and TFormC all derive
    // from TFormBase and override Execute() ...
    MyList.Add('FormA', TFormA);
    MyList.Add('FormB', TFormB);
    MyList.Add('FormC', TFormC);

    FormD := TFormD.Create(nil);
    FormD.ShowModal;
    FormD.Free;
    end;

    procedure TFormD.fcShapeBtn1Click(Sender: TObject);
    var
    FormClass: TFormBaseClass;
    begin
    if MyList.TryGetValue(Edit1.Text, FormClass) then
    FormClass.Execute;
    end;
  2. 做类似的事情,但使用接口(interface)而不是基类(但这仅适用于对象,不适用于类类型):

    unit MyIntfU;

    interface

    type
    IMyIntf = interface
    ['{41BEF2B6-C27F-440E-A88B-9E5CF8840034}']
    function Execute: Boolean;
    end;

    implementation

    end.

    unit FormDU;

    interface

    uses
    ..., MyIntfU;

    type
    TFormD = class(TForm, MyIntf)
    Edit1: TEdit;
    fcShapeBtn1: TfcShapeBtn;
    ...
    public
    function Execute: Boolean;
    ...
    end;

    var
    FormD: TFormD;
    MyList: TDictionary<string, TForm>;

    implementation

    uses
    FormAU, FormBU, FormCU;

    function TFormD.Execute: Boolean;
    begin
    MyList := TDictionary<string, TForm>.Create;

    // make sure TFormA, TFormB, and TFormC are all
    // instantiated beforehand and implement IMyIntf ...
    MyList.Add('FormA', FormA);
    MyList.Add('FormB', FormB);
    MyList.Add('FormC', FormC);

    FormD := TFormD.Create(nil);
    FormD.ShowModal;
    FormD.Free;
    end;

    procedure TFormD.fcShapeBtn1Click(Sender: TObject);
    var
    Form: TForm;
    Intf: IMyIntf;
    begin
    if MyList.TryGetValue(Edit1.Text, Form) then
    begin
    if Supports(Form, IMyIntf, Intf) then
    Intf.Execute;
    end;
    end;
  3. 根本不要在 TDictionary 中存储类/对象,而是存储实际的类方法:

    unit FormDU;

    interface

    uses
    ...;

    type
    TFormD = class(TForm)
    Edit1: TEdit;
    fcShapeBtn1: TfcShapeBtn;
    ...
    public
    class function Execute: Boolean;
    ...
    end;

    TMyClassMethod = function: Boolean of object;

    var
    FormD: TFormD;
    MyList: TDictionary<string, TMyClassMethod>;

    implementation

    uses
    FormAU, FormBU, FormCU;

    class function TFormD.Execute: Boolean;
    begin
    MyList := TDictionary<string, TMyClassMethod>.Create;

    MyList.Add('FormA', TFormA.Execute);
    MyList.Add('FormB', TFormB.Execute);
    MyList.Add('FormC', TFormC.Execute);

    FormD := TFormD.Create(nil);
    FormD.ShowModal;
    FormD.Free;
    end;

    procedure TFormD.fcShapeBtn1Click(Sender: TObject);
    var
    Meth: TMyClassMethod;
    begin
    if MyList.TryGetValue(Edit1.Text, Meth) then
    Meth;
    end;

关于delphi - 调用不同形式的类函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49434666/

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