在设计时在表单上删除组件时显示警告

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属性肯定会起作用.较新的版本往往从属性列表中的某个选定位置开始,但非可视组件通常具有相当多的属性,因此它应该不是问题.

  • @Alister我想知道为什么你没有接受这个答案(或者最近的任何其他答案).由于这显然是对你的问题的完美答案,我只能假设你已经忘记了接受答案的礼仪. (5认同)
  • 有趣的是,在我使用和编写VCL组件的这些年里,我从未见过或听说过`PaletteCreated()`. (2认同)
  • @DavidHeffeman,Alister,对不起,伙计们,我也无法工作.似乎在任何Delphi版本中都没有实现调用PalleteCreated表单IDE.没想到,delphi文档从未让我失望过.我认为,这可以算作一个bug并发送QC报告,也可以在更新中看到一些变通方法,它们可以工作(在多个版本中检查过),但不幸的是它们并不那么优雅. (2认同)