Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Problem mit Feld in selbstdefinierter Klasse (https://www.delphipraxis.net/27819-problem-mit-feld-selbstdefinierter-klasse.html)

Nothine 16. Aug 2004 02:58


Problem mit Feld in selbstdefinierter Klasse
 
Hi erstmal, bin jetz, obwohl ich schon länger hier lese und auch fast immer gute antworten gefunden hab :thumb:, auf ein problem gestoßen zu dem ich hier nirgendswo was gefunden hab... (und hab so mal ganz davon abgesehn meinen ersten post hier :stupid:)

Naja aber zum Problem, ich habe innerhalb einer selbstdefinierten klasse des typs tpanel eine private-deklarierte variable des typs tscrollbox, die wiederum mit weiteren panels gefüllt werden soll, was über den schreibzugriff auf die property PCCount geregelt werden soll
Delphi-Quellcode:
type TPCButtonList = class(TPanel)
  private
    FPCCount: Integer;
    ScrollBox: TScrollBox; // <-- besagtes Feld
    procedure SetPCCount(Count: Word); // <-- prozedur die das füllen regeln soll
  protected
  public
    constructor Create(AOwner: TComponent);    override;
    destructor Destroy;                       override;
    procedure  SetBounds(ALeft,ATop: Integer); reintroduce;
    property   PCCount: Integer read FPCCount write SetPCCount;
  published
  end;
nun funktioniert das auch beim ersten mal soweit ganz gut, im constructor wird die scrollbox initialisiert, ich füll sie beim erstellen mit werten,
Delphi-Quellcode:
  procedure InitializiseForm(Form: TForm);
  begin
    with TPCButtonList.Create(Application) do begin
      Parent := Form;
      Name  := 'PCButtonList';
      SetBounds(13,10);
      PCCount := 24; // <-- was hier passiert, 24 is jetz einfach irgendein wert
    end;
und alles is super, aber wenn ich nachträglich PCCount nochmal verändern will, löst quasi schon das angucken der variable ne exception aus, ich kann in der SetPCCount prozedur nicht mal überprüfen ob scrollbox nil ist ohne eine exception auszulösen...

der vollständigkeit halber hier nochmal die Set prozedur:
Delphi-Quellcode:
procedure TPCButtonList.SetPCCount(Count: Word);
var I: Integer;
const Tops: array[0..14] of Byte = (14,0,1,2,3,4,5,6,7,8,9,10,11,12,13);
begin
  if ScrollBox.ComponentCount-1 <> -1 then
    for I := 0 to ScrollBox.ComponentCount-1 do
      ScrollBox.Components[I].Free;
  for I := 1 to Count do begin
    with TPanel.Create(Application) do begin
      Parent := ScrollBox;
      Name   := 'Rechner' + IntToStr(I);
      Caption := 'SomeTitle' + ' ' + IntToStr(I);
      SetBounds((Pred(I)div 15)*70,30*Tops[I mod 15],65,22);
    end;
  end;
  FPCCount := Count;
end;
Naja der worte viel die frage natürlich kurz: woran liegt es das ich dieses feld bzw. diese variable nich mehr aufrufen kann?
bin dankbar für jede antwort :oops:

Hansa 16. Aug 2004 03:26

Re: Problem mit Feld in selbstdefinierter Klasse
 
nun denn, da fehlt doch was. :-D Wo ist PCcount und FPCcount genau deklariert ? Wie ich das da sehe müßte eine "Zugriffsverletzung bei Adresse blabla" auftreten.

Nothine 16. Aug 2004 03:30

Re: Problem mit Feld in selbstdefinierter Klasse
 
FPCCount is in der klasse TPCButtonList deklariert und PCCount is ne property und muss deswegen nich nochma deklariert werden, oder seh ich das falsch :?:

Edit: stimmt schon, ne zugriffsverletzung bei Addresse 00000208 oder so...

Stevie 16. Aug 2004 08:05

Re: Problem mit Feld in selbstdefinierter Klasse
 
1. procedure SetPCCount(Count: Integer);

2. Teilweise sind die Parameter für die Konstruktoren nicht korrekt gewählt

3. Du musst erst die erstellten Panels korrekt freigeben, sonst gibt's Konflikte!

Muetze1 16. Aug 2004 08:34

Re: Problem mit Feld in selbstdefinierter Klasse
 
Moin!

4. Wo im Constructor erstellst du denn die ScrollBox? Ich seh diebezüglich dort überhaupt nix.
5. Mich wunderts auch, dass du die erstellte Instanz von TPCButtonList nirgendwo ablegst und dir merkst...

MfG
Muetze1

Nothine 16. Aug 2004 14:37

Re: Problem mit Feld in selbstdefinierter Klasse
 
Zitat:

Zitat von Stevie
1. procedure SetPCCount(Count: Integer);
2. Teilweise sind die Parameter für die Konstruktoren nicht korrekt gewählt
3. Du musst erst die erstellten Panels korrekt freigeben, sonst gibt's Konflikte!

zu 1) wo liegt der Sinn mehr Speicherplatz zu verbrauchen wenn für Count eh nur positive Werte gewählt werden? Ich hätt auch Byte genommen, aber andererseits wollt ich mir eine Zahl über 255 offen halten
zu 2) da ich den constructor noch gar nich gepostet hatte verweise ich dich auf weiter unten in meinem beitrag :zwinker:
zu 3) genau das bezwecke ich ja mit den ersten 3 zeilen der SetPCCount prozedur! er soll alle panels (bzw. generell alle komponenten) die in der scrollbox liegen free'en um anschließend dem werte-parameter count entsprechend neue panels zu erstellen

