Announcement

Collapse
No announcement yet.

Pointer, Pointer, Pointer

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Pointer, Pointer, Pointer

    in eine TList möchte ich die Adresse einer Komponente aufnehmen.
    cListe:=TList.create;
    cListe.Add(@Edit2);
    das funktioniert hervorragend ...
    num muß ich noch eine Komponente dem namen nach hinzufügen...

    var compo:TComponent
    begin
    compo:=TComponent(FindComponent('Edit1'));
    if compo <> nil then
    cListe.Add(@compo)
    end

    und hier liegt auch schon das Problem. Nachdem die Routine verlassen wird, ist compo nicht mehr gültig. Damit die Verbindung zur TList noch brauchbar ist benötige ich also die richtige Adresse der Komponente und nicht den Zeiger compo auf die Komponente.

    Wer kann mir mit der richtigen Syntax helfen ???

    Vielen Dank im Voraus

    Carsten Jockenhöfer

  • #2
    Hallo Carsten,

    was passiert, wenn Du compo statt @compo in die Liste einträgst?

    Gruß Lory

    Comment


    • #3
      Hi Loryn,<br><br>
      bei der Dereferenzierung<br>
      TEdit(cListe.Items[1]^).text:='sdfdsfasdf'<br>
      gibt es eine Zugriffsverletzung...<br><br>
      :-(((
      <br><br>
      MfG Carsten Jockenhöfe

      Comment


      • #4
        Hallo Carsten,

        ich denke du hast kein Syntax-Problem, sondern ein Verstaendnisproblem. Die Variable "compo", die du lokal in einer Funktion erzeugst, ist lediglich ein Zeiger auf ein Objekt der Klasse TComponent. In Delphi sind alle Variablen, die vom Typ einer Klasse sind implizit immer Zeiger auf Objekte vom Typ dieser Klasse. Das merkst du daran, dass wenn du z.B. zur Laufzeit eine Komponente erzeugen moechtest, du dann den Konstruktor aufrufen musst. <p>
        var<br>
        compo: TEdit;<br>
        begin<br>
        compo := TEdit.Create(self);<br>
        In deinem Beispiel erzeugst du keine neue Komponente, sondern richtest lediglich mit Hilfe der Funktion "FindComponent('Edit1')" den Zeiger auf eine bereits bestehende Komponente. An TList uebergibst du die Adresse der Komponente.<br>
        Du kannst dir also jederzeit wieder einen neuen Zeiger erzeugen und diesen dann auf eine in der TList gespeicherten Adressen zeigen lassen.<p>
        Mit Hilfe der Eigenschaft Items kannst auf alle Elemente der TList zugreifen.<br>
        var<br>
        CompoNeu: TComponent;<br>
        //alternativ:
        PCompoNeu: ^TComponent;<br>
        I: Integer;<br>
        begin<br>
        for I := 0 to cListe.Count - 1 do begin<br>
        CompoNeu := TComponent(cListe.Items[I]^);<br>
        //alternativ<br>
        PCompoNeu := cListe.Items[I];
        if CompoNeu.Name = 'Weiss nicht genau' then begin<br>
        //alternativ
        if PCompoNeu.Name = 'Was auch immer' then begin<br>
        ...<br>
        ...<br>
        end;<br>
        end;<br>
        end;<p>

        Ich hoffe das hilft dir weiter.<p>
        Gruss<br>
        Wolfgang Rolle

        Comment


        • #5
          und es klappt immer noch nicht ...
          <tt>
          unit main;

          interface

          uses
          Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
          StdCtrls, ComCtrls, contnrs;

          type
          PComponent = ^TEdit;
          TForm1 = class(TForm)
          Button1: TButton;
          Edit1: TEdit;
          Edit2: TEdit;
          Edit3: TEdit;
          StatBar: TStatusBar;
          Button2: TButton;
          ListBox: TListBox;
          Label1: TLabel;
          procedure Button1Click(Sender: TObject);
          procedure FormActivate(Sender: TObject);
          procedure FormDeactivate(Sender: TObject);
          procedure Button2Click(Sender: TObject);
          private
          { Private-Deklarationen }
          public
          { Public-Deklarationen }
          ListOfComponents:TList;
          end;

          var
          Form1: TForm1;

          implementation

          {$R *.DFM}

          procedure TForm1.Button1Click(Sender: TObject);
          var compo:TComponent;
          RefCompo:TComponent;
          begin
          ListOfComponents.Add(@Edit1);
          ListOfComponents.Add(@Edit2);

          compo:=TComponent(FindComponent('Edit3'));
          if compo<>nil then
          begin
          ListOfComponents.Add(@compo);
          end;

          RefCompo:=TComponent(ListOfComponents.Items[0]^);
          (RefCompo as TEdit).text:='aaa11';
          RefCompo:=TComponent(ListOfComponents.Items[1]^);
          (RefCompo as TEdit).text:='bbb22';
          RefCompo:=Tcomponent(ListOfComponents.Items[2]^);
          (RefCompo as TEdit).text:='ccc33';
          end;

          procedure TForm1.Button2Click(Sender: TObject);
          var i:integer;
          RefCompo:TComponent;
          begin
          // Anzeige der Komponentennamen
          if ListOfComponents.Count>0 then
          begin
          ListBox.Clear;
          for i:= 0 to ListOfComponents.Count-1 do
          begin
          RefCompo:=TComponent(ListOfComponents.Items[i]^);
          ListBox.Items.Add(RefCompo.Name);
          end;
          end;
          end;

          procedure TForm1.FormActivate(Sender: TObject);
          begin
          ListOfComponents:=TList.create;
          end;

          procedure TForm1.FormDeactivate(Sender: TObject);
          begin
          ListOfComponents.free;
          end;

          end.</tt&gt

          Comment


          • #6
            Hallo Carsten,

            wäre es nicht einfacher, statt @Edit1 direkt Edit1 in die Liste einzutragen? Wie Wolfgang bereits bemerkt hat, ist Edit1 (vom Typ TEdit) schon ein Zeiger und @Edit1 ist also Pointer of Pointer. Trägst Du dann wie vorgeschlagen compo und nicht @compo in die Liste ein, kannst Du im folgenden auf Dereferenzierung verzichten. Es tritt kein Laufzeitfehler mehr auf.

            TEdit(cListe.Items[0]).Text := 'mein neuerText';

            Gruß Lory

            Comment


            • #7
              Hallo Carsten,

              habe eben erst Dein Programmbeispiel gelesen.

              In der Methode Button1Click ist compo eine lokale Variable. @compo ist ungültig, sobald Button1Click verlassen wird. Daher kommt es in Button2Click zu einem Laufzeitfehler, sobald Du auf den dritten Listeneintrag zugreifst.

              Trage in Button1Click direkt Edit1, Edit2, compo (ohne @) in ListOfComponents ein, dann kannst Du in Button2Click mit:

              ListBox.Items.Add(TComponent(ListOfComponents.Item s[i]).Name)

              die Komponentennamen in der ListBox anzeigen.

              Lory

              Comment


              • #8
                Danke Wolfgang, danke Lyron, echt tolle Hilfe, jetzt klappts.<p>
                :-))))))))))) .... der Feierabend ist gerettet.<p>
                <p>
                MfG Carsten Jockenhöfer<p&gt

                Comment

                Working...
                X