Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Delphi Anzahl Formulare / Dynamisch Klassen ansprechen? (https://www.delphipraxis.net/123356-anzahl-formulare-dynamisch-klassen-ansprechen.html)

miLeRiAm 31. Okt 2008 10:17


Anzahl Formulare / Dynamisch Klassen ansprechen?
 
moin moin,

ja, ich habe bereits die suchfunktion genutzt und einen hinweis darauf erhalten, dass "Screen.FormCount" das sein soll, was ich benötige. Ist es aber leider offensichtlich nicht ganz.

Delphi-Quellcode:
  for j := 0 to screen.FormCount-1 do
   for i := 0 to screen.forms[j].componentcount-1 do
   screen.forms[j].components[i].tag := ((j+1) * 10000) + i;
Problem: Ich habe derzeit 3 Formulare, die for geht also von 0 - 2, das überschreitet dann aber den Listindex?

Zitat:

---------------------------
Benachrichtigung über Debugger-Exception
---------------------------
Im Projekt sms_manager.exe ist eine Exception der Klasse EListError mit der Meldung 'Listenindex überschreitet das Maximum (2)' aufgetreten.
---------------------------
Anhalten Fortsetzen Hilfe
---------------------------

Ideen?


Edith meint: Kann es sein das "FormCount" eine andere Anzahl Formulare zurückgibt, als sich in dem Array "Forms" zurückgibt?

DeddyH 31. Okt 2008 10:19

Re: Anzahl Formulare in der Applikation
 
Zitat:

Delphi-Quellcode:
for j := 0 to screen.FormCount-0 do

Wieso -0? Macht ja keinen Sinn.

Angel4585 31. Okt 2008 10:23

Re: Anzahl Formulare in der Applikation
 
FormCount beinhaltet zB 2

dann geht deine Schleife

0
1
2

das Array hat die Felder

0
1

:zwinker:

miLeRiAm 31. Okt 2008 10:24

Re: Anzahl Formulare in der Applikation
 
Zitat:

Zitat von DeddyH
Zitat:

Delphi-Quellcode:
for j := 0 to screen.FormCount-0 do

Wieso -0? Macht ja keinen Sinn.

Zitat:

Zitat von Angel4585
FormCount beinhaltet zB 2

dann geht deine Schleife

0
1
2

das Array hat die Felder

0
1

:zwinker:

Tippfehler, ist natürlich -1.

Klappen tut es leider auch mit -1 nicht.

DeddyH 31. Okt 2008 10:25

Re: Anzahl Formulare in der Applikation
 
Und mit -1 kommt der Fehler auch?

miLeRiAm 31. Okt 2008 10:30

Re: Anzahl Formulare in der Applikation
 
Zitat:

Zitat von DeddyH
Und mit -1 kommt der Fehler auch?

Ja, allerdings verstehe ich das nicht.

Ich habe 3 Forms.

TfrmMain
TfrmLogin
TfrmAddEntry

in der TfrmMain wird das ganze gemacht und die for geht bis zum Index 3 (???).


Delphi-Quellcode:
  for j := 0 to screen.FormCount-1 do


   for i := 0 to screen.Forms[j].ComponentCount-1 do screen.Forms[j].Components[i].Tag := ((j+1) * 10000) + i;


   for i := 0 to screen.Forms[j].ComponentCount-1 do

   if (screen.Forms[j].Components[i] is TButton)     or
      (screen.Forms[j].Components[i] is TToolButton) or
      (screen.Forms[j].Components[i] is TLabel)      or
      (screen.Forms[j].Components[i] is TMenuItem)   or
      (screen.Forms[j].Components[i] is TCheckBox)   or
      (screen.Forms[j].Components[i] is TRadioButton) or
      (screen.Forms[j].Components[i] is TTabSheet)   or
      (screen.Forms[j].Components[i] is TSpeedButton) then
   begin

     if screen.Forms[j].Components[i] is TButton then
     handleList.Add(IntToStr(screen.Forms[j].Components[i].Tag)+'='+TButton(screen.Forms[j].Components[i]).Caption);

     if screen.Forms[j].Components[i] is TToolButton then
     handleList.Add(IntToStr(screen.Forms[j].Components[i].Tag)+'='+TToolButton(screen.Forms[j].Components[i]).Caption);

     if screen.Forms[j].Components[i] is TLabel then
     handleList.Add(IntToStr(screen.Forms[j].Components[i].Tag)+'='+TLabel(screen.Forms[j].Components[i]).Caption);

     if screen.Forms[j].Components[i] is TMenuItem then
     handleList.Add(IntToStr(screen.Forms[j].Components[i].Tag)+'='+TMenuItem(screen.Forms[j].Components[i]).Caption);

     if screen.Forms[j].Components[i] is TCheckBox then
     handleList.Add(IntToStr(screen.Forms[j].Components[i].Tag)+'='+TCheckBox(screen.Forms[j].Components[i]).Caption);

     if screen.Forms[j].Components[i] is TRadioButton then
     handleList.Add(IntToStr(screen.Forms[j].Components[i].Tag)+'='+TRadioButton(screen.Forms[j].Components[i]).Caption);

     if screen.Forms[j].Components[i] is TTabSheet then
     handleList.Add(IntToStr(screen.Forms[j].Components[i].Tag)+'='+TTabSheet(screen.Forms[j].Components[i]).Caption);

     if screen.Forms[j].Components[i] is TSpeedButton then
     handleList.Add(IntToStr(screen.Forms[j].Components[i].Tag)+'='+TSpeedButton(screen.Forms[j].Components[i]).Caption);

   end;

end;

Ach ja, wenn jemand einen -sauberen- (!) weg kennt, alle Captions von Componenten, die Captions haben dürfen in eine Liste zu speichern, immer her damit. Damit ärgere ich mich nämlich schon geraume Zeit herum. Der Code ist mittlerweile auch ziemlich Dirty, da ich ständig dran rumändere.

DeddyH 31. Okt 2008 10:33

Re: Anzahl Formulare in der Applikation
 
Zuerst einmal fällt mir auf, dass da ein begin-end-Block fehlt. Eigentlich müsste auch eine Compiler-Warnung kommen, dass j nach Schleifendurchlauf undefiniert sei. Und evtl. könntest Du es mal mit RTTI versuchen, aber damit kenn ich mich auch nicht aus, die Forensuche sollte da aber weiterhelfen.

miLeRiAm 31. Okt 2008 10:41

Re: Anzahl Formulare in der Applikation
 
Zitat:

Zitat von DeddyH
Zuerst einmal fällt mir auf, dass da ein begin-end-Block fehlt. Eigentlich müsste auch eine Compiler-Warnung, dass j nach Schleifendurchlauf undefiniert sei. Und evtl. könntest Du es mal mit RTTI versuchen, aber damit kenn ich mich auch nicht aus, die Forensuche sollte da aber weiterhelfen.

i lol'ed in rL.

Danke, begin / end.. man. Ist noch zu früh ;)

Frankfurtoder 31. Okt 2008 10:56

Re: Anzahl Formulare in der Applikation
 
Formatieren hilft ;) Der Code mit den If's sieht ja grausam aus.

miLeRiAm 31. Okt 2008 11:10

Re: Anzahl Formulare in der Applikation
 
Zitat:

Zitat von Frankfurtoder
Formatieren hilft ;) Der Code mit den If's sieht ja grausam aus.

Delphi-Quellcode:
 if handleList.Count = 0 then
 begin

  frmMain.handleList.Clear;

  for j := 0 to screen.FormCount-1 do
  begin

   for i := 0 to screen.Forms[j].ComponentCount-1 do
   begin
    screen.Forms[j].Components[i].Tag := ((j+1) * 10000) + i;
   end;

   for i := 0 to screen.Forms[j].ComponentCount-1 do
   begin

    comp := screen.Forms[j].Components[i];

    if (comp is TButton) or (comp is TToolButton) or (comp is TLabel) or (comp is TMenuItem) or
       (comp is TCheckBox) or (comp is TRadioButton) or (comp is TTabSheet) or (comp is TSpeedButton)
    then
     begin

      if comp is TButton then     handleList.Add(IntToStr(comp.Tag)+'='+TButton(comp).Caption);
      if comp is TToolButton then handleList.Add(IntToStr(comp.Tag)+'='+TToolButton(comp).Caption);
      if comp is TLabel then      handleList.Add(IntToStr(comp.Tag)+'='+TLabel(comp).Caption);
      if comp is TMenuItem then   handleList.Add(IntToStr(comp.Tag)+'='+TMenuItem(comp).Caption);
      if comp is TCheckBox then   handleList.Add(IntToStr(comp.Tag)+'='+TCheckBox(comp).Caption);
      if comp is TRadioButton then handleList.Add(IntToStr(comp.Tag)+'='+TRadioButton(comp).Caption);
      if comp is TTabSheet then   handleList.Add(IntToStr(comp.Tag)+'='+TTabSheet(comp).Caption);
      if comp is TSpeedButton then handleList.Add(IntToStr(comp.Tag)+'='+TSpeedButton(comp).Caption);

     end;

   end;

  end;

 end;

