Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Schleife durch alle Controls eines Parents liefert falsche Control-Inhalte (https://www.delphipraxis.net/175862-schleife-durch-alle-controls-eines-parents-liefert-falsche-control-inhalte.html)

cltom 24. Jul 2013 15:24

Delphi-Version: XE2

Schleife durch alle Controls eines Parents liefert falsche Control-Inhalte
 
Hallo,

mühsamer Titel, komischer Effekt. Ich habe eine Klasse mit einer Prozedur, die mir alle Controls eines Parents durchgeht und abhängig vom Control-Typ den Inhalt ausliest. Ähnliche Prozeduren sind hier schon mehrfach aufgetaucht. Sinngemäß sieht das so aus:

Delphi-Quellcode:
{*******************************************************************}
procedure TUserInterfaceOps.ControlToStringList(parentcontrol : TWinControl;
  var astringlist: TStringList; includename, includevalue : boolean);
{*******************************************************************}
var
  i : integer;
  str_temp : string;
begin

  for i := 0 to parentcontrol.ControlCount-1 do
    begin
      try

        str_temp := '';

        if parentcontrol.Controls[i] is TAdvPanel then
          ControlToStringList(TWinControl(parentcontrol.Controls[i]),astringlist,includename,includevalue);

        if parentcontrol.Controls[i] is TAdvEdit then
          begin
            if includename then str_temp := parentcontrol.Controls[i].Name;
            if includename and includevalue then str_temp := str_temp + ' = ';
            if includevalue then str_temp := str_temp + (parentcontrol.Controls[i] as TAdvEdit).Text;
            astringlist.Add(str_temp);
          end;

        if parentcontrol.Controls[i] is TCheckBox then
          begin
            if includename then str_temp := parentcontrol.Controls[i].Name;
            if includename and includevalue then str_temp := str_temp + ' = ';
            if includevalue then str_temp := str_temp + BoolToStr((parentcontrol.Controls[i] as TCheckBox).checked);
            astringlist.Add(str_temp);
          end;

      except
        astringlist.Add('Error reading ' + parentcontrol.Controls[i].Name);

      end;

    end;

end;
Der Prozedur übergebe ich das ganze Formular und krieg dann eine Stringlist nach dem Schema:

Edit1 = Edit1Text
Edit2 = Edit2Text

usw.

Das funktionierte bis dato problemlos, solange das Projekt eigenständig war. Wenn aber ich das aufrufende Objekt/Formular aber in ein anderes Projekt integriere, dann liefert mir die Prozedur eine Liste von Werten, die nicht in den Edits drin stehen, sondern die beim Create des Forms erzeugt wurden.

Wenn ich zB folgendes probiere:

Delphi-Quellcode:
        if parentcontrol.Controls[i] is TAdvEdit then
          begin
            if includename then str_temp := parentcontrol.Controls[i].Name;
            if includename and includevalue then str_temp := str_temp + ' = ';
            (parentcontrol.Controls[i] as TAdvEdit).Text := 'irgendwas'; //<----- 
            if includevalue then str_temp := str_temp + (parentcontrol.Controls[i] as TAdvEdit).Text;
            astringlist.Add(str_temp);
          end;
dann wird zwar der wert "irgendwas" in die Stringliste geschrieben, nicht aber zurück aufs Form. Ich kann auch direkt vor dem Aufruf von ControlsToStringList noch etwas in die edits reinschreiben (im delphicode), in der StringList taucht dann dennoch der Wert auf, den ich beim Create des Forms zugewiesen habe.

danke für hinweise
tom

Der schöne Günther 24. Jul 2013 15:52

AW: Schleife durch alle Controls eines Parents liefert falsche Control-Inhalte
 
Vielleicht wird das, was die .Text-Property ausliest nur aktualisiert, wenn der Benutzer es auch sieht, also beim Zeichnen des Controls? Veranlasse vor dem Auslesen doch mal ein Neuzeichnen.

Mikkey 6. Aug 2013 11:01

AW: Schleife durch alle Controls eines Parents liefert falsche Control-Inhalte
 
Bin zwar neu in Delphi, aber das kann in jeder anderen Sprache denselben Effekt ergeben.

Der Inhalt von Edit-Controls wird im Windows per "SetWindowText" gesetzt. Dies löst üblicherweise eine WM-SETTEXT-Nachricht aus. Da Du mit der Schleife innerhalb des Threads bist (davon gehe ich jedenfalls aus) werden Änderungen, die an den Controls vorgenommen werden erst nach Ende der Schleife verarbeitet.

Es ist zwar denkbar, dass WM_SETTEXT mit "SendMessage" an das Control gegeben wird, es ist aber wahrscheinlich, dass dabei Verklemmungen oder Endlosrekursionen auftreten. So wird WM_SETTEXT nur in der Warteschlange abgelegt und später verarbeitet.

Gruß, Mikkey

cltom 21. Aug 2013 12:57

AW: Schleife durch alle Controls eines Parents liefert falsche Control-Inhalte
 
Danke für die Hinweise.

Nach einigen Stunden überlegen (und zwei Wochen Urlaub) kam heute die Lösung:

beim Aufruf der Prozedur ControlToStringList hatte ich als ParentControl einen konkreten Form-Namen drin. Das hab ich durch "self" ersetzt und voilà. Jetzt kann man mich vermutlich dafür prügeln, ich nehme aber an, dieses Verhalten liegt daran, dass ich das Formular mit

with TBestimmtesForm.Create(Application) do
Show;

erzeuge. :oops:

Deswegen hat es auch als Standalone geklappt, weil da das Formular, das der ControlToStringList übergeben wird, das zum Projektstart erzeugte Hauptform ist. Ich bin aber dankbar für eine fundiertere Erklärung zum Verständnis.

Olli73 21. Aug 2013 13:23

AW: Schleife durch alle Controls eines Parents liefert falsche Control-Inhalte
 
Zitat:

Zitat von cltom (Beitrag 1225673)
beim Aufruf der Prozedur ControlToStringList hatte ich als ParentControl einen konkreten Form-Namen drin. Das hab ich durch "self" ersetzt und voilà.

with TBestimmtesForm.Create(Application) do
Show;

Dein "konkreter Form-Name" ist eine globale Variable und wenn du dieser Variablen nicht deine erzeugte Form zuweist (Form2 := TForm2.Create(...)) steht natürlich auch keine Referenz auf die erzeugte Form drin. Da es nicht "geknallt" hat, gehe ich davon aus, dass auch zusätzlich eine Instanz beim Start automatisch von Delphi erstellt wird, worauf dann die Variable verweist.

Wenn es möglich sein soll, mehrere Instanzen des Formulars zu erstellen dann mache Folgendes:
(1) Sicherstellen, dass keine Instanz automatisch erzeugt wird
(2) Lösche die globale Variable weg. Dann kommst du nicht in Versuchung...

uligerhardt 21. Aug 2013 13:25

AW: Schleife durch alle Controls eines Parents liefert falsche Control-Inhalte
 
Wenn du raten musst, was bei
Delphi-Quellcode:
with
passiert, verwende es nicht. :mrgreen:
Was konkret schiefläuft, ist ohne etwas mehr Code schwer zu sagen.


Alle Zeitangaben in WEZ +1. Es ist jetzt 03:46 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz