将组件定义为具有与其类名不同的名称前缀(减去 "T")

Defining a component to have a name prefix different than its ClassName (minus the "T")

在Delphi中,当IDE在设计时插入一个新组件时,它会为其名称添加一个前缀,该前缀是ClassName减去前导“T”,然后添加一个数字使得它的名字独一无二。

询问如何更改组件名称的前缀部分,以便

Edit1

可以改为

ed1

接受的答案指的是 GExperts 中的“重命名组件”实用程序,就目前而言还不错。

但是,有没有一种方法可以让我始终获得相同的、非标准的组件前缀,而不必在 Componxent Palette 中创建和安装后代组件?我知道如何做到这一点,但如果我想为多个组件做这件事,那将是一件不受欢迎的苦差事。

我也注意到了那个问答。

在我看来好像是某事的特例I wrote an answer for,如何指定 添加到表单的组件属性的默认值。而是 long-winded 并且不适用于组件的名称 属性。但是,它可以工作 对于名称,也有一些非常小的修改,因此它现在将支持规范 像这样的默认值:

[TMemo]
Lines.Strings=

[TEdit]
Font.Name=Courier New
Font.Size=11

[TButton]
Name=btn
Caption=

[TCheckBox]
Name=cb
Caption=

请注意,TButton 和 TCheckBox 使用 non-standard 名称前缀和空白标题。 空白的标题是为了避免必须删除 IDE 提供的默认值。

需要添加到 design-time 包并安装在 IDE 中的单元的完整代码如下。主要变化, 与我之前的回答相比,组件的名称 属性 是分开处理的 此

的任何其他属性
procedure TDesignNotifierForm.SetComponentName(AComponent : TComponent; AComponentName : String);
var
  AOwner : TComponent;
begin
  //    First, try to find the component's Form.  We need this so that we can ask the Form's
  //    Designer to generate a unique name for the component instance (Comp1, Comp2, etc).
  AOwner := AComponent.Owner;
  while (AOwner <> Nil) and not(AOwner is TForm) do
    AOwner := AOwner.Owner;

  if AOwner is TForm then begin
    AComponentName := TForm(AOwner).Designer.UniqueName(AComponentName);
    AComponent.Name := AComponentName;
    TForm(AOwner).Designer.Modified;  //  Notify the Form's Designer
  end;
end;

procedure TDesignNotifierForm.SetComponentProperties(AComponent : TComponent; ComponentClassName : String);
var
  i : Integer;
  AString : String;
  Index : Integer;
begin

  //    Note:  The defaults which can be set include the Component's Name.  For simplicity, it can be included
  //    amongst the other defaults but requires special treatment (see SetComponentName).
  //
  if Ini.SectionExists(ComponentClassName) then begin
    Ini.ReadSectionValues(ComponentClassName, SL);
    Index := SL.IndexOfName('Name');
    if Index >= 0  then begin
      AString := SL.Values['Name'];
      SetComponentName(AComponent, AString);
    end;

    for i := 0 to SL.Count - 1 do begin
      if i <> Index then begin
        AString := ComponentClassName + '.' + SL[i];
        SetComponentProperty(AComponent, AString);
      end;
    end;
  end;
end;

单位代码:

unit DesignNotifierFormu;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ExtCtrls, StdCtrls, TypInfo, ToolsApi, DesignIntf, IniFiles;

const
  WM_CompInserted = WM_User + 1;

type
  TDesignNotifierForm = class(TForm)
    Memo1: TMemo;
    Panel1: TPanel;
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    procedure SetComponentProperties(AComponent : TComponent; ComponentClassName: String);
    procedure SetComponentName(AComponent: TComponent; AComponentName: String);
  public
    AComp : TComponent;
    Ini : TMemIniFile;
    SL : TStringList;
    procedure Log(const Title, Msg : String);
    procedure WMCompInserted(var Msg : TMsg); message WM_CompInserted;
  end;

  TDesignNotification = class(TInterfacedObject, IDesignNotification)
    F : TDesignNotifierForm;
    procedure ItemDeleted(const ADesigner: IDesigner; AItem: TPersistent);
    procedure ItemInserted(const ADesigner: IDesigner; AItem: TPersistent);
    procedure ItemsModified(const ADesigner: IDesigner);
    procedure SelectionChanged(const ADesigner: IDesigner;
      const ASelection: IDesignerSelections);
    procedure DesignerOpened(const ADesigner: IDesigner; AResurrecting: Boolean);
    procedure DesignerClosed(const ADesigner: IDesigner; AGoingDormant: Boolean);
    constructor Create;
    destructor Destroy; override;
  end;

var
  DesignNotification : TDesignNotification;

implementation

{$R *.dfm}

constructor TDesignNotification.Create;
begin
  inherited Create;
  F := TDesignNotifierForm.Create(Nil);
  F.Show;
  F.Log('Event', 'Notifier created');
end;

procedure TDesignNotification.DesignerClosed(const ADesigner: IDesigner;
  AGoingDormant: Boolean);
begin
end;

procedure TDesignNotification.DesignerOpened(const ADesigner: IDesigner;
  AResurrecting: Boolean);
var
  C : TComponent;
  Msg : String;
begin
  EXIT;  //  following for experimenting only
  C := ADesigner.Root;
  if C <> Nil then begin
    Msg := C.ClassName;
    //  At this point, you can call ShowMessage or whatever you like
    ShowMessage(Msg);
  end
  else
    Msg := 'no root';
  F.Log('Designer Opened', Msg);
