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/)
-   -   procedure wird nicht aufgerufen (https://www.delphipraxis.net/154301-procedure-wird-nicht-aufgerufen.html)

JnZn558 5. Sep 2010 08:20

procedure wird nicht aufgerufen
 
Delphi-Quellcode:
TAb = class(TPersistent)
  private
    m_owndraw: Boolean;

  public
    constructor Create;

  published
    property DrawOwn: Boolean read m_owndraw write m_owndraw;

  end;

  TTest = class(TPageControl)
  private
    m_tab: Boolean;

    procedure SetTab( ab: Boolean );

  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;

  published
    property DrawOwn: Boolean read m_tab write SetTab;

  end;
bei obige beispiel wird die procedure SetTab korrekt aufgerufen

Delphi-Quellcode:
TAb = class(TPersistent)
  private
    m_owndraw: Boolean;

  public
    constructor Create;

  published
    property DrawOwn: Boolean read m_owndraw write m_owndraw;

  end;

  TTest = class(TPageControl)
  private
    m_tab: TAb;

    procedure SetTab( ab: TAb );

  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;

  published
    property DrawOwn: TAb read m_tab write SetTab;

  end;
hier wird die procedure SetTab gar nicht aufgerufen, warum tut es nicht??? was mache ich falsch

SirThornberry 5. Sep 2010 08:42

AW: procedure wird nicht aufgerufen
 
weißt du denn bei der zweiten Klasse überhaupt jemals ein TAb zu?
Der Unterschied ist das beim ersten Quelltext dein mTab ein einfacher Datentyp ist. Beim zweiten Quelltext ist es hingegen eine Klasse bei der dann auch eine Instanz erzeugt werden muss etc.

JnZn558 5. Sep 2010 10:09

AW: procedure wird nicht aufgerufen
 
ja, eine instanz hab ich erzeugt, sonst wuerde man die Subeigentschaft DrawOwn nicht angezeigt.

Sir Rufo 5. Sep 2010 10:18

AW: procedure wird nicht aufgerufen
 
imho muss keine Instanz erzeugt werden, es wird ja lediglich die Referenz in ab gespeichert.
Somit müsste SetTab auch dann durchlaufen werden, wenn man DrawOwn nur nil zuweist.

Ich befürchte aber, dass der Teufel da im Detail steckt.

Wäre schön, wenn wir den ganzen Quellcode zu diesen Klassen bekommen könnten
ach ja, und natürlich den Code, wo diese Klasse benutzt wird.

sx2008 5. Sep 2010 13:14

AW: procedure wird nicht aufgerufen
 
Zitat:

Zitat von JnZn558 (Beitrag 1047575)
was mache ich falsch?

Du hältst dich nicht an die Namenskonventionen von Borland und verwirrst dadurch die Mitleser und auch dich selbst.
Daher sollte der Code so aussehen:
Delphi-Quellcode:
private
  FDrawOwn : Boolean;
  procedure SetDrawOwn(const Value:Boolean);
public
 property DrawOwn: Boolean read FDrawOwn write SetDrawOwn;
So erkennt man leichter was zusammengehört (weil "DrawOwn" konsistent verwendet wird).

Wenn auf das Property DrawOwn niegends schreibend zugegriffen wird, dann optimiert der Kompiler die Procedure SetDrawOwn einfach weg.
Man erkennt es daran, dass die blauen Punkte nach dem Kompilieren fehlen.

JnZn558 5. Sep 2010 16:58

AW: procedure wird nicht aufgerufen
 
so hier den ganzen komponente quellcode
ist nur so ne beispiel, deshalb kein besondere sagenhafte Name vergeben.
Delphi-Quellcode:
unit PageControl1;

interface

uses
  SysUtils, Classes, Controls, ComCtrls;

type
  TAb = class(TPersistent)
  private
    m_owndraw: Boolean;

  public
    constructor Create;

  published
    property DrawOwn: Boolean read m_owndraw write m_owndraw;

  end;

  TTest = class(TPageControl)
  private
    m_tab: TAb;

    procedure SetTab( ab: TAb );

  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;

  published
    property DrawOwn: TAb read m_tab write SetTab;

  end;

procedure Register;

implementation

  procedure Register;
  begin
    RegisterComponents('Samples', [TTest]);
  end;

  { TAb }

  constructor TAb.Create;
  begin
    Self.m_owndraw := True;
  end;

{ TTest }

constructor TTest.Create(AOwner: TComponent);
begin
  inherited;
  Self.m_tab := TAb.Create;
end;

destructor TTest.Destroy;
begin
  Self.m_tab.Free;
  inherited;
end;

procedure TTest.SetTab(ab: TAb);
begin
  Self.m_tab := ab;
  Self.OwnerDraw := ab.DrawOwn;
end;

end.
Zitat:

Zitat von sx2008 (Beitrag 1047605)
Zitat:

Zitat von JnZn558 (Beitrag 1047575)
was mache ich falsch?

Du hältst dich nicht an die Namenskonventionen von Borland und verwirrst dadurch die Mitleser und auch dich selbst.
Daher sollte der Code so aussehen:
Delphi-Quellcode:
private
  FDrawOwn : Boolean;
  procedure SetDrawOwn(const Value:Boolean);
public
 property DrawOwn: Boolean read FDrawOwn write SetDrawOwn;
So erkennt man leichter was zusammengehört (weil "DrawOwn" konsistent verwendet wird).

Wenn auf das Property DrawOwn niegends schreibend zugegriffen wird, dann optimiert der Kompiler die Procedure SetDrawOwn einfach weg.
Man erkennt es daran, dass die blauen Punkte nach dem Kompilieren fehlen.

ich komme von C++ da ist gewoehnlich membervariable mit einem m voranzustellen.

ich weiss nicht was F bei klassevariable bei delphi bedeutet, kann mir jemand bitte aufklaeren wofuer das steht?

Luckie 5. Sep 2010 17:05

AW: procedure wird nicht aufgerufen
 
"F" steht wohl für das englische Wort field, zu deutsch Feld. Als Felder, Eigenschaften oder Attribute bezeichnet man in der OOP private Variablen einer Klasse.

JnZn558 5. Sep 2010 17:59

AW: procedure wird nicht aufgerufen
 
was ist falsch an meinem code, das SetTab nicht aufgerufen wird

OldGrumpy 5. Sep 2010 20:00

AW: procedure wird nicht aufgerufen
 
Dein bisher gezeigter Code enthält keinerlei Aufrufe von TTest.SetTab, daher ist die Antwort einfach: Weils nicht aufgerufen wird ;) Innerhalb von TTest greifst du direkt auf m_tab zu ohne den Setter zu benutzen und von außen wird es im gezeigten Code auch nirgends angesprochen. Warum also sollte TTest.SetTab überhaupt aufgerufen werden?

