Announcement

Collapse
No announcement yet.

Woran erkenne ich ob eine Komponente ein Container ist ?

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

  • Woran erkenne ich ob eine Komponente ein Container ist ?

    Morgen,

    Ich habe vor eine Routine beim FormCreate aufzurufen die mir alle Komponeten auf dem Formular durchsucht und wenn eine vom Typ TOvcDateEdit ist soll er mir den Name in ein Memo schreiben, mein Problem ist wie gehe ich Bsp. ein Panel durch ? Ohne das ich sagen muss

    Ctrl : TControl
    if Ctrl is TPanel

  • #2
    Hallo Sven,<br>
    hier ein bißchen Source:<pre>
    <font face="Verdana" size="1" color="#000000">unit Unit1;

    interface

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

    type
    TForm1 = class(TForm)
    Label1: TLabel;
    Edit1: TEdit;
    Memo1: TMemo;
    Panel1: TPanel;
    CheckBox1: TCheckBox;
    Panel2: TPanel;
    Button1: TButton;
    Button2: TButton;
    ListBox1: TListBox;
    ListBox2: TListBox;
    Label2: TLabel;
    Label3: TLabel;
    procedure Button2Click(Sender: TObject);
    private
    { Private-Deklarationen }
    procedure FindControls(Base : TWinControl; L : TStrings);
    procedure FindComponents(Base : TForm; L : TStrings);
    public
    { Public-Deklarationen }
    end;

    var
    Form1: TForm1;

    implementation

    {$R *.dfm}

    { TForm1 }

    procedure TForm1.FindControls(Base: TWinControl; L: TStrings);
    var
    iCnt : Integer;
    begin
    For iCnt:=0 to Base.ControlCount-1 do
    begin
    If Base.Controls[iCnt] is TComponent then
    Listbox1.Items.AddObject(TComponent(Base.Controls[iCnt]).Classname,Base.Controls[iCnt]);
    // Jetzt prüfen, ob FindControls rekursiv aufgerufen werden soll
    If Base.Controls[iCnt] is TWinControl then <b><font face="Verdana" size="1" color="#0000FF">// Nur Nachfahren von TWinControl können Container sein !!!
    </font></b> FindControls(TWinControl(Base.Controls[iCnt]),L);
    end;
    end;

    procedure TForm1.Button2Click(Sender: TObject);
    begin
    ListBox1.Clear;
    FindControls(Form1,Listbox1.Items);
    ListBox2.Clear;
    FindComponents(Form1,Listbox2.Items);
    end;

    procedure TForm1.FindComponents(Base: TForm; L: TStrings);
    var
    iCnt : Integer;
    begin
    // Da Form1 Eigentümer aller Komponenten ist, wird hier die Reursion nicht benötigt
    For iCnt:=0 to Base.ComponentCount-1 do
    begin
    If Base.Components[iCnt] is TComponent then
    Listbox2.Items.AddObject(TComponent(Base.Component s[iCnt]).Classname,Base.Components[iCnt]);
    end;
    end;

    end.</font></pre>
    Folgendes kannst Du in der Hilfe finden<br>
    <pre>
    <font face="Verdana" size="1" color="#000000"><b><font face="Verdana" size="1" color="#FF0080">Controls</font></b> ist ein Array mit allen untergeordneten Steuerelementen. Dies sind alle Steuerelemente, die dieses
    Steuerelement in ihrer Eigenschaft <b><font face="Verdana" size="1" color="#FF0080">Parent</font></b> angeben. Die Eigenschaft Controls kann genutzt werden, wenn über den Index und nicht über den
    Namen auf ein Steuerelement zugegriffen werden soll. Controls kann beispielsweise genutzt werden, um nacheinander auf alle untergeordneten Steuerelemente zuzugreifen.
    Verwechseln Sie die Eigenschaft Controls nicht mit der Eigenschaft Components. Die Eigenschaft Controls listet alle Steuerelemente auf, die
    untergeordnete Steuerelemente dieses Steuerelements sind, während die Eigenschaft Components alle Komponenten aufführt, deren Eigentümer dieses
    Steuerelement ist. <b><font face="Verdana" size="1" color="#FF0080">Das Formular ist Eigentümer aller auf ihm plazierten Komponenten, die deshalb in der Eigenschaft Components des Formulars
    aufgelistet werden, auch wenn es sich um die untergeordneten Fenster eines Steuerelements im Formular handelt.
    </font></b>Controls ist eine schreibgeschützte Eigenschaft. Verwenden Sie die Methoden InsertControl oder RemoveControl, um ein untergeordnetes Steuerelement
    hinzuzufügen oder zu entfernen. Soll ein untergeordnetes Steuerelement einer anderen übergeordneten Komponente (Parent) zugeordnet werden, weisen
    Sie der Eigenschaft Parent des Steuerelements einen neuen Wert zu. Dadurch wird die Methode RemoveControl der bisher übergeordneten Komponente
    und anschließend die Methode InsertControl der neuen übergeordneten Komponente aufgerufen.</font>
    </pre>
    <br>
    <br>
    &#10

    Comment


    • #3
      Danke erstmal für deine mühe !
      Aber wenn ich beispiels weise einen Button in das Panel lege findet er dieses nicht !

      Comment


      • #4
        Danke, aber es geht nicht durch Panels oder andere Container durch und sucht nach Komponeten, mein ansatz schicke ich mal mit guck mal bitte durch was man in diesem Bsp. TTabSheet (ist ja mienes wissens nach ein Container) ersetzen könnte das ich nicht für jedes möglich Container diesen aufwand betreiben müsste .

        if Ctrl is TTabSheet then

        uses
        Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
        OvcBase, OvcEditF, OvcEdPop, OvcEdCal, ComCtrls, StdCtrls, ExtCtrls;

        type
        TForm1 = class(TForm)
        buStart: TButton;
        Edit1: TEdit;
        Memo1: TMemo;
        Panel1: TPanel;
        GroupBox1: TGroupBox;
        PageControl1: TPageControl;
        TabSheet1: TTabSheet;
        TabSheet2: TTabSheet;
        OvcDateEdit1: TOvcDateEdit;
        OvcController1: TOvcController;
        OvcDateEdit2: TOvcDateEdit;
        OvcDateEdit3: TOvcDateEdit;
        OvcDateEdit4: TOvcDateEdit;
        procedure buStartClick(Sender: TObject);
        private
        { Private-Deklarationen }
        public
        procedure InitForm(WinCtrl: TWinControl);
        { Public-Deklarationen }
        end;

        var
        Form1: TForm1;

        implementation

        {$R *.DFM}

        uses
        unVmInfo;

        procedure TForm1.buStartClick(Sender: TObject);
        begin
        InitForm(self);
        end;

        procedure TForm1.InitForm(WinCtrl: TWinControl);
        var
        j: Integer;
        Ctrl: TControl;
        begin
        for j := 0 to WinCtrl.ControlCount -1 do
        begin
        Ctrl := WinCtrl.Controls[j];
        if Ctrl is TOvcDateEdit then
        begin
        TOvcDateEdit(Ctrl).Epoch := VmInfo.Epoch;
        TOvcDateEdit(Ctrl).ForceCentury := True;
        end;
        if Ctrl is TGroupBox then
        begin
        InitForm(TWinControl(Ctrl));
        Continue;
        end;
        if Ctrl is TPanel then
        begin
        InitForm(TWinControl(Ctrl));
        Continue;
        end;
        if Ctrl is TPageControl then
        begin
        InitForm(TWinControl(Ctrl));
        Continue;
        end;
        if Ctrl is TTabSheet then
        begin
        InitForm(TWinControl(Ctrl));
        Continue;
        end;
        Form1.Memo1.Lines.Add(Ctrl.ClassName);
        end;
        end;

        end

        Comment


        • #5
          Danke !
          Wie hast du das so gut Formatiert bekommen ? Bist du jede Zeile durchgegangen und und hast ein <br> gemacht

          Comment


          • #6
            Hallo SvenB.<br>ich habe mir mal einen kleinen Editor (nur für den Eigengebrauch) gebastelt

            Comment


            • #7
              Hallo, Sven,
              du kannst dir auch mal den "Source Export" der GExperts anschauen.
              Damit kannst du direkt aus dem Delphi-Editor heraus HTML-"Abbilder"
              deines Codes generieren (mit Syntax-Highlighting).
              Funktioniert nicht ganz perfekt (bei mir fehlt z.B. (fast?) immer ein schließendes Font-Tag), aber mit ein, zwei zusätzlichen Handgriffen
              kannst du das hinbiegen.
              <br>Ciao, Uli

              Comment


              • #8
                Danke !

                Wobei das mit den Container immernoch nicht recht funzt ! er erkennt ein T Panel nicht als Container, meiner meihnung nach dürfte er ein Edit und ein Panel nicht in die die gleiche ListBox schreiben ! Habt ihr ne idee was z.B. ein Panel ein TabSheet haben was ein Edit nicht hat woran ich erkennen kann das es sich um ein Container handelt

                Comment


                • #9
                  Hallo Ulrich,<br>mit GExperts habe ich es auch probiert. GExperts erzeugt aber derart viele HTML-Tags, dass schnell die Zeichenbegrenzung des Forums erreicht ist

                  Comment


                  • #10
                    Hallo Sven,<br>hier eine Variante von FindComponents, die nur Container in die Listbox schiebt
                    <pre>
                    procedure TForm1.FindComponents(Base: TForm; L: TStrings); var
                    iCnt : Integer; begin
                    // Da Form1 Eigentümer aller Komponenten ist, wird hier die Reursion nicht benötigt
                    For iCnt:=0 to Base.ComponentCount-1 do begin
                    If (Base.Components[iCnt] is TWinControl) and (csAcceptsControls in TWinControl(Base.Components[iCnt]).ControlStyle) then
                    Listbox2.Items.AddObject(TComponent(Base.Component s[iCnt]).Classname,Base.Components[iCnt]);
                    end;
                    end;
                    </pre&gt

                    Comment


                    • #11
                      Man muß zwischen zwei Klassen von Kontainern/Hierarchien unterscheiden.<br>
                      <li>Komponeten-hierarchie (logischer Aufbau der VCL)
                      <li>Kontrol-hierarchie (visueller Aufbau der VCL, eng verknüpft mit der Windows-Fensterlogik)<br>

                      Die Komponentenhierarchie wird bestimmt durch TComponent.Components[] und TComponent.ComponentCount und TComponent.Owner, die Root ist fast immer ein TForm.<br>

                      Die Kontrolhierarchie wird bestimmt durch TWinControl.Controls[], TWinControl.ControlCount und TControl.Parent, die Root ist fast immer ein TForm.<br>

                      Mit TComponent.ControlStyle [csAcceptsControls] wird bestimmt ob diese Komponente = TWinControl visuell untergerordnete Controls besitzen darf, wohlgemerkt zur Design-Zeit im Delphi Formdesigner.
                      D.h. ein TWinControl ohne csAcceptControls kann trotzdem untergeordnete Childcontrols besitzen.<br>

                      Die Unterscheidung in Deinem Falle läuft also über TWinControl.ControlCount ! und muß demzufolge rekursive auch die untergeordnetetn Childcontrols durchscanen da diese ja selber wiederum "Kontainer" sein könnten.

                      <pre>

                      procedure ListControls(Control: TControl; Childs, Container: TStrings);
                      var
                      I: Integer;
                      begin
                      if (Control is TWinControl) and
                      (TWinControl(Control).ControlCount > 0) then
                      with TWinControl(Control) do
                      begin
                      Container.AddObject(Name, Control);
                      for I := 0 to ControlCount -1 do
                      ListControls(Controls[I], Childs, Container);
                      end else
                      Childs.AddObject(Control.Name, Control);
                      end;

                      </pre>

                      Hage

                      Comment


                      • #12
                        Danke erstmal ich probier mich mal an euren ansätzen ..

                        Comment

                        Working...
                        X