Cast a form dynamically
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;
精彩评论