JnZn558 5. Sep 2010 21:19

AW: procedure wird nicht aufgerufen
 
Zitat:

Zitat von OldGrumpy (Beitrag 1047673)
Dein bisher gezeigter Code enthält keinerlei Aufrufe von TTest.SetTab, daher ist die Antwort einfach: Weils nicht aufgerufen wird ;) Innerhalb von TTest greifst du direkt auf m_tab zu ohne den Setter zu benutzen und von außen wird es im gezeigten Code auch nirgends angesprochen. Warum also sollte TTest.SetTab überhaupt aufgerufen werden?

irgendwie kappiere ich deine antwort nicht, ich hab doch ein setter funktion "SetTab", das hast du doch auch erwaehnt, und von aussen, is vorgesehen, wenn die eigentschaft "TTest.DrawOwn" gesetzt is, sollte SetTab dadurch aufgerufen, aber es tut nicht wie geplant

Sir Rufo 5. Sep 2010 22:04

AW: procedure wird nicht aufgerufen
 
Wir sehen hier aber nicht ein Gramm Code, wo DrawOwn etwas zugewiesen wird!

Wir sehen nur die Deklaration, aber nicht wie es benutzt wird.

JnZn558 6. Sep 2010 02:50

AW: procedure wird nicht aufgerufen
 
also ich hab jez ein beispiel von delphi.about.com

ich hab zum testen code reingeschrieben, hier kann ich euch zeigen was ich gemeint hab

hier komponente quellcode
Delphi-Quellcode:
unit ExpandingComponent;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  OurCollection;