Zitat:

Zitat von Muetze1
4. Wo im Constructor erstellst du denn die ScrollBox? Ich seh diebezüglich dort überhaupt nix.
5. Mich wunderts auch, dass du die erstellte Instanz von TPCButtonList nirgendwo ablegst und dir merkst...

zu 4) den constructor hab ich noch gar nich gepostet ^^ des mach ich dann jetz ma schnell...
Delphi-Quellcode:
constructor TPCButtonList.Create(AOwner: TComponent);
  begin
    inherited Create(Application);
    ScrollBox := TScrollBox.Create(Application);
    with ScrollBox do begin
      Name        := 'ScrollBox';
      Parent      := self;
      AutoScroll  := True;
      BorderStyle := bsNone;
      @OnMouseMove := @MouseMoves;
      with HorzScrollBar do begin
        Increment := 70;
        Smooth    := False;
        Tracking  := True;
      end;
    end;
    FPCCount := 0;
  end;
zu 5) hm ja aber wozu auch, innerhalb der prozeduren für die klasse kann ich ja mit self drauf zugreifen...

ich seh schon, das wird doch nich so einfach wie ich dachte :roll:

Stevie 16. Aug 2004 15:03

Re: Problem mit Feld in selbstdefinierter Klasse
 
Zitat:

Zitat von Nothine
Zitat:

Zitat von Stevie
1. procedure SetPCCount(Count: Integer);
2. Teilweise sind die Parameter für die Konstruktoren nicht korrekt gewählt
3. Du musst erst die erstellten Panels korrekt freigeben, sonst gibt's Konflikte!

zu 1) wo liegt der Sinn mehr Speicherplatz zu verbrauchen wenn für Count eh nur positive Werte gewählt werden? Ich hätt auch Byte genommen, aber andererseits wollt ich mir eine Zahl über 255 offen halten
zu 2) da ich den constructor noch gar nich gepostet hatte verweise ich dich auf weiter unten in meinem beitrag :zwinker:
zu 3) genau das bezwecke ich ja mit den ersten 3 zeilen der SetPCCount prozedur! er soll alle panels (bzw. generell alle komponenten) die in der scrollbox liegen free'en um anschließend dem werte-parameter count entsprechend neue panels zu erstellen

zu 1.: Ich meine damit, dass das so überhaupt nicht läuft!!! (Weil Property-Typ <> Parameter-Typ)

zu 2.: Ich wollte damit sagen, dass der an Create übergebene Parameter nicht immer unbedingt der beste ist (z.B. statt Application lieber Form o.Ä.)

zu 3.: Die werden aber nicht richtig freigegeben!!!

Ich hab's mit Delphi6Pro getestet und die oben genannten Probleme gehabt... :roll:

Gruber_Hans_12345 16. Aug 2004 15:17

Re: Problem mit Feld in selbstdefinierter Klasse
 
Hi
Zitat:

Zitat von Nothine
und alles is super, aber wenn ich nachträglich PCCount nochmal verändern will, löst quasi schon das angucken der variable ne exception aus, ich kann in der SetPCCount prozedur nicht mal überprüfen ob scrollbox nil ist ohne eine exception auszulösen...

wo willst du zB den PCCount ändern ? Hast du diesen teil des Codes, wo du den PCCount ändern willst ?

Stevie 16. Aug 2004 15:32

Re: Problem mit Feld in selbstdefinierter Klasse
 
