将组件定义为具有与其类名不同的名称前缀(减去 "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.
在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.