type
  TExpandingRecord = class(TPersistent)
  private
    FIntegerProp : Integer;
    FStringProp : String;
    FCollectionProp : TOurCollection;
    procedure SetCollectionProp(const Value: TOurCollection);
  public
    constructor Create(AOwner : TComponent);
    destructor Destroy; override;

    procedure Assign(Source : TPersistent); override;
  published
    property IntegerProp : Integer
      read FIntegerProp
      write FIntegerProp;
    property StringProp : String
      read FStringProp
      write FStringProp;
    property CollectionProp : TOurCollection
      read FCollectionProp
      write SetCollectionProp;
  end;

  TExpandingComponent = class(TComponent)
  private
    { Private declarations }
    FProperty1,
    FProperty2,
    FProperty3 : TExpandingRecord;
    FTest: string;
  protected
    { Protected declarations }
    procedure SetProperty1(const Value : TExpandingRecord);
    procedure SetProperty2(const Value : TExpandingRecord);
    procedure SetProperty3(const Value : TExpandingRecord);
    procedure SetTest( str: string );
  public
    { Public declarations }
    constructor Create(AOwner : TComponent); override;
    destructor Destroy; override;
  published
    { Published declarations }
    property Property1 : TExpandingRecord
      read FProperty1
      write SetProperty1;
    property Property2 : TExpandingRecord
      read FProperty2
      write SetProperty2;
    property Property3 : TExpandingRecord
      read FProperty3
      write SetProperty3;
    property testproperty: string read FTest write SetTest;
  end;

procedure Register;

implementation

procedure Register;
begin
  RegisterComponents('Samples', [TExpandingComponent]);
end;

{ TExpandingRecord }

procedure TExpandingRecord.Assign(Source: TPersistent);
begin
  if Source is TExpandingRecord then
    with TExpandingRecord(Source) do begin
      Self.IntegerProp := IntegerProp;
      Self.StringProp := StringProp;
      Self.CollectionProp := CollectionProp; //This actually assigns
    end else
      inherited; //raises an exception
end;

constructor TExpandingRecord.Create(AOwner : TComponent);
begin
  inherited Create;
  FCollectionProp := TOurCollection.Create(AOwner);
end;

destructor TExpandingRecord.Destroy;
begin
  FCollectionProp.Free;
  inherited;
end;

procedure TExpandingRecord.SetCollectionProp(const Value: TOurCollection);
begin
  FCollectionProp.Assign(Value);
end;

{ TExpandingComponent }

constructor TExpandingComponent.Create(AOwner: TComponent);
begin
  inherited;
  FProperty1 := TExpandingRecord.Create(Self);
  FProperty2 := TExpandingRecord.Create(Self);
  FProperty3 := TExpandingRecord.Create(Self);
end;

destructor TExpandingComponent.Destroy;
begin
  FProperty1.Free;
  FProperty2.Free;
  FProperty3.Free;
  inherited;
end;

procedure TExpandingComponent.SetProperty1(const Value: TExpandingRecord);
begin
  ShowMessage('Property1');
  FProperty1.Assign(Value);
end;

procedure TExpandingComponent.SetProperty2(const Value: TExpandingRecord);
begin
  ShowMessage('Property2');
  FProperty2.Assign(Value);
end;

procedure TExpandingComponent.SetProperty3(const Value: TExpandingRecord);
begin
  ShowMessage('Property3');
  FProperty3.Assign(Value);
end;

procedure TExpandingComponent.SetTest(str: string);
begin
  ShowMessage('testproperty');
  FTest := str;
end;
hier testanwendung
Delphi-Quellcode:
unit Unit1;

interface

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

type
  TForm1 = class(TForm)
    ExpandingComponent1: TExpandingComponent;
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

end.
ich aendere alle properties in objekt inspekter von der komponente in testanwendung nacheinander,

Property1 bis Property3 zeigen leider keine Meldung, also nur bei testproperty gibt es eine meldung "testproperty" aus, und breakpoint haelt auch nur bei testproperty an, property1 bis property3 ignorieren breakpoint, es macht mich voll verrueckt. is das normal? ich hoffe ihr koennt mich jez viel besser verstehen

OldGrumpy 6. Sep 2010 16:43

AW: procedure wird nicht aufgerufen
 
Ich wiederhole mich nur ungern, aber in deinem Posting ist wieder keine Zeile Code die zeigt wie auf die Properties auch zugegriffen wird. Warum lässt Du den interessanten Teil immer weg? Diesmal hast Du in Deiner "Testanwendung" ja nicht mal mehr eine Instanz der Klasse TExpandingComponent erzeugt. Es wird also nicht mehr was Du uns zeigst, sondern immer weniger. Falsche Richtung...

