delphi 在设计时将组件拖放到窗体上时显示警告

ffscu2ro  于 2022-11-04  发布在  其他
关注(0)|答案(2)|浏览(182)

我正在整理一个大型遗留项目中使用的组件,我已经删除了220个自定义组件中的大约90个,用标准的 Delphi 控件替换它们。一些剩余的组件需要大量的工作来删除,我没有可用的。我想阻止任何人额外使用这些组件中的一些组件,并想知道是否有一种方法显示一条消息,如果组件在设计阶段放在表单上,例如“不要使用这个控件,请改用x或y”。
另一种可能性是隐藏组件托盘上的控件(但仍在设计时使控件正确呈现在窗体上)。

w41d8nur

w41d8nur1#

有一个受保护的动态方法TComponent.PaletteCreated,它只在一种情况下被调用:当我们从组件面板将此组件添加到表单时。
从组件面板创建组件时响应。
PaletteCreated是在设计时从组件面板创建组件时自动调用的。组件编写者可以重写此方法,以执行仅在从组件面板创建组件时才需要的调整。
在TComponent中实现时,PaletteCreated不执行任何操作。
您可以重写此方法以显示警告,这样,当用户试图将其放入窗体时,它只会警告用户一次。

更新

我无法在 Delphi 7、XE2和Delphi 10西雅图(试用版)中使用此过程,因此似乎无法实现从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;

和实施:

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属性肯定会起作用。新版本倾向于从属性列表中的某个选定位置开始,但非可视组件通常有相当多的属性,所以这应该不是问题。

nom7f22z

nom7f22z2#

要确定组件首次创建(放置在窗体上)的时间,请执行以下操作:
覆写**“CreateWnd”**并在其中使用下列if陈述式:

if (csDesigning in ComponentState) and not (csLoading in ComponentState) then
  // We have first create

点击此处了解更多详情〉〉Link

相关问题