有一个受保护的动态方法TComponent.PaletteCreated,它只在一种情况下被调用:当我们从组件面板添加这个组件到一个表单时。
从组件面板创建组件时响应。
PaletteCreated 在刚从组件面板创建组件时在设计时自动调用。组件编写者可以重写此方法以执行仅在从组件面板创建组件时才需要的调整。
正如在 TComponent 中实现的那样,PaletteCreated 什么都不做。
您可以覆盖此方法以显示警告,因此当用户尝试将其放入表单时,它只会提醒用户一次。
更新
我无法让这个程序在 Delphi 7、XE2 和 Delphi 10 Seattle(试用版)中运行,因此似乎没有实现从 IDE 调用 PaletteCreated。
我已将报告发送给 QC:http://qc.embarcadero.com/wc/qcmain.aspx?d=135152
也许开发者有一天会让它工作。
更新 2
有一些有趣的解决方法,我一直在尝试,工作正常。假设 TOldBadButton 是不应该使用的组件之一。我们覆盖“加载”过程和 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;
和实施:
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;
问题是,这仅适用于视觉组件。如果您有自定义对话框、图像列表等,它们永远不会收到 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;
实现:
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;
当从调色板添加新组件时,旧版本的 Delphi 总是将对象检查器滚动到顶部,因此我们的 Aaw_please 属性肯定会起作用。较新的版本往往从属性列表中的某个选定位置开始,但非可视组件通常具有相当多的属性,因此应该不是问题。