end;

destructor TDesignNotification.Destroy;
begin
  F.Close;
  F.Free;
  inherited;
end;

procedure TDesignNotification.ItemDeleted(const ADesigner: IDesigner;
  AItem: TPersistent);
begin
end;

procedure TDesignNotification.ItemInserted(const ADesigner: IDesigner;
  AItem: TPersistent);
var
  S : String;
begin
  if AItem is TComponent then begin
    S := 'Component name: ' + TComponent(AItem).Name;
    F.AComp := TComponent(AItem);
    PostMessage(F.Handle, WM_CompInserted, 0, 0);
  end
  else
    S := 'Item';
  F.Log('Designer', ADesigner.GetComponentName(TComponent(AItem)));
  F.Log('ItemInserted', S);
end;

procedure TDesignNotification.ItemsModified(const ADesigner: IDesigner);
begin
end;

procedure TDesignNotification.SelectionChanged(const ADesigner: IDesigner;
  const ASelection: IDesignerSelections);
begin
end;

procedure SetUp;
begin
  DesignNotification := TDesignNotification.Create;
  RegisterDesignNotification(DesignNotification);
end;

procedure TDesignNotifierForm.FormCreate(Sender: TObject);
begin
  Ini := TMemIniFile.Create('d:\aaad7\ota\componentdefaults\defaults.ini');
  SL := TStringList.Create;
end;

procedure TDesignNotifierForm.FormDestroy(Sender: TObject);
begin
  SL.Free;
  Ini.Free;
end;

procedure SplitStr(const Input, Delim : String; var Head, Tail : String);
var
  P : Integer;
begin
  P := Pos(Delim, Input);
  if P = 0 then begin
    Head := Input;
    Tail := '';
  end
  else begin
    Head := Copy(Input, 1, P - 1);
    Tail := Copy(Input, P + Length(Delim), MaxInt);
  end;
end;

procedure SetComponentProperty(AComponent : TComponent; AString : String);
var
  Value,
  Head,
  Tail,
  ObjName,
  PropName : String;
  Obj : TObject;
  AType : TTypeKind;
begin
  //  needs to Use TypInfo
  SplitStr(AString, '=', PropName, Value);
  if PropName = '' then else;

  SplitStr(PropName, '.', Head, Tail);

  if Pos('.', Tail) = 0 then begin
    SetStrProp(AComponent, Tail, Value);
  end
  else begin
    SplitStr(Tail, '.', ObjName, PropName);
    Obj := GetObjectProp(AComponent, ObjName);
    if Obj is TStrings then begin
      //  Work around problem setting e.g. TMemo.Lines.Text
      TStrings(Obj).Text := Value;
    end
    else begin
      AType := PropType(Obj, PropName);
      case AType of
        //  WARNING - incomplete list
        tkString,
        tkLString : SetStrProp(Obj, PropName, Value);
        tkInteger : SetOrdProp(Obj, PropName, StrToInt(Value));
        tkFloat : SetFloatProp(Obj, PropName, StrToFloat(Value));
      end; { case }
    end;
  end;

end;

procedure TDesignNotifierForm.SetComponentName(AComponent : TComponent; AComponentName : String);
var
  AOwner : TComponent;
begin
  //    First, try to find the component's Form.  We need this so that we can ask the Form's
  //    Designer to generate a unique name for the component instance (Comp1, Comp2, etc).
  AOwner := AComponent.Owner;
  while (AOwner <> Nil) and not(AOwner is TForm) do
    AOwner := AOwner.Owner;

  if AOwner is TForm then begin
    AComponentName := TForm(AOwner).Designer.UniqueName(AComponentName);
    AComponent.Name := AComponentName;
    TForm(AOwner).Designer.Modified;  //  Notify the Form's Designer
  end;
end;

procedure TDesignNotifierForm.SetComponentProperties(AComponent : TComponent; ComponentClassName : String);
var
  i : Integer;
  AString : String;
  Index : Integer;
begin

  //    Note:  The defaults which can be set include the Component's Name.  For simplicity, it can be included
  //    amongst the other defaults but requires special treatment (see SetComponentName).
  //
  if Ini.SectionExists(ComponentClassName) then begin
    Ini.ReadSectionValues(ComponentClassName, SL);
    Index := SL.IndexOfName('Name');
    if Index >= 0  then begin
      AString := SL.Values['Name'];
      SetComponentName(AComponent, AString);
    end;

    for i := 0 to SL.Count - 1 do begin
      if i <> Index then begin
        AString := ComponentClassName + '.' + SL[i];
        SetComponentProperty(AComponent, AString);
      end;
    end;
  end;
end;

procedure TDesignNotifierForm.WMCompInserted(var Msg: TMsg);
var
  S : String;
begin
  if AComp <> Nil then
    S := AComp.Name
  else
    S := 'Name not known';
  Log('WMCompInserted', S);

  SetComponentProperties(AComp, AComp.ClassName);

  AComp := Nil; // We're done with AComp
end;

procedure TDesignNotifierForm.Log(const Title, Msg: String);
begin
  if csDestroying in ComponentState then
    exit;
  Memo1.Lines.Add(Title + ': ' + Msg);
end;

initialization
  SetUp;
finalization
  if DesignNotification <> Nil then begin
    UnRegisterDesignNotification(DesignNotification);
  end;
end.