JnZn558 6. Sep 2010 17:54

AW: procedure wird nicht aufgerufen
 
Zitat:

Zitat von OldGrumpy (Beitrag 1047817)
Ich wiederhole mich nur ungern, aber in deinem Posting ist wieder keine Zeile Code die zeigt wie auf die Properties auch zugegriffen wird. Warum lässt Du den interessanten Teil immer weg? Diesmal hast Du in Deiner "Testanwendung" ja nicht mal mehr eine Instanz der Klasse TExpandingComponent erzeugt. Es wird also nicht mehr was Du uns zeigst, sondern immer weniger. Falsche Richtung...

ist das so schwer zu verstehen, es ist genauso wie wenn du ein button auf formular ziehst, erzeugst du selbst da ein instanz oder was?? das uebernimmt doch delphi, dafuer sind doch komponente in delphi da, um die arbeit zu erleichtern, dasselbe hab ich auch mit meiner komponente gemacht, es wird nicht zur laufzeit erzeugt, da muss man expliziert ne instanz erzeugen.

OldGrumpy 6. Sep 2010 19:16

AW: procedure wird nicht aufgerufen
 
Durch Rumgeschnauze wird Dein Posting auch nicht besser. Die Frage bleibt weiterhin warum Du keinen Code zeigst der mit deiner selbstgebauten Klasse auch arbeitet. Wenn Du da über den Objektinspektor Sachen zuweist, solltest Du noch die entsprechenden Snippets aus dem *.DFM mit einstellen, Kristallkugeln sind gerade aus. Ansonsten zeig mal endlich Code der mit den Properties auch arbeitet. Nicht die Setter hinter den Properties, sondern Code der "von außen" auf die Properties zugreift. Denn davon ist bislang trotz mehrfacher Nachfrage nix zu sehen. Sollte das zu schwer sein, kannst Du auch einfach mal dein komplettes Projekt in ein ZIP-Archiv packen und hier einstellen.

DeddyH 6. Sep 2010 19:19

AW: procedure wird nicht aufgerufen
 
Der Setter wird nur dann aufgerufen, wenn die öffentliche Property einen neuen Wert zugewiesen bekommt und nicht dann, wenn die Klasse selbst auf das dahinterliegende private Feld zugreift. Und Ersteres hat man bislang in keinem der gezeigten Codes zu sehen bekommen.

JnZn558 6. Sep 2010 22:55

AW: procedure wird nicht aufgerufen
 
ich hab es nun geschafft

Delphi-Quellcode:
unit Unit1;

interface

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

type
  TForm1 = class(TForm)
    ExpandingComponent1: TExpandingComponent;
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
    tes: TExpandingRecord;

  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
  tes := TExpandingRecord.Create( Self );
  ExpandingComponent1.Property1.StringProp := 'mach mal das was ich will';
  ExpandingComponent1.Property1 := tes; // erst bei dieser zeile springt eine meldung aus
end;
oh man, hab mich voll durchgequaelt. danke fuer alle muehe, mir tipps zugeben

OldGrumpy 6. Sep 2010 23:51

AW: procedure wird nicht aufgerufen
 
Zitat:

Zitat von JnZn558 (Beitrag 1047904)
ich hab es nun geschafft

Gratuliere!

Zitat:

Zitat von JnZn558 (Beitrag 1047904)
Delphi-Quellcode:
procedure TForm1.FormCreate(Sender: TObject);
begin
  tes := TExpandingRecord.Create( Self );
  ExpandingComponent1.Property1.StringProp := 'mach mal das was ich will';
  ExpandingComponent1.Property1 := tes; // erst bei dieser zeile springt eine meldung aus
end;

Das ist ja auch kein Wunder, der erste Zugriff ist ja nur ein Lesezugriff, da wird also nur der Getter angesprochen (der liefert dann die Instanz von TExpandingRecord zurück, von der dann der Setter von TExpandingRecord.StringProp angezogen wird, welcher in dem Fall nur direkt die zugehörige Membervariable befüllt...) Da kann ja auch keine Meldung vom Setter von TExpandingComponent.Property1 ausgegeben werden :)
Und beim zweiten Zugriff wird dann der "richtige" Setter angezogen und Deine Message ausgegeben.


Alle Zeitangaben in WEZ +1. Es ist jetzt 21:16 Uhr.

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