Die Exception kommt, weil du den PCCount eines nicht initialisierten Objekts ändern willst! (Daher die Frage(5.) von Mütze, hab ich auch voll übersehen... :oops:)

Nachfolgende Fehler:
- Das Freigeben der Labels klappt auch nicht richtig, weil sie nicht als Unterelemente von deiner ScrollBox erstellt werden. (und somit nicht über Components erreichbar sind)
- Wenn du eine Schleife durchläufst und dann einzelne Elemente aus der Liste nimmst, dann stimmt der Zähler nicht, denn wenn i = 0 ist und du somit das 1. Element löscht, wird das 2. zum Element[0], aber du bist jetzt bei i=1. Das heißt, jedes 2.Element wird gelöscht und dann gibt's einen Überlauf!!!

Hier die gefixte Unit:
Delphi-Quellcode:
unit PCButtonList;

interface

uses
  Windows, Messages, SysUtils, Classes, Controls, ExtCtrls, Forms;

type TPCButtonList = class(TPanel)
  private
    FPCCount: Integer;
    ScrollBox: TScrollBox; // <-- besagtes Feld
    procedure SetPCCount(Count: Integer); // <-- prozedur die das füllen regeln soll
  protected
  public
    constructor Create(AOwner: TComponent);    override;
    destructor Destroy;                       override;
//    procedure  SetBounds(ALeft,ATop: Integer); reintroduce;
    property   PCCount: Integer read FPCCount write SetPCCount;
  published
  end;

procedure Register;

implementation

procedure Register;
begin
  RegisterComponents('Beispiele', [TPCButtonList]);
end;

{ TPCButtonList }

constructor TPCButtonList.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  ScrollBox := TScrollBox.Create(Self);
  with ScrollBox do
  begin
    Name        := 'ScrollBox';
    Parent      := self;
    AutoScroll  := True;
    BorderStyle := bsNone;
//    @OnMouseMove := @MouseMoves;
    with HorzScrollBar do
    begin
      Increment := 70;
      Smooth    := False;
      Tracking  := True;
    end;
  end;
  FPCCount := 0;
end;

destructor TPCButtonList.Destroy;
begin
  FreeAndNil(ScrollBox);
  inherited;
end;

procedure TPCButtonList.SetPCCount(Count: Integer);
var I: Integer;
const Tops: array[0..14] of Byte = (14,0,1,2,3,4,5,6,7,8,9,10,11,12,13);
begin
  while ScrollBox.ComponentCount > 0 do
    ScrollBox.Components[0].Free;
  for I := 1 to Count do
  begin
    with TPanel.Create(ScrollBox) do
    begin
      Parent := ScrollBox;
      Name   := 'Rechner' + IntToStr(I);
      Caption := 'SomeTitle' + ' ' + IntToStr(I);
      SetBounds((Pred(I)div 15)*70,30*Tops[I mod 15],65,22);
    end;
  end;
  FPCCount := Count;
end;

end.
Und der Aufruf:
Delphi-Quellcode:
unit Unit1;

interface

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

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure FormCreate(Sender: TObject);
    procedure Button1Click(Sender: TObject);
  private
    { Private-Deklarationen }
    PCButtonList: TPCButtonList;
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
  PCButtonList := TPCButtonList.Create(Form1);
  with PCButtonList do
  begin
    Parent := Form1;
    Name  := 'PCButtonList';
//    SetBounds(13,10);
    PCCount := 24; // <-- was hier passiert, 24 is jetz einfach irgendein wert
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  PCButtonList.PCCount := 10;
end;

end.
Nur nicht unterkriegen lassen!!! ;-) :thumb:

Nothine 16. Aug 2004 15:48

Re: Problem mit Feld in selbstdefinierter Klasse
 
Zitat:

Nachfolgende Fehler:
- Das Freigeben der Labels klappt auch nicht richtig, weil sie nicht als Unterelemente von deiner ScrollBox erstellt werden. (und somit nicht über Components erreichbar sind)
- Wenn du eine Schleife durchläufst und dann einzelne Elemente aus der Liste nimmst, dann stimmt der Zähler nicht, denn wenn i = 0 ist und du somit das 1. Element löscht, wird das 2. zum Element[0], aber du bist jetzt bei i=1. Das heißt, jedes 2.Element wird gelöscht und dann gibt's einen Überlauf!!!

[...]

Nur nicht unterkriegen lassen!!! ;-) :thumb:
:shock: man bin ich doof, auf sowas hätt ich auch selber kommen können :wall:
danke für die hilfe! :-D :bounce1:


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