Announcement

Collapse
No announcement yet.

Komponenten mit Variablen ansprechen

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

  • Komponenten mit Variablen ansprechen

    Hallo Programmierfreunde,<br>
    mein Ziel ist es, Komponenten mit einer Laufvariable anzusprechen.<br>
    <br>
    Vereinfacht dargestellt sollte es so aussehen:<br>
    <br>
    for I := 0 to ComponentCount - 1 do begin<br>
    Temp := Components[I];<br>
    if Temp.Tag > 0 then<br>
    TLabel(Temp).Caption := Ini.ReadString('testing', inttostr(TLabel(Temp).Tag),'error-error-error');<br>
    end;<br><br>
    Die wichtigste Zeile ist die vierte: Mein Label heißt z.B. "Label1" und soll beschriftet werden. In Temp hätte ich jetzt z.B. "1" stehen. Nun kann ich aber nicht einfach schreiben: 'Label'+TLabel(Temp).Caption := ... .<br>
    Das wäre natürlich auch zu einfach <br>
    Kann mir da vielleicht jemand weiterhelfen bitte ?<br>
    <br>
    Super herzlichen Dank und bis bald,<br>
    Zuletzt editiert von Gast_1; 31.03.2010, 13:07. Reason: Realname entfernt

  • #2
    Schau mal unter <b>FindComponent</b>

    Comment


    • #3
      Hallo !<br>
      Herzlichen Dank Nico für deinen Beitrag, damit bin ich schonmal weitergekommen. Jetzt habe ich nur das Problem, dass mein Quelltext eigentlich klappen müsste, aber er tut es einfach nicht. Die Caption ändert sich einfach nicht...<br>
      Auf meiner Form "About" existiert die Label-Komponente mit der Eigenschaft Name = 'Lab2000' und mit dem Tag '2000'.<br>
      Ich habe folgenden Source:<br><br>
      procedure TAbout.FormDblClick(Sender: TObject);<br>
      var<br>
      Ini: TIniFile;<br>
      ii : Integer;<br>
      Temp : TComponent;<br>
      begin<br>
      try<br>
      Ini:=TIniFile.Create(ExtractFilePath(ParamStr(0))+ '\german.ini');
      <p> with About do begin<br>
      for ii := 0 to ComponentCount - 1 do begin<br>
      Temp := Components[i];<br>
      if Temp.Tag &gt; 0 then begin</p>
      <p> <b>TLabel(Findcomponent('Lab'+inttostr(Temp.Tag))) .Caption := Ini.ReadString('translation',
      inttostr(TLabel(Temp).Tag),'Error?');</b></p>
      <p><br>
      end;<br>
      end;<br>
      end;<br>
      finally<br>
      Ini.Free;<br>
      end;<br>
      end;<br><br>
      Ich weiß im Augenblick nicht weiter, wenn mir jemand helfen kann, wäre das eine super Hilfe !<br><br>
      Schöne Grüße,<br>
      Zuletzt editiert von Gast_1; 31.03.2010, 13:07. Reason: Realname entfernt

      Comment


      • #4
        Ich würde die fettgedruckte Zeile mal etwas aufdröseln und mir die Einzelteile dann mal im Debugger anschauen. In etwa der Code:
        <pre>
        // var
        // lbl: TLabel;
        // s: string;
        lbl := TLabel(Findcomponent('Lab'+inttostr(Temp.Tag)));
        s := lbl.Caption; //(*)
        s := Ini.ReadString('translation', inttostr(TLabel(Temp).Tag),'Error?'); //(**)
        lvl.Caption := s;
        </pre>
        und dann auf die Zeile mit dem (*) nen Breakpoint gesetzt.
        Nach dieser und der nächsten Zeile kannst du ja mal kucken, wie
        der String s jeweils ausschaut, und daraus (hoffentlich) weitere Schlüsse ziehen.
        <br>HTH, Uli

        Comment


        • #5
          <p>Hi Uli !</p>
          <p>Ersteinmal danke ich dir f&uuml;r deine &Uuml;berlegung. Ich habe deinen Codevorschlag
          einmal implentiert und habe dabei folgende Ergebnisse erzielt:</p>
          <p>Temp.Tag = 2000<br>
          lbl := TLabel(Findcomponent('Lab'+inttostr(Temp.Tag))); <b>//&lt;- lb1 = nil
          (!!!)<br>
          </b>s := lbl.Caption; //(*) <b>&lt;- s = '' / logisch, da die Caption einer
          unbekannten Komponente halt nichts ergeben kann...</b><br>
          s := Ini.ReadString('translation', inttostr(TLabel(Temp).Tag),'Error?'); <b>//(**)
          &lt;- s = 'TestTestTestTest', Wert aus der Inidatei erfolgreich gelesen und
          in s reingeschrieben</b><br>
          lbl.Caption := s; //<b>&lt;-lb1 ist ja nil, daher wird auch kein Label ge&auml;ndert
          ! </b><br>
          <br>
          Der Fehler liegt also schon in der ersten Zeile. Stellt sich die Frage, was
          hab ich falsch gemacht ?<br>
          Die Komponente ist auch wiegesagt entsprechend bennant : Name = 'Lab2000';<br>
          <br>
          Super herzlichen Dank f&uuml;r weitere Hilfe !!</p>
          <p>Sch&ouml;ne Gr&uuml;&szlig;e und alles Beste,<br>
          <br><br>PS: Selbst wenn ich einfach nur TLabel(FindComponent('Lab2000'))... angebe, findet er nichts, obwohl die Kompo 'Lab2000' heißt
          Zuletzt editiert von Gast_1; 31.03.2010, 13:07. Reason: Realname entfernt

          Comment


          • #6
            Das ist komisch. Du hast also definitiv eine Komponente auf deiner
            Form, deren Name-property 'Lab2000' ist? Und ein Aufruf FindComponent('Lab2000') von dieser Form aus findet nichts?
            <p>Wenn ja, dann versuch doch mal, das Problem mit einem möglichst kleinen Programm nachzuvollziehen, welches du dann mal hier posten kannst.
            <p>Ciao. Uli

            Comment


            • #7
              Der Owner der Komponente sollte die Frage stellen...
              Wenn also das Label1 auf Form1 liegt muß selbige die Kompo suchen...
              Beispiel:

              <pre><p><b>procedure</b> TForm1.Button1Click(Sender: TObject);
              <b>var</b>
              AOwner: TComponent;
              <b>begin</b>
              AOwner := Self;
              <i>// AOwner := nil;</i>
              <b>with</b> TLabel.Create(AOwner) <b>do</b>
              <b>begin</b>
              Parent := Self;
              Name := 'Label1';
              Caption := 'hallo, world!';
              <b>if</b> Assigned(Self.FindComponent('Label1')) <b>then</b>
              ShowMessage('jet doch.')
              <b>else</b>
              ShowMessage('nich jefunden!');
              Free();
              <b>end</b>;
              <b>end</b>;<p></pre>

              - nic

              Comment


              • #8
                Hallo !<br>
                <br>
                Nico, dein Quelltext funktioniert bei mir in meinem Project super klasse. Sollte
                auch, sonst w&auml;re ich total verzweifelt gewesen. Herzlichen Dank an dich,
                Nico !<br>
                <br>
                Jetzt habe ich folgendes Problem : <br>
                In einem neuen Project klappt der Quelltext, den ich oben hingeschrieben habe,
                astrein. Ich kann nichts beanstanden. Nun versuche ich das nochmals in meinem
                Project, und schon klappts nicht mehr. Und die Kompo hei&szlig;t wirklich &quot;Lab2000&quot;,
                ich habe es auch schon mit anderen Namen probiert, es geht einfach nicht, als
                wenn es in diesem Project spuken w&uuml;rde.<br>
                ...<br>
                Gerade habe ich noch etwas ausprobiert:<br>
                Auf meinem Main Formular klappt mein Source. Aber in meinen &quot;Unter&quot;-Fenstern
                klappt es nicht mehr. Liegt es vielleicht daran, wie ich die Fenster aufgerufen
                habe ? Vielleicht klappt ja deswegen die <i>FindComponent</i> Routine nicht
                ?<br>
                </p>
                <p>So rufe ich ein Unterfenster vom Mainformular auf:<br>
                <br>
                <i>var<br>
                Form : TUpdateCheck;<br>
                begin<br>
                Form := TUpdateCheck.Create(Self);</i></p>
                <p><i> Try<br>
                If Form.ShowModal = mrOK then<br>
                begin<br>
                <br>
                end;<br>
                finally<br>
                Form.Free;<br>
                end;</i></p>
                <p>F&uuml;r eure Hilfe bin ich sehr dankbar !!!!<br>
                Sch&ouml;ne Gr&uuml;&szlig;e,<br>
                Zuletzt editiert von Gast_1; 31.03.2010, 13:07. Reason: Realname entfernt

                Comment


                • #9
                  Es muß immer der Owner nach der Komponente fragen,<br>
                  vielleicht hilft Dir folgendes Beispiel...

                  <pre><p><b>program</b> Project1;
                  <p>
                  <b>uses</b>
                  Forms,
                  Unit1 <b>in</b> 'Unit1.pas' <i>{Form1}</i>,
                  Unit2 <b>in</b> 'Unit2.pas' <i>{Form2}</i>;
                  <p>
                  <i>{$R *.RES}</i>
                  <p>
                  <b>begin</b>
                  Application.Initialize;
                  Application.CreateForm(TForm1, Form1);
                  Application.Run;
                  <b>end</b>.<p></pre>
                  <p>//////////////////////////////////////////////////////////////////////<p>
                  <pre><p><b>unit</b> Unit1;
                  <p>
                  <b>interface</b>
                  <p>
                  <b>uses</b>
                  Windows, Messages,
                  SysUtils,
                  Classes, Controls, StdCtrls, Forms,
                  Unit2;
                  <p>
                  <b>type</b>
                  TForm1 = <b>class</b>(TForm)
                  Button1: TButton;
                  <b>procedure</b> Button1Click(Sender: TObject);
                  <b>private</b>
                  <i>{ Private declarations }</i>
                  <b>public</b>
                  <i>{ Public declarations }</i>
                  <b>end</b>;
                  <p>
                  <b>var</b>
                  Form1: TForm1;
                  <p>
                  <b>implementation</b>
                  <p>
                  <i>{$R *.DFM}</i>
                  <p>
                  <b>procedure</b> TForm1.Button1Click(Sender: TObject);
                  <b>var</b>
                  AForm: TForm2;
                  ALabel: TLabel;
                  <b>begin</b>
                  Application.CreateForm(TForm2, AForm);
                  <b>if</b> Assigned(AForm) <b>then</b>
                  <b>try</b>
                  ALabel := TLabel(AForm.FindComponent('Label1'));
                  <b>if</b> Assigned(ALabel) <b>then</b>
                  ALabel.Caption := 'in Form1 von Form2 gefunden';
                  AForm.ShowModal();
                  <b>finally</b>
                  AForm.Free();
                  <b>end</b>;
                  <b>end</b>;
                  <p>
                  <b>end</b>.<p></pre>
                  <p>//////////////////////////////////////////////////////////////////////<p>
                  <pre><p><b>unit</b> Unit2;
                  <p>
                  <b>interface</b>
                  <p>
                  <b>uses</b>
                  Windows, Messages,
                  SysUtils,
                  Classes, Controls, StdCtrls, Forms;
                  <p>
                  <b>type</b>
                  TForm2 = <b>class</b>(TForm)
                  Button1: TButton;
                  Label1: TLabel;
                  procedure Button1Click(Sender: TObject);
                  <b>private</b>
                  <i>{ Private declarations }</i>
                  <b>public</b>
                  <i>{ Public declarations }</i>
                  <b>end</b>;
                  <p>
                  <b>implementation</b>
                  <p>
                  <i>{$R *.DFM}</i>
                  <p>
                  <b>procedure</b> TForm2.Button1Click(Sender: TObject);
                  <b>var</b>
                  ALabel: TLabel;
                  <b>begin</b>
                  ALabel := TLabel(FindComponent('Label1'));
                  <b>if</b> Assigned(ALabel) <b>then</b>
                  ALabel.Caption := 'von Form2 selbst gefunden';
                  <b>end</b>;
                  <p>
                  <b>end</b>.<p></pre>

                  - nic

                  Comment


                  • #10
                    um das Casting auf einen bestimmten Typ sicherer zu machen sollte man überprüfen, ob die gefundene Komponente über ein TLabel ist...
                    <pre><p><b>if</b> Assigned(ALabel) <b>and</b> (ALabel <b>is</b> TLabel) <b>then</b>
                    ALabel.Caption := 'ick bin 'n TLabel';<p></pre>

                    - nic

                    Comment


                    • #11
                      Hallo,

                      ich habe folgendes Problem:<BR>In einem MDI-Formular werden Komponenten zur Laufzeit mit "with TTabSheet.Create(Self) do ..." erstellt.<BR>Verlässt nun der Compiler das Formular und kommt später wieder<BR>an die gleiche Stelle, so merkt er nicht, dass diese<BR> Komponente bereits erzeugt und im Speicher liegen muss.<BR>Er erzeugt sie immer wieder neu. Wahrscheinlich kommt es deshalb<BR>abundzu zum Absturz. Wenn ich diese Komponente mit einer festen<BR>Variable erzeuge ("TabSheet1 := TTabSheet.Create(Self)")<BR> so kann sie im Speicher gefunden werden. Da in diesem Programm<BR>viele Komponenten erzeugt werden, möchte ich nicht den Weg der<BR>Variablen gehen.<P>Worin liegt der Unterschied zwischen beiden Methoden und wie kann<BR>ich vermeiden, dass bei erster Methode die Komponenten ständig<BR>neu erzeugt werden?<P>Claudi

                      Comment


                      • #12
                        Hallo Claudia,<br>
                        so wie sich deine Beschreibung liest, erzeugst du deine Tabsheets an der falschen Stelle. Beschreib doch mal, wann du die Teile erzeugst, wohin du sie plazierst usw.
                        <br>Ciao, Uli

                        Comment


                        • #13
                          Hallo Ulrich,<P>
                          danke für Deine schnelle Antwort :-)<P>
                          Die Komponenten werden durch den Aufruf von FormActivate erzeugt.<BR>
                          Ablauf: In einem anderen Formular liegt eine Navigatorleiste.<BR>Bei Klick (Next, Prior) wird jedes Mal FormActivate aufgerufen<BR>und in Abhängigkeit der Datensätze verschieden TabSheets, Edits,<BR>Labels, etc. erzeugt. Leider habe ich keine Stelle gefunden, wo<BR>diese auch wieder freigegeben werden. Mir ist auch nicht ganz klar,<BR>weshalb mein Vorgänger Komponenten erzeugt, die zu diesem Zeitpunkt<BR>gar nicht sichtbar sind. Der Versuch, den Aufruf FormActivate <BR>herauszunehmen, da der Fokus auf dem Formular mit der<BR> Navigatorleiste bleibt, ist leider fehlgeschlagen.<BR>Da hat sich das Programm aufgehängt. Ich hoffe, Du kannst etwas<BR>mit meinen Informationen anfangen.<P>
                          Viele Grüße<BR>
                          Claudi

                          Comment


                          • #14
                            Ich bin zwar nicht ganz sicher, ob ich alles richtig verstanden habe, aber für mich klingt das Ganze so, als müsstest du einfach im OnClick des Navigators (*nicht* in FormActivate oder FormShow o.ä.) zuerst alle zu löschenden Komponenten löschen und danach die neuen erzeugen - fertig.
                            <br>Deiner Beschreibung nach wäre das Problem bei dem Vorgehen, herauszufinden, welche Kompos du löschen musst. Bevor ich mich dazu weiter auslasse, noch eine Frage: Ich vermute, du erzeugst zuerst die Tabsheets und danach alle anderen Kompos als Kinder dieser TabSheets. Ist das richtig?<br>
                            Ciao, Uli

                            Comment


                            • #15
                              Ja, das ist richtig. Als Parent des Tabsheet ist PageControl1 angegeben, auf das Tabsheet werden noch Labels etc. geladen.<P>Im OnClick des Navigators sind die Komponenten nicht vorhanden (Self.FindComponent() = NIL), deshalb kann ich sie nicht löschen. Im OnClick des Navigators wird aber FormActivate aufgerufen, wo dann die Komponenten erzeugt werden. Beim nächsten OnClick Ereignis sind die Komponenten wieder nicht auffindbar und werden erneut erzeugt.
                              Ich habe testweise ein Tabsheet mit Variable (Tabsheet1 := TTabsheet.Create(Self)) erzeugt. Dieses kann beim Onclick ermittelt werden und wird nicht wieder neu erzeugt. Kann ich das Problem (die erzeugten Komponenten wieder im Speicher zu finden) ohne Variablen lösen?
                              Hier ein kleiner Ausschnitt:
                              procedure TF_BEARB.FormActivate(Sender: TObject);
                              var
                              ...
                              <PRE> PROCEDURE KreierePage(Sheet: integer; Bez: string);
                              begin
                              // Sheet
                              if NOT Assigned(Self.FindComponent('PageX' + IntToStr(Sheet))) then // CST 11.09.2002
                              with TTabSheet.Create(Self) do begin
                              Parent:= PageControl1;
                              Name:= 'PageX' + IntToStr(Sheet);
                              Caption:= Bez;
                              PageControl:= PageControl1;
                              end;

                              // ScrollBox draufsetzen
                              if NOT Assigned(Self.FindComponent('ScrollBoxX' + IntToStr(Sheet))) then // CST 11.09.2002
                              with TScrollBox.Create(Self) do begin
                              Parent:= PageControl1.Pages[Sheet];
                              Name:= 'ScrollBoxX' + IntToStr(Sheet);
                              VertScrollBar.Tracking:= FALSE;
                              BorderStyle:= bsSingle;
                              Align:= alClient
                              end
                              end;

                              PROCEDURE KreiereSpeedButton(Sheet, xKoor, yKoor, P: integer);
                              begin
                              if NOT Assigned(Self.FindComponent('SpeedButtonX' + IntToStr(i))) then // CST 11.09.2002
                              with TSpeedButton.Create(Self) do begin
                              Left:= xKoor;
                              Top:= yKoor;
                              Parent:= F_BEARB.FindComponent('ScrollBoxX' + IntToStr(Sheet)) as TWinControl;
                              Name:= 'SpeedButtonX' + IntToStr(i);
                              Caption:= '';
                              Tag:= P;
                              OnClick:= SpeedButtonXClick;
                              Glyph:= F_SETUP.BitBtn3.Glyph;
                              end;
                              end;
                              begin
                              .
                              .
                              KreierePage(TabSheetMerker[Bereich].Sheet, Bez);
                              .
                              .
                              end;
                              </PRE&gt

                              Comment

                              Working...
                              X