Habe ich grade ;)
Wurde langsam wirklich unübersichtlich.

Gefallen tut mir die Lösung aber dennoch nicht.

Stichwort: Mehrsprachigkeit.

angos 31. Okt 2008 11:11

Re: Anzahl Formulare in der Applikation
 
Hi,

um heruaszufinden ob ein Objekt eine Property hat, habe ich hier im Forum mal was gefunden gehabt:


Delphi-Quellcode:
uses
  TypInfo;
[...]

function HasProperty(AClass : TObject; APropertyName : String) : Boolean;
var
  MyPropInfo: PPropInfo;
begin
  MyPropInfo := GetPropInfo(AClass.ClassInfo, APropertyName);
  Result := MyPropInfo <> NIL;
end;

procedure TForm1.btnClick(Sender: TObject);
begin
  if HasProperty(MeinObjekt, 'Caption') then
  begin

  end;
end;
HTH
Ansgar

DeddyH 31. Okt 2008 11:16

Re: Anzahl Formulare in der Applikation
 
Abgesehen davon verstehe ich nicht, wieso 2 Schleifen nacheinander abgearbeitet werden.
Zitat:

Delphi-Quellcode:
...
   for i := 0 to screen.Forms[j].ComponentCount-1 do //erste Schleife
   begin
    screen.Forms[j].Components[i].Tag := ((j+1) * 10000) + i;
   end;

   for i := 0 to screen.Forms[j].ComponentCount-1 do //zweite Schleife
   begin

    comp := screen.Forms[j].Components[i];
...


miLeRiAm 31. Okt 2008 11:24

Re: Anzahl Formulare in der Applikation
 
Und so wird der Code immer schöner.
HasProperty ist zwar super, allerdings hilft mir das nicht weite.

Delphi-Quellcode:
 if handleList.Count = 0 then
 begin

  for j := 0 to screen.FormCount-1 do
  begin

   for i := 0 to screen.Forms[j].ComponentCount-1 do
   begin

    comp := screen.Forms[j].Components[i];

    comp.Tag := ((j+1) * 10000) + i;

      if comp is TButton then     handleList.Add(IntToStr(comp.Tag)+'='+TButton(comp).Caption);
      if comp is TToolButton then handleList.Add(IntToStr(comp.Tag)+'='+TToolButton(comp).Caption);
      if comp is TLabel then      handleList.Add(IntToStr(comp.Tag)+'='+TLabel(comp).Caption);
      if comp is TMenuItem then   handleList.Add(IntToStr(comp.Tag)+'='+TMenuItem(comp).Caption);
      if comp is TCheckBox then   handleList.Add(IntToStr(comp.Tag)+'='+TCheckBox(comp).Caption);
      if comp is TRadioButton then handleList.Add(IntToStr(comp.Tag)+'='+TRadioButton(comp).Caption);
      if comp is TTabSheet then   handleList.Add(IntToStr(comp.Tag)+'='+TTabSheet(comp).Caption);
      if comp is TSpeedButton then handleList.Add(IntToStr(comp.Tag)+'='+TSpeedButton(comp).Caption);

   end; // for i = components

  end; // for j = forms

 end; // if list is empty

