Delphi-PRAXiS
Seite 1 von 2  1 2      

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 property setzen bzw. ändern (https://www.delphipraxis.net/20616-property-setzen-bzw-aendern.html)

cBoB 20. Apr 2004 15:28


property setzen bzw. ändern
 
Hallochen, ich wieder!

Neues Problem:

Unit2:

Delphi-Quellcode:
unit devices;
interface
uses kl2700,Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  Menus, ComCtrls, StdCtrls, ExtCtrls;

type
  TDevice1 = class(TForm)
    FPSheet: TTabSheet;
    procedure SetPSheet(var tst: TTabSheet);
  private
  public
    property PSheet: TTabSheet read FPSheet write SetPSheet;
  end;

implementation
var Dev1 : TDevice1;

procedure TDevice1.SetPSheet(var tst: TTabSheet);
begin
Dev1.FPSheet:=tst;   //hier ist dann vorbei - er wirft ne Fehlermeldung (Exception)
end;
Und dazu aus Unit1, die von Unit2 die probperty PSheet ändern können soll:

Delphi-Quellcode:
var
  Form1: TForm1;
  Dev1: TDevice1;

procedure TForm1.cr_tabs;
const
  TabTitles: array[0..4] of ShortString =
    ('Gerät1','Gerät2','Gerät3','Gerät4','Gerät5');
var
  i: integer;
begin
  for i := 0 to (devcount-1) do
    with TTabSheet.Create(Self) do
    begin
      PageControl := Form1.PageControl1;
      Dev1.PSheet:=PageControl1.Pages[i];      //hier erfolgt der zugriff

      PageControl1.Pages[0].Show;
   end;
end;
Nun stürtzt das Programm aber immer ab, wenn ich auf PSheet zugreifen will. Durch den Einzelschrittbetrieb kann ich sehen, daß es erst bei der direkten Zuweisung anhält.
Was kann falsch sein?
-c-

maximov 20. Apr 2004 15:32

Re: property setzen bzw. ändern
 
Hi.

Du missbrauchst properties, die zum kapseln von lokalen objekt-feldern da sind, und nicht um an globalen rum zu manipulieren :wink:

Teste es mal so:
Delphi-Quellcode:
procedure TDevice1.SetPSheet(var tst: TTabSheet);
begin
  self.FPSheet:=tst;   //hier ist dann vorbei - er wirft ne Fehlermeldung (Exception)
end;

Muetze1 20. Apr 2004 15:38

Re: property setzen bzw. ändern
 
Moin!

Das Self braucht nicht geschrieben werden in diesem Falle, ansonsten sind noch 2 Dinge auffällig:

1. Du hast in deinem Code in jeder der beiden Units die Variabel Dev1 : TDevice1 definiert - aber nun ist die Frage, wird überhaupt eine - und wenn, welche - mit einer Instanz von TDevice1 gefüllt?

2. Dein FPSheet ist schon Public definiert, somit frei von aussen zugreifbar - also, wozu die Properties? (siehe maximov).

MfG
Muetze1

cBoB 20. Apr 2004 16:28

Re: property setzen bzw. ändern
 
Momomomoment - nicht ganz so hastig! Wie gesagt, ich bin noch nicht lange dabei, Delphi zu programmieren. So die Standardsachen wie einfache Dateioperationen oder Statische Formulare usw. benötigen ja nicht so das Hintergrundwissen - die funktionieren halt einfach, wenn man sich da was zusammenklickt. Aber wenns dann um dynamische oder gar eben selbst erstellete Objekte geht, dann wirds schon schlimm - aber irgendwie muß man ja mal anfangen und daran kommen, nich?

So, und nun wieder zurück zum Thema!
Wie meinste das genau mit instanziieren? Meinst Du, es müßte eine Instanz mittels Dev1.Create erzeugt werden? Nein, das kommt in beiden Units nicht vor. Bis jetzt kam ich aber an die anderen (hier zwar nicht zu sehen) Methoden heran, die noch damit verbunden sind. Und daß in beiden Units Dev1 defieniert wurde, dürfte doch auch nicht stören, da diese doch eigentlich nur für eine Unit als global zu sehen sind, oder?
Und zum 2. Punkt: Ich wollte FPSheet ja auch schon direkt ansprechen, aber war das Programm auch der Meinung, daß das eine Zugriffsverletzung sei...
Also weitersuchen und MEHR INPUT :shock:

-c-


PS: Wer kann ne gut Buchempfehlung aussprechen?! Aber nicht unbedingt so ein Buch, dass erst erklärt, was der Unterschied zwischen nem Interpreter und nem Kompiler ist. :stupid:

Muetze1 20. Apr 2004 21:05

Re: property setzen bzw. ändern
 
Moin!

Du hast in beiden Units

Code:
Var
  Dev1 : TDevice1;
stehen. Dieses beides enthält nur einen Platzhalter wo du nachher eine Instanz von TDevice1 reinlegen kannst. Standardmässig gibt es sowas aber nicht in den Variablen, daher bekommst du bei dem Zugriff auf Dev1.xxx auch Probleme - da ist noch nix. Um da aber was reinzubekommen gibt es die Möglichkeit das Objekt anzulegen (instanziieren), und ja, es geht so wie du meintest (fast)

Code:
  Dev1 := TDevice1.Create();
Die Frage ist dabei nur noch, welche Parameter du beim Create mit angeben musst, und in welchem Dev1 du das abspeicherst. Dadurch das du es in beiden Units deklaraiert hast, kann es leicht zu Verwechselungen kommen so dass du auf die falsche Variable zugreifst. Und du greifst ja auf Dev1 in deinem Code zu - und wenn da noch keine Instanz drinne ist in Dev1, dann kommt es zu der Zugriffsverletzung.

Ich bin noch nicht so lange hier (ein paar Tage), daher die Frage an die anderen: gibt es hier ein Tutorial für OOP ?

MfG
Muetze1

cBoB 21. Apr 2004 07:36

Re: property setzen bzw. ändern
 
Morgen Muetze!
Prinzipiell ist mir das mit OOP schon klar, schwer ist es eben, durch die ganzen Konventionen durchzublicken. Die Idee mit dem Tut und dann eben schön auf Delphi bezogen ist nicht schlecht, aber ich glaub, ich hab hier davon schon was gesehen. Aber bin auch noch nicht länger als Du dabei.

Nochmal zurück zum Thema: warum kann ich aber dann trotzdem auf die Methoden aus TDevice1 zurückgreifen, auch wenns noch nicht instanziiert ist?

-c-

oki 21. Apr 2004 09:00

Re: property setzen bzw. ändern
 
Hi CBOB,

schau mal in deinen Project-Code. Offensichtlich hast du dein Formular aus Unit2 deinem Projekt hinzugefügt. Somit wird automatisch schon eine Instanz beim Prog-Start erzeugt. Nun kann ich natürlich nicht sagen, was du an dem vorliegenden Code alles geändert hast.

Die übliche Vorgehensweise ist aber so:

1. Du fügst ein neues Formular in dein Projekt ein, und Delphi erzeugt automatisch den Aufruf
Delphi-Quellcode:
  Application.CreateForm(TForm1, Device1);
Somit besteht eine Instanze die genutzt werden kann. Üblicheweise erzeugt Delphi auch automatisch die Instanz-Variable im implementation-Teil deiner Formular-Unit (hier Unit2)

2. Du machst das lieber alles alleine:

hier wähle ich folgende Verfahrensweise. Zum Bsp. im Main-Form creiere ich das Formular im OnCreate Ereignes meines MainForm. Das dann, wenn es für die ganze Laufzeit erhalten bleiben soll. Dann muß aber beachtet werden, dass bei Aufrufen aus anderen Units die Instanz global verfügbar sein muß. Das hat oben Delphi aber automatisch für mich gemacht. Sinn bringt das eigentlich nur, für spezielle Nutzungen, bei denen Du das entsprechende Formular oder Objekt in einer Instanz unbedingt privat kapseln möchtest.

Nun gut, was machst du im eigentlichen Object:

Hier solltest du eigentlich nie globale Bezüge verwenden, da damit dein Object unflexibel wird. Es ist immer an speziell erstellte instanzen gebunden etc.

In deinem eigenen Object kannst du der Einfachheit halber immer direkt auf eigene Eigenschaften und Methoden ohne Instanzangabe zugreifen. Der Parameter self wird sozusagen implizit unterstellt.

Bsp.:
Delphi-Quellcode:
procedure TDevice1.SetPSheet(var tst: TTabSheet);
begin
  FPSheet:=tst;  
end;


// entspricht:
procedure TDevice1.SetPSheet(var tst: TTabSheet);
begin
  self.FPSheet:=tst;  
end;
Deine Unit 2 sollte in der eigenen Erstellung eigentlich so aussehen:

Delphi-Quellcode:
unit devices;
interface
uses kl2700,Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  Menus, ComCtrls, StdCtrls, ExtCtrls;

type
  TDevice1 = class(TForm)
  private
    FPSheet: TTabSheet;
    procedure SetPSheet(var tst: TTabSheet);
  public
    property PSheet: TTabSheet read FPSheet write SetPSheet;
  end;

var Dev1 : TDevice1;

implementation

procedure TDevice1.SetPSheet(var tst: TTabSheet);
begin
  FPSheet:=tst;   //hier ist dann vorbei - er wirft ne Fehlermeldung (Exception)
end;
Passiert das alles nicht per Drag and Drop im Fomular kümmerst Du dich selber um das Creieren Deiner Objekte.

Machst du es per Drag and Drop, sind diese Public und ein Property tut wirklich nicht not.

Gut, ich hoffe es war verständlich,

Gruß oki

maximov 21. Apr 2004 09:08

Re: property setzen bzw. ändern
 
Zitat:

Zitat von cBoB
...

Nochmal zurück zum Thema: warum kann ich aber dann trotzdem auf die Methoden aus TDevice1 zurückgreifen, auch wenns noch nicht instanziiert ist?

Du kannst (zur laufzeit) nur solange auf methoden, von objekten die noch nicht instanziert sind (nil), zugreiffen, wie dort nicht mit den objekt-daten gearbeitet wird! Denn dann wird faktisch nicht auf den objekt-speicher zugegriffen, nur auf den code der klasse.

Und (besser man sagt es dir früher als spät) man sollte soweit wie möglich auf globale variablen verzichten, weil das schlechten stil fördert.

oki 21. Apr 2004 09:14

Re: property setzen bzw. ändern
 
[quote="maximov"]
Zitat:

Zitat von cBoB
...

Und (besser man sagt es dir früher als spät) man sollte soweit wie möglich auf globale variablen verzichten, weil das schlechten stil fördert.

dem schließe ich mich uneingeschränkt an!

Gruß oki

cBoB 21. Apr 2004 09:19

Re: property setzen bzw. ändern
 
@oki
Danke für die Ausführlichkeit! Hab das aber schon so irgendwie hingebogen bekommen - quasi übernacht :wink: .

@max
Aha, hab mir sowas in der Art schon gedacht. Was meinst Du hier aber genau mit Objectdaten?
Und daß Globale Variablen vermieden werden sollten, war mir auch schon klar. Ich bemüh mich jedenfalls, wenig davon gebrauch zu machen. In einigen wenigen Fällen kommt man aber drum rum.

Was ist eigentlich mit ner Buchempfehlung zum Thema? Woher habt Ihr Eure Erfahrung bzw. Wissen - zugeflogen kommt sowas bis jetzt ja noch nicht, oder? :angle:

-c-


Alle Zeitangaben in WEZ +1. Es ist jetzt 14:48 Uhr.
Seite 1 von 2  1 2      

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