动态投射表单

时间:2010-01-12 13:12:58

标签: delphi

我正在编写一个程序来关闭在(任何)表单上创建和打开的所有adoquery,问题是我需要在表单上进行强制转换以识别组件。如何制作动态演员,如示例中所示?

我需要这样的东西

Procedure OpenADODataSets(Form:TForm;FormType:TClass);
...
...
(Form as FormType).ComponentCount

Procedure OpenADODataSets(Form:TForm;FormType:TClass);
...
...
FormType(Form).ComponentCount

这是代码。

Procedure OpenADODataSets(Form:TForm;FormType:TClass);
var
  i: integer;
begin

    for i:=0 to (Form as FormType).ComponentCount-1 do
     if (Form as FormType).Components[i].ClassType=TADOQuery then
       if not TADOQuery((Form as FormType).Components[i]).Active then
        TADOQuery((Form as FormType).Components[i]).Open;

end;

更新

问题通过@Edelcom的答案解决了

Procedure OpenADODataSets(Form:TForm);
var
  i: integer;
begin

    for i:=0 to Form.ComponentCount-1 do
     if Form.Components[i].ClassType=TADOQuery then
       if not TADOQuery(Form.Components[i]).Active then
        TADOQuery(Form.Components[i]).Open;

end;

2 个答案:

答案 0 :(得分:2)

为什么你需要(Form as FormType)(正如我评论的那样)。 查看我自己的一些代码,工作正常:

procedure TProgSettingsVisual.FillStandardSaveFilesForForm( const pForm: TForm;);
var i : integer;
    x : string;
    thisComponent : TComponent;
begin
   With pForm do
   begin
      for i := 0 to ComponentCount-1 do
      begin
         thisComponent := Components[i];

         x := LowerCase(Components[i].ClassName);


         if x = 'tovcinifilestore'
         then begin
            TOvcIniFileStore(Components[i]).IniFileName := FormSaveFile(pForm);
         end;

         if x = 'tovdformstate'
         then begin
             ...
         end;

         if x = 'tovccomponentstate'
         then begin
              ...

答案 1 :(得分:1)

类型转换的目的是告诉编译器标识符的类型,以便它可以生成使用该标识符的正确代码。当您想要的类型存储在变量中时,编译器不能进行任何类型检查。它无法确认FormType的运行时值是否为具有Components属性的类型,因此无法编译代码。

当您不知道该类型是什么时,不能将类型转换为类型。如果你发现自己需要这样做,那你就做错了什么。发表一个关于你真正想要做什么的问题。 (另请参阅:“XY问题。”)

在你的情况下,你要做的是编写一个适用于多种形式的函数。但是,您在表单对象中使用的所有属性实际上都可用于所有表单类型,因为它们是TForm或更早版本中引入的属性。事实上,您正在使用的属性在TComponent中引入 - 所有组件都可以拥有其他组件,因此它们都具有ComponentsComponentCount属性。您不需要知道表单具有哪种特定类型,因为您的代码可以与任何组件类型一起使用。

procedure OpenADODataSets(Owner: TComponent);
var
  i: Integer;
begin
  for i := 0 to Owner.ComponentCount - 1 do
    if Owner.Components[i] is TADOQuery
       and not TADOQuery(Owner.Components[i]).Active then
      TADOQuery(Owner.Components[i]).Open;
end;

甚至,从Delphi 2005开始:

procedure OpenADODataSets(Owner: TComponent);
var
  comp: TComponent;
begin
  for comp in Owner do
    if comp is TADOQuery
       and not TADOQuery(comp).Active then
      TADOQuery(comp).Open;
end;

由于数据集在打开之前已经检查它们是否处于活动状态,因此您不必先检查:

if comp is TADOQuery then
  TADOQuery(comp).Open;