开发者

Cast a form dynamically

开发者 https://www.devze.com 2022-12-16 17:05 出处:网络
I am writing a procedure to close all adoquery created and open on a (any) form, the problem is I need to do a cast on the form to identify the components. how can I make a dynamic cast like shown in

I am writing a procedure to close all adoquery created and open on a (any) form, the problem is I need to do a cast on the form to identify the components. how can I make a dynamic cast like shown in the example?

I need something like this

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

or

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

this is the code.

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

    for i:=0 to (Form as FormType).ComponentCou开发者_如何学Gont-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;

UPDATE

problem solved with the answer of @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;


Why do you need the (Form as FormType) (as I commented). Looked up some of my own code, which works fine :

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
              ...


Type casting's purpose is to tell the compiler the type of an identifier so that it can generate correct code that uses that identifier. When your desired type is stored in a variable, the compiler can't do any type checking. It can't confirm that the run-time value of FormType will be a type that has a Components property, so it can't compile the code.

You can't type-cast to a type when you don't know what that type is. If you find yourself needing to do that, you're doing something wrong. Post a question about what you're really trying to do. (See also: "XY problem.")

In your case, what you're trying to do is write a function that works on many kinds of forms. But all the properties you're using from the form object are actually available to all form types because they're properties introduced in TForm or earlier. In fact, the properties you're using are introduced in TComponent — all components can own other components, so they all have Components and ComponentCount properties. You don't need to know which specific type the form has because your code can work equally well with any component type.

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;

Or even, as of 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;

Since data sets already check whether they're active before opening themselves, you don't really have to check first:

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

精彩评论

暂无评论...
验证码 换一张
取 消