Das Problem bleibt bestehen, dass ich in Delphi (bisher) keine Möglichkeit gefunden habe, Klassen dynamisch zuzuweisen, z.B. so:

TClass('TLabel').Caption
oder
TClass(comp.ClassName).Caption

Das kann in Delphi nie klappen, da man sofort die Klassentypen benötigt um auf etwas zuzugreifen.
Es wird nicht einfach compiliert in der Hoffnung der User weiß genau was er da gerade zusammenbaut.

Ideen?

DeddyH 31. Okt 2008 11:49

Re: Anzahl Formulare / Dynamisch Klassen ansprechen?
 
Basierend auf obigem Code habe ich mal diese Funktion gebastelt:
Delphi-Quellcode:
function CompHasCaption(AClass : TObject; out sResult: string): Boolean;
const sProp = 'Caption';
var
  MyPropInfo: PPropInfo;
begin
  sResult := '';
  MyPropInfo := GetPropInfo(AClass.ClassInfo, sProp);
  Result := Assigned(MyPropInfo);
  if Result then
    sResult := GetPropValue(AClass, sProp);
end;
Damit sollte es gehen.

miLeRiAm 31. Okt 2008 11:54

Re: Anzahl Formulare / Dynamisch Klassen ansprechen?
 
Delphi-Quellcode:
 if handleList.Count = 0 then
 begin

  for j := 0 to screen.FormCount-1 do

   for i := 0 to screen.Forms[j].ComponentCount-1 do
   begin

    comp := screen.Forms[j].Components[i];

    comp.Tag := ((j+1) * 10000) + i;

    if (CompHasCaption(Comp, s)) then handleList.Add(IntToStr(comp.Tag)+'='+s);

   end; // for i = components

 end; // if list is empty

Wie wenig code das nur noch ist ;)

VIELEN lieben Dank, hat mich viele Nerven gekostet.


Für alle die noch was setzen wollen, so gehts:

Delphi-Quellcode:
function CompSetCaption(AClass : TObject; Caption: string): Boolean;
const sProp = 'Caption';
var
  MyPropInfo: PPropInfo;
begin
  MyPropInfo := GetPropInfo(AClass.ClassInfo, sProp);
  Result := Assigned(MyPropInfo);
  if Result then
  begin
   SetPropValue(AClass, sProp, Caption);
   result := true;
  end else
   result := false;
end;

DeddyH 31. Okt 2008 12:09

Re: Anzahl Formulare / Dynamisch Klassen ansprechen?
 
Kleiner Verbesserungsvorschlag:
Delphi-Quellcode:
function CompSetCaption(AClass : TObject; const Caption: string): Boolean;
const sProp = 'Caption';
var
  MyPropInfo: PPropInfo;
begin
  MyPropInfo := GetPropInfo(AClass.ClassInfo, sProp);
  Result := Assigned(MyPropInfo);
  if Result then
    SetPropValue(AClass, sProp, Caption);
end;

miLeRiAm 31. Okt 2008 12:22

Re: Anzahl Formulare / Dynamisch Klassen ansprechen?
 
Vielen Dank, habs allesamt mal für die codelib vorgeschlagen :)

Sehr sehr praktisch.


Alle Zeitangaben in WEZ +1. Es ist jetzt 02:28 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