AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Sonstige Fragen zu Delphi Unterschied zwischen "Self" und Form2 (MDI-Child-Formular)?
Thema durchsuchen
Ansicht
Themen-Optionen

Unterschied zwischen "Self" und Form2 (MDI-Child-Formular)?

Ein Thema von Kalakmul · begonnen am 6. Aug 2014 · letzter Beitrag vom 7. Aug 2014
Antwort Antwort
Benutzerbild von Kalakmul
Kalakmul

Registriert seit: 11. Apr 2008
27 Beiträge
 
Delphi 2010 Professional
 
#1

Unterschied zwischen "Self" und Form2 (MDI-Child-Formular)?

  Alt 6. Aug 2014, 21:59
Ich habe ein Programm (MDI) erstellt, das außer dem Hauptformular zwei Childfenster enthält.

Von diesen soll eines (Form3 - "Auswahlfenster" genannt) beim Programmstart sofort angezeigt werden (mittels Projektoptionen - verfügbare Formulare unter "automatisch erzeugen" eingetragen). Es soll Buttons als eine Art Auswahl enthalten, von denen aus weitere Childfenster angezeigt werden können. Jedes Childfenster soll aber nur einmal angezeigt werden können.

Das zweite Childfenster ("Kindfenster" genannt) wird zur Laufzeit erzeugt und hat einen Button, mit dem es wieder geschlossen werden kann.

Das habe ich auch so hinbekommen (mit dem unten auskommentierten "Form2 := nil", bin dabei aber auf ein Verständnisproblem im FormClose-Ereignis des "Kindfensters" gestoßen:

Delphi-Quellcode:
procedure TForm2.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  Action := caFree;
  if Self = Form2
  then begin
// Self := nil; // klappt offenbar nicht (Child wird nach einmaligem
                 // Schließen nicht mehr angezeigt.
// TForm2(Sender) := nil;
// Form2 := nil; // sonst öffnet sich das das Fenster nur beim ersten Mal
                   // Offenbar ist "self" nicht genau dasselbe
                   // an dieser Stelle wie "Form2".
    TForm(Self) := nil; // auch so geht es nicht
  end;
end;
So wie der Quelltext oben angegeben ist, lässt sich das Kindfenster einmal schließen und wird beim erneuten Versuch, es zu öffnen, nicht mehr angezeigt.

Der aufrufende Quellcode zur Anzeige des Kindfensters lautet:

Delphi-Quellcode:
procedure TForm3.btnZeigeChildClick(Sender: TObject);
begin
  if Form2 = nil then // soll verhindern, dass das Child 2mal angezeigt wird
  begin
    Application.CreateForm(TForm2, Form2);
  end;
end;
Was ich nun nicht verstehe ist, warum nur das explizite Setzen von Form2 auf nil wie gewünscht funktioniert, selbst wenn ich Self auf TForm2 caste und vorher auf "Self = Form2" getestet habe. Kann mir hierzu jemand eine Erklärung geben?

Im Anhang habe ich das Beispielprojekt angehängt. Ich benutze Delphi 2010 und habe es damit kompiliert.
Angehängte Dateien
Dateityp: zip MDI-Fenster mit Self schließen.zip (405,5 KB, 1x aufgerufen)
Wer fragt, ist ein Narr für 5 Minuten, wer nicht fragt, ist ein Narr ein Leben lang.
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.063 Beiträge
 
Delphi 12 Athens
 
#2

AW: Unterschied zwischen "Self" und Form2 (MDI-Child-Formular)?

  Alt 6. Aug 2014, 22:26
Self ist ein "unsichtbarer" Parameter in allen Klassen-Methoden.
Nur bei class procedure/function ist der Self-Parameter nicht die Instanz, sondern der Klassentyp.
Und statische Klassenmethoden (class procedure name(); static; ) haben garkein Self, womit sie praktisch genauso wie "normale" Prozeduren sind.


Delphi-Quellcode:
procedure TForm2.FormClose(Self: TForm2; Sender: TObject; var Action: TCloseAction);
begin
  Action := caFree;
  ...
end;
Und nun überleg mal, warum es nichts bringt diesem Parameter etwas zuzuweisen (kein (var Self: TForm2; ... ).

Die Form selber weiß von der externen Variable Form2 überhaupt nichts.
Und sie weiß auch nicht, ob es sonstwo noch Variablen gibt. Und es wird auch nirgendwo verwaltet ob und welche Variablen es irgendwo gibt, in denen eventuell eine Instanz dieser Klasse drin abgelegt ist.
Neuste Erkenntnis:
Seit Pos einen dritten Parameter hat,
wird PoSex im Delphi viel seltener praktiziert.

Geändert von himitsu ( 6. Aug 2014 um 22:29 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#3

AW: Unterschied zwischen "Self" und Form2 (MDI-Child-Formular)?

  Alt 6. Aug 2014, 22:32
Zum Thema Self :
http://docwiki.embarcadero.com/RADSt.../Methoden#Self
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#4

AW: Unterschied zwischen "Self" und Form2 (MDI-Child-Formular)?

  Alt 6. Aug 2014, 22:35
... in denen eventuell eine Instanz dieser Klasse drin abgelegt ist.
In den Variablen ist niemals eine Instanz abgelegt, sondern eine Referenz (Pointer) auf den Speicherbereich der Instanz.
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat
Volker Z.

Registriert seit: 4. Dez 2012
Ort: Augsburg, Bayern, Süddeutschland
419 Beiträge
 
Delphi XE4 Ultimate
 
#5

AW: Unterschied zwischen "Self" und Form2 (MDI-Child-Formular)?

  Alt 7. Aug 2014, 00:44
Hallo,

naja, dass Self nichts mit der Variable zu tun hat wurde ja schon erklärt.

Zitat:
Es soll Buttons als eine Art Auswahl enthalten, von denen aus weitere Childfenster angezeigt werden können. Jedes Childfenster soll aber nur einmal angezeigt werden können.
Das könntest Du vielleicht so hinbiegen (pack folgendes in eine eigene Unit [im Folgenden mal sap.pas]):
Delphi-Quellcode:
function CreateForm (const FormClass : TCustomFormClass) : TCustomForm;
begin
  Result := FormClass.Create (Application.MainForm)
end;

function FindComponentByClass (const Component : TComponent; const ComponentClass : TComponentClass) : TComponent;
var
  i : Integer;
  c : TComponent;
begin
  Result := nil;
  for i := 0 to Component.ComponentCount - 1 do
    begin
      c := Component.Components [i];
      if c is ComponentClass then
        begin
          Result := c;
          Break
        end
    end
end;

procedure ShowMDIForm (const FormClass : TCustomFormClass);
var
  c : TComponent;
  f : TCustomForm;
begin
  c := FindComponentByClass (Application.MainForm, FormClass);
  if Assigned (c) then
    f := TForm (c)
  else
    begin
      f := CreateForm (FormClass);
      if not Assigned (f) then
        // Do whatever you want if it fails
    end;

  if f.WindowState = wsMinimized then
    f.WindowState := wsNormal
  else
    f.BringToFront
end;
In den Formularen dann jeweils ein:
Delphi-Quellcode:
procedure TFormX.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  Action := caFree
end;
Und an den Stellen an denen ein weiteres MDIChild angezeigt werden soo
Delphi-Quellcode:
uses
  sap.pas;

procedure TFormY.ButtonClick(Sender: TObject);
begin
  ShowMDIForm (TFormX)
end;
Gruß
Volker Zeller
  Mit Zitat antworten Zitat
Benutzerbild von Kalakmul
Kalakmul

Registriert seit: 11. Apr 2008
27 Beiträge
 
Delphi 2010 Professional
 
#6

AW: Unterschied zwischen "Self" und Form2 (MDI-Child-Formular)?

  Alt 7. Aug 2014, 17:20
Dank an alle für die Antworten.

@himitsu (kein "var" in der Deklaration)
Was mir noch nicht ganz klar ist:

Delphi-Quellcode:
unit Unit1;

interface

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

type
  TForm1 = class(TForm)
    btn1: TButton;
    procedure btn1Click(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.btn1Click(Sender: TObject);
begin
  (Sender as TButton).Caption := 'Änderung';
end;

end.
In diesem kleinen Programm wird "Sender" benutzt, um die Aufschrift von Button "btn1" zu ändern. In der Deklaration steht auch kein "var" bei Sender dennoch wird die Aufschrift verändert. Vermutlich liegt dies daran, dass die Visibility der verschiedenen Objekte nicht gleich ist. Soweit ich es jetzt verstanden habe, kann also in meinem Beispiel im Beitrag #1 das Formular sich selbst (self) nicht sehen wohl aber seine Member (wie also in diesem Beispiel oben "btn1") - schon etwas eigenartig.

Und wenn self auch nicht exakt Form2 ist (in #1) so bezieht es sich doch letztlich auf Form2, oder ich habe den Eintrag in der Wiki aus Sir Rufos Beitrag noch nicht verstanden:
Zitat:
Der Bezeichner Self verweist in der Implementierung einer Methode auf das Objekt, in dem die Methode aufgerufen wird.
Wer fragt, ist ein Narr für 5 Minuten, wer nicht fragt, ist ein Narr ein Leben lang.

Geändert von Kalakmul ( 7. Aug 2014 um 17:29 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.063 Beiträge
 
Delphi 12 Athens
 
#7

AW: Unterschied zwischen "Self" und Form2 (MDI-Child-Formular)?

  Alt 7. Aug 2014, 17:54
Da wird ja auch nicht die Referenz verändert, sondern etwas, auf das die Referenz verlinkt.

Du wolltest aber die Referenz (den Inhalt der Variable und nicht Etwas in dem, worauf die Referenz in der Variable zeigt) ändern.

Der Vergleich wäre also
Delphi-Quellcode:
procedure TForm1.btn1Click(Sender: TObject);
begin
  Sender := nil; // oder Sender := btn2;
end;
Neuste Erkenntnis:
Seit Pos einen dritten Parameter hat,
wird PoSex im Delphi viel seltener praktiziert.
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 02:54 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