开发者

The same property and procedure in different Classes. How they can be accessed?

I created several new objects

TMyMemo = class (开发者_如何学JAVATMemo)
private
  FYahoo = Integer;
  procedure SetYahoo(Value:integer)
public
  procedure Google(A,B:integer; S:string);
published
  property Yahoo:integer read FYahoo write SetYahoo;
end;

TMyPaintbox = class (TPaintbox)
private
  FYahoo = Integer;
  procedure SetYahoo(Value:integer) 
public
  procedure Google(A,B:integer; S:string);
published
  property Yahoo:integer read FYahoo write SetYahoo;
end;

TMyButton = class (TButton)
private
  FYahoo = Integer;
  procedure SetYahoo(Value:integer) 
public
  procedure Google(A,B:integer; S:string);
published
  property Yahoo:integer read FYahoo write SetYahoo;
end;

. . .

These Controls are placed on Form1. Is there a way, how can I change the same property (Yahoo) and run the procedure (Google), which is declared in different objects in general?

I do not want to manually check class type like: if Controls[i] is TMyMemo then ... if controls[i] is TMyPaintbox then ...

because I do not know how many of my new classes will have property Yahoo and method Google (This is only simple example). Probably I have to use ^ and @ operator or FieldAdress, MethodAddress I do not know what else. Can you help me find general solution?

procedure Form1.Button1Click(Sender:TObject);
var i:integer;   
begin
  for i:=0 to Form1.ControlCount-1 do
           begin   
           Controls[i].Google(4,5, 'Web');   // this should be changed somehow
           Controls[i].Yahoo:=6;             // this should be changed somehow
           end;
end;

end;

Thanks


Define an interface which has both method Google() and property Yahoo defined.

Make your TMyButton, TMyMemo and TMyPaintbox inherit from that interface and override those methods to do what is necessary.

In the loop, cast the controls to the interface type using the "as" operator and access the Yahoo field and Google() method.

Here is the code - The is operator doesnt work as intended in Delphi 2009 and below, so I had to write a function for that - It needs to rely on catching a cast exception, so it isn't the cleanest solution:

type

  TMyInterface = interface(IInterface)
  ['{1F379072-BBFE-4052-89F9-D4297B9A826F}']

    function GetYahoo : Integer;
    procedure PutYahoo(i : Integer);

    property Yahoo : Integer read GetYahoo write PutYahoo;
    procedure Google(A, B : integer; S : string);
  end;

  TMyButton = class (TButton, TMyInterface)
  private
    FStr : String;
    FYah : Integer;

  public
    function GetYahoo : Integer;
    procedure PutYahoo(i : Integer);
    procedure Google(A, B : integer; S : string);
  end;

  TMyMemo = class (TMemo, TMyInterface)
  private
    FStr : String;
    FYah : Integer;

  public
    function GetYahoo : Integer;
    procedure PutYahoo(i : Integer);
    procedure Google(A, B : integer; S : string);
  end;


{ TMyButton }

function TMyButton.GetYahoo: Integer;
begin
  Result := 0;
end;

procedure TMyButton.Google(A, B: integer; S: string);
begin
  FStr := S + '=' + IntToStr(A + B);
end;

procedure TMyButton.PutYahoo(i: Integer);
begin
  FYah := 42;
end;

{ TMyMemo }

function TMyMemo.GetYahoo: Integer;
begin
  //
end;

procedure TMyMemo.Google(A, B: integer; S: string);
begin
  //
end;

procedure TMyMemo.PutYahoo(i: Integer);
begin
  //
end;

function IsMyIntf(c : TControl) : TMyInterface;
begin
  try
    Result := c as TMyInterface;
  except on e : Exception do
    Result := nil;
  end;
end;

procedure TForm2.Button1Click(Sender: TObject);
var
  i: Integer;
  p : TMyInterface;
begin
  for i  := 0 to ControlCount - 1 do
  begin
    p := IsMyIntf(Controls[i]);
    if (p <> nil) then
    begin
      p.PutYahoo(i);
      p.Google(i, i, 'Hah!');
    end;
  end;

end;


  1. Use the same base class
  2. Use an interface
  3. Use the D2010 RTTI
  4. Implement a custom message on all controls and process it.


@lyborko, the Controls[i] returns a TControl Class wich not have an implementation for the Google method and the Yahoo property.for resolve you problem, you can check the class of the Controls[i] using the ClassType property and then implement something like this.

procedure TForm1.Button1Click(Sender: TObject);
var i:integer;
begin
  for i:=0 to Form1.ControlCount-1 do
     begin
      if Controls[i].ClassType = TMyPaintbox  then
      begin
       TMyPaintbox (Controls[i]).Google(4,5, 'Web');
       TMyPaintbox (Controls[i]).Yahoo:=6;
      end
      else
      if Controls[i].ClassType = TMyMemo  then
      begin
       TMyMemo (Controls[i]).Google(4,5, 'Web');
       TMyMemo (Controls[i]).Yahoo:=6;
      end
      else
      if Controls[i].ClassType = TMyButton  then
      begin
       TMyButton (Controls[i]).Google(4,5, 'Web');
       TMyButton (Controls[i]).Yahoo:=6;
      end;

     end;
end;


Better that use IF...ELSE with differents classes for know the component class you can use RTTI to know if an object has a específic property. You can find the code and explanation here:
Modify control properties using RTTI
Here you can find more code for access properties of a component using RTTI.

Regards.


You are propobly looking for RTTI.
Se this article about that http://delphi.about.com/od/vclusing/a/coloringfocused.htm (look at page 3)

The Only problem is that it Can't se public properties/methods, only published (i don't know if that stil is true in delphi 2010). A lot of RTTI info for delphi 2010 can be found here http://robstechcorner.blogspot.com/2009/09/so-what-is-rtti-rtti-is-acronym-for-run.html .

Calling a method by name (via RTTI): Se http://delphi.about.com/cs/adptips2004/a/bltip0204_3.htm

0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