7

我想用另一个名为 MyTToolBar 的类来继承 TToolBar,以便我可以覆盖一个方法。我是 Delphi 的新手,但是在尝试了各种方法两个小时后,我无法使用 MyTToolBar 代替 TToolBar。我不能成为第一个想要覆盖可视组件类上的方法的人。

我更多来自 Xcode 背景,其中子类化视觉组件很容易。您创建父类(例如,MySuperClass)的子类(例如,MySubclass),然后只需在Xcode 的Interface Builder 视图中分配子类。子类被自动识别和使用。

为什么我似乎不能在 Delphi RAD Studio XE3 中执行此操作?

将 TToolBar 添加到 TForm 后,似乎无法更改类。我尝试通过 Object Inspector 以及 .PAS 源代码文件。如果我更改 .PAS 文件中的类,我会收到一条错误消息,提示工具栏“应为 Vcl.ComCtrls.TToolBar 类型,但声明为 MyTToolbar。更正声明?” 这只是看起来很愚蠢......

哦,我还使用了新组件向导,选择:文件 -> 新建 -> 其他 -> Delphi 项目 -> Delphi 文件 -> 组件。我选择 MyTToolBar 的祖先作为 TToolBar 并告诉它在“示例”调色板页面中注册。但是,它不会出现在“示例”页面中。

4

3 回答 3

18

与您的 XCode 方法最接近的方法是在 Delphi 中使用“interposer”类。基本上,您不会更改 IDE 为标准TToolBar用途创建的代码。相反,您声明了一个派生自标准TToolBar组件但也被命名的新类,并在声明标准TToolBar使其对编译器可见。编译器最后看到的任何类都将是在流式传输 DFM时实例化的实际类类型。TToolBarTToolBarTForm

您可以通过以下两种不同方式之一TToolBar使编译器在标准类之后看到您的自定义类:TToolBar

  1. TToolBar在与您的类相同的单元中声明自定义TForm类:

    unit MyForm;
    
    interface
    
    uses
      ..., Vcl.ComCtrls, ...;
    
    type
      TToolBar = class(Vcl.ComCtrls.TToolBar)
        // override what you need...
      end;
    
      TMyForm = class(TForm)
        ToolBar1: TToolBar; // <-- do not change this!
        ...
      end;
    
    implementation
    
    // implement custom TToolBar as needed...
    
    // normal TForm implementation code as needed ...
    
    end.
    
  2. 您可以TToolBar在其自己的单元中声明自定义类,然后在添加单元后将其添加到TForm单元的uses子句中ComCtrls

    unit MyToolBar;
    
    interface
    
    uses
      ..., Vcl.ComCtrls;
    
    type
      TToolBar = class(Vcl.ComCtrls.TToolBar)
        // override what you need...
      end;
    
    implementation
    
    // implement custom TToolBar as needed...
    
    end.
    

    .

    unit MyForm;
    
    interface
    
    uses
      ..., Vcl.ComCtrls, ..., MyToolBar;
    
    type
      TMyForm = class(TForm)
        ToolBar1: TToolBar; // <- do not change this!
        ...
      end;
    
    implementation
    
    // normal TForm implementation code as needed ...
    
    end.
    

这种方法仅适用于每个项目。如果您想TToolBar在多个项目中使用您的自定义类,那么您最好将它安装到 IDE 中,就像@KenWhite 描述的那样,并使用它而不是标准的TToolBar. 回到命名它TMyToolBar(或其他),不要再命名它TToolBar,因为它不会用作插入器。确保该包在其项目选项中标记为“运行时和设计时”(创建单独的仅运行时和仅设计时包超出了本讨论的范围)。 TMyToolBar将在设计时提供,您可以TForm像使用任何其他组件一样放置您的组件。如果不是,那么您没有正确设置它。

于 2013-02-09T00:31:47.617 回答
5

要更改现有表单上的组件,它实际上必须是 IDE 可以在设计时创建实例的组件。当然,这意味着 IDE 必须首先意识到这一点。

这样做的方法是创建您自己的后代组件,并将其实际安装到设计时包中的 IDE 中。然后,您可以将其放在您的表单上而不是标准版本上,或者通过一些工作将其替换到现有表单上。(不过,您必须先创建版本并安装它。)

File->New->Package (Delphi)从 IDE 的菜单开始。像保存任何其他项目一样保存包(例如,MyComponents.dpk)。

现在使用File->New->Other->Delphi Files,并Component在右窗格中双击。向导将New Component启动,您可以在其中选择要继承的现有组件(或设计新组件)。

按照向导的步骤操作,您最终将获得组件的基本外壳:

unit MyToolBar1;

interface

uses
  System.SysUtils, System.Classes, Vcl.Controls, Vcl.ToolWin, Vcl.ComCtrls;

type
  TMyToolBar = class(TToolBar)
  private
    { Private declarations }
  protected
    { Protected declarations }
  public
    { Public declarations }
  published
    { Published declarations }
  end;

procedure Register;

implementation

procedure Register;
begin
  RegisterComponents('Samples', [TMyToolBar]);
end;

end.

在新后代中实现您想要的任何功能,然后保存文件。

右键单击包中的Project Manager(默认情况下在 IDE 中的右上角窗口),然后Install从上下文菜单中选择。这将编译和构建包,并自动将其安装在 IDE 中。(我展示的示例将Samples根据调用中指示的内容将新组件放在调色板中的页面上RegisterComponents。)

完成上述操作后,您可以更改现有表单(首先备份 .pas 和 .dfm 文件!)。我将使用TToolBar您提到的,以及我在下面的说明中发布的外壳的示例替换。

手动将源代码编辑器中的类名从TToolBar更改为TMyToolBar.

右键单击表单,然后View as Text从上下文菜单中选择。

找到TToolBar,并将其从 更改TToolBarTMyToolBar

再次右键单击,然后View as Form从上下文菜单中选择。如果您正确地完成了这些步骤,单击工具栏上的 应该会TMyToolBar在对象检查器中显示您。如果您没有看到它(或者如果您收到错误消息),那么您做错了;您可以通过右键单击代码编辑器顶部的选项卡并选择来关闭选项卡,Close tab然后对有关保存更改的提示回答“否”,然后在必要时从我告诉您首先制作的备份副本中恢复。

于 2013-02-09T00:31:19.853 回答
1

为您的班级创建一个单元:

Unit YourComponent;
interface
uses
 ....
Type
 TYourNewClass=Class(ExistingClass)
   private
   ...
   protected
   ...   
   public
   ...
   published
  end;

  procedure Register;

implementation

.....

procedure Register;
begin
  RegisterComponents('YourPalette', [TYourNewClass]);
end;

创建一个新包(或打开一个自己的现有包)并添加您的单元选择安装在您的 Package.bpl 上。

于 2013-02-09T00:23:51.747 回答