Ali*_*ter -1 delphi components
我正在整理一个大型遗留项目中使用的组件,我已经淘汰了220个自定义组件中的大约90个,用标准的Delphi控件替换它们.其余一些组件需要大量工作才能删除我无法使用的组件.我想阻止任何人额外使用其中一些组件,并想知道是否有一种方法可以在设计时将组件放在表单上显示消息 - 例如"不要使用此控件,请使用改为x或y".
另一种可能性是隐藏组件托盘上的控件(但在设计时仍然可以在窗体上正确呈现控件).
Yur*_*kov 17
有一个受保护的动态方法TComponent.PaletteCreated,只在一种情况下调用:当我们从组件调色板中将此组件添加到表单时.
从组件面板创建组件时响应.
当组件刚从组件面板创建时,PaletteCreated在设计时自动调用.组件编写器可以覆盖此方法以执行仅在从组件选项板创建组件时所需的调整.
正如在TComponent中实现的那样,PaletteCreated什么都不做.
您可以覆盖此方法以显示警告,因此当他尝试将其置于表单时,它将仅提醒用户一次.
UPDATE
我无法在Delphi 7,XE2和Delphi 10 Seattle(试用版)中使用此程序,因此似乎没有实现从IDE调用PaletteCreated.
我向QC发送了报告:http://qc.embarcadero.com/wc/qcmain.aspx?d = 135152 也许开发人员有一天会让它工作.
更新2
有一些有趣的解决方法,我一直试用它们,正常工作.假设TOldBadButton是不应该使用的组件之一.我们覆盖'Loaded'过程和WMPaint消息处理程序:
TOldBadButton=class(TButton)
private
fNoNeedToShowWarning: Boolean; //false when created
//some other stuff
protected
procedure Loaded; override;
procedure WMPaint(var Message: TWMPaint); message WM_PAINT;
//some other stuff
end;
Run Code Online (Sandbox Code Playgroud)
和实施:
procedure TBadOldButton.Loaded;
begin
inherited;
fNoNeedToShowWarning:=true;
end;
procedure TOldBadButton.WMPaint(var Message: TWMPAINT);
begin
inherited;
if (csDesigning in ComponentState) and not fNoNeedToShowWarning then begin
Application.MessageBox('Please, don''t use this component','OldBadButton');
fNoNeedToShowWarning:=true;
end;
end;
Run Code Online (Sandbox Code Playgroud)
问题是,这仅适用于可视组件.如果你有自定义对话框,图像列表等,他们永远不会得到WMPaint消息.在这种情况下,我们可以添加另一个属性,因此当它在对象检查器中显示时,它会调用getter并在此处显示警告.像这样的东西:
TStupidOpenDialog = class(TOpenDialog)
private
fNoNeedToShowWarning: boolean;
function GetAawPlease: string;
procedure SetAawPlease(value: string);
//some other stuff
protected
procedure Loaded; override;
//some other stuff
published
//with name like this, probably will be on top in property list
property Aaw_please: string read GetAawPlease write SetAawPlease;
end;
Run Code Online (Sandbox Code Playgroud)
执行:
procedure TStupidOpenDialog.Loaded;
begin
inherited;
fNoNeedToShowWarning:=true; //won't show warning when loading form
end;
procedure TStupidOpenDialog.SetAawPlease(value: string);
begin
//nothing, we need this empty setter, otherwise property won't appear on object
//inspector
end;
function TStupidOpenDialog.GetAawPlease: string;
begin
Result:='Don''t use this component!';
if (csDesigning in ComponentState) and not fNoNeedToShowWarning then begin
Application.MessageBox('Please, don''t use this component','StupidOpenDialog');
fNoNeedToShowWarning:=true;
end;
end;
Run Code Online (Sandbox Code Playgroud)
当从调色板添加新组件时,较旧版本的Delphi始终将对象检查器滚动到顶部,因此我们的Aaw_please属性肯定会起作用.较新的版本往往从属性列表中的某个选定位置开始,但非可视组件通常具有相当多的属性,因此它应该不是问题.