AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein GUI-Design mit VCL / FireMonkey / Common Controls Delphi EntwZeit - Subkomponente löschen - Exception wird ausgelöst
Thema durchsuchen
Ansicht
Themen-Optionen

EntwZeit - Subkomponente löschen - Exception wird ausgelöst

Ein Thema von christian_r · begonnen am 3. Mai 2008 · letzter Beitrag vom 4. Mai 2008
Antwort Antwort
Seite 1 von 2  1 2      
christian_r
(Gast)

n/a Beiträge
 
#1

EntwZeit - Subkomponente löschen - Exception wird ausgelöst

  Alt 3. Mai 2008, 11:20
Ich weiß gar nicht, ob ich in diesem Forum trotz Anmeldung schon einen Beitrag geschrieben hatte, deshalb noch mal Hallo an das Forum.


Ich setzte mich gerade das erste Mal mit der Entwicklung eigener Komponenten auseinander. Die Grundlage und Installation einer neuen Komponente läuft fehlerfrei. Nun bin ich dabei, Eigenschaften für Subkomponenten zu implementieren. Diese sind derzeit existierende native Komponenten von D7, z. B. eine ComboBox.

Relevanter Code ...
Delphi-Quellcode:
unit DkComponent;

interface

uses
  Classes, StdCtrls;

type
  TDkComponent = class( TComponent )
   private
    FComboBox : TComboBox;
   published
    property ComboBox
              : TComboBox
              read FComboBox
              write FComboBox;
  end;

procedure Register
          ( );

implementation

procedure Register
          ( );
begin
  RegisterComponents( 'Test Components', [ TDkComponent ] );
end;

end.
Nun habe ich folgendes Problem: Wenn ich eine ComboBox in meine Anwendung ziehe und diese meiner Komponente zuweise, dann kann ich die ComboBox nicht löschen, ohne diese in meiner Komponente vorher abzuwählen. Bleibt die ComboBox in meiner Komponente zugewiesen und ich lösche sie, wird eine Exception ausgelöst. Anschließend kann ich nicht mehr auf meine Komponente zugreifen, da weiterhin eine Exception ausgelöst wird.

Ich habe mir die Quellen von TForm und deren Vorfahrenreihe angesehen, um herauszufinden, wie es dort mit dem Popup gelöst wurde. Aber da ist nix dabei, was mir helfen könnte. Ich finde keine Codes, die das Löschen direkt überprüfen, oder ähnliches.
  Mit Zitat antworten Zitat
mkinzler
(Moderator)

Registriert seit: 9. Dez 2005
Ort: Heilbronn
39.851 Beiträge
 
Delphi 11 Alexandria
 
#2

Re: EntwZeit - Subkomponente löschen - Exception wird ausgel

  Alt 3. Mai 2008, 11:26
Wie weist du zu?
Markus Kinzler
  Mit Zitat antworten Zitat
christian_r
(Gast)

n/a Beiträge
 
#3

Re: EntwZeit - Subkomponente löschen - Exception wird ausgel

  Alt 3. Mai 2008, 11:29
Ich habe beide Komponenten, meine eigene und die ComboBox, auf das Formular gezogen und weise die ComboBox meiner Komponente im Objekt-Inspektor zu.

Edit: Normal per DropDown der Eigenschaft ComboBox im Obj.-Inspektor.

Edit 2: Ich habe den Quellcode im ersten Thread erweitert. Hatte die Registrierung der Komponente vorerst weggelassen.
  Mit Zitat antworten Zitat
christian_r
(Gast)

n/a Beiträge
 
#4

Re: EntwZeit - Subkomponente löschen - Exception wird ausgel

  Alt 3. Mai 2008, 12:14
Hier nochmal die Exception, wenn ich die ComboBox lösche:

Zitat:
Access violation at address 40005989 in module 'rtl70.bpl'. Read of address 0000001B."
Ich habe jetzt versuchsweise eine Methode SetComboBox( ) implementiert, mit der ich die ComboBox mittels "write" zuweise und die ComboBox als SubComponent deklariert.

Delphi-Quellcode:
type
  TDkComponent = class( TComponent )
   private
    FComboBox : TComboBox;
   protected
    procedure SetComboBox
              ( pValue : TComboBox );
              virtual;
   published
    property ComboBox
              : TComboBox
              read FComboBox
              write SetComboBox;
  end;

implementation

procedure TDkComponent.SetComboBox
          ( pValue : TComboBox );
begin
  Self.FComboBox := pValue;
  Self.FComboBox.SetSubComponent( True );
end;
Das war auch ein Fehlversuch. Resultat ist, dass er weiterhin die Exception beim Löschen auslöst. Nun kommt dazu, dass er beim Start der Applikation einen "EReadError" auslöst.

Zitat:
"Debugger Exception Notification"
Project Project1.exe raised exception class EReadError with message 'Invalid property path'. Process stopped. Use Step or Run to continue.
Ich verstehe das Konzept von SetSubComponent( ) nicht. Wann muss ich diese Methode verwenden?
  Mit Zitat antworten Zitat
Apollonius

Registriert seit: 16. Apr 2007
2.325 Beiträge
 
Turbo Delphi für Win32
 
#5

Re: EntwZeit - Subkomponente löschen - Exception wird ausgel

  Alt 3. Mai 2008, 12:19
Du brauchst keinen Setter, musst aber die Methode Notification überschreiben und beim Löschen der Combobox dein Feld auf nil setzen.
Wer erweist der Welt einen Dienst und findet ein gutes Synonym für "Pointer"?
"An interface pointer is a pointer to a pointer. This pointer points to an array of pointers, each of which points to an interface function."
  Mit Zitat antworten Zitat
christian_r
(Gast)

n/a Beiträge
 
#6

Re: EntwZeit - Subkomponente löschen - Exception wird ausgel

  Alt 3. Mai 2008, 12:52
Danke Philip für den Tip.

Zum besseren Verständnis schaue ich mir erst mal die geerbte Methode von TComponent an, damit ich weiß, was ich da überhaupt mache. So tief bin ich bisher nie in die Delphi-OO-Materie eingestiegen.

Delphi-Quellcode:
procedure TComponent.Notification(AComponent: TComponent;
  Operation: TOperation);
var
  I: Integer;
begin
  if (Operation = opRemove) and (AComponent <> nil) then
    RemoveFreeNotification(AComponent);
  if FComponents <> nil then
  begin
    I := FComponents.Count - 1;
    while I >= 0 do
    begin
      TComponent(FComponents[I]).Notification(AComponent, Operation);
      Dec(I);
      if I >= FComponents.Count then
        I := FComponents.Count - 1;
    end;
  end;
end;
Wenn ich die ComboBox meiner Komponente zuweise, dann wird doch aber nicht wirklich der Owner der ComboBox neu zugewiesen? Dieser wurde ja bereits beim Drop auf das Formular zugewiesen. Das würde bedeuten, dass TDkComponent.Components nicht verändert wird.

Wenn ich "Notification" richtig deute, bezieht es sich doch aber auf das Löschen einer Komponente aus der Eigenschaft "Components". Wird diese nicht nur für Komponenten verwendet, deren Eigenschaft Owner auf eben jenes TComponent-Objekt referenziert?

Außerdem verstehe ich nicht ganz, warum Components in Notification komplett rekursiv freigegeben wird.

Entschuldigt bitte, wenn ich jetzt hier im Forum im Grundwissen rumstocher.

Möglich, das ich Dinge falsch verstehe.
  Mit Zitat antworten Zitat
Apollonius

Registriert seit: 16. Apr 2007
2.325 Beiträge
 
Turbo Delphi für Win32
 
#7

Re: EntwZeit - Subkomponente löschen - Exception wird ausgel

  Alt 3. Mai 2008, 13:18
Notification wird immer dann aufgerufen, wenn der Owner deiner Komponente (bei zur Design-Zeit erstellten Komponenten ist dies das Formular) eine neue Unterkomponente erhält oder eine Unterkomponente zerstört wird. Operation ist dabei entweder opInsert oder opRemove und AComponent die Komponente.
In deiner überschriebenen Notification-Methode musst du also prüfen, ob AComponent deine Combobox und Operation opRemove ist, wenn ja, musst du dein Feld auf nil setzen. Schau dir dazu auch mal TControl.Notification an.

Zitat:
Außerdem verstehe ich nicht ganz, warum Components in Notification komplett rekursiv freigegeben wird.
Der Notification-Aufruf wird nur an die Unterkomponenten weitergegeben. Da wird nichts freigegeben.
Wer erweist der Welt einen Dienst und findet ein gutes Synonym für "Pointer"?
"An interface pointer is a pointer to a pointer. This pointer points to an array of pointers, each of which points to an interface function."
  Mit Zitat antworten Zitat
christian_r
(Gast)

n/a Beiträge
 
#8

Re: EntwZeit - Subkomponente löschen - Exception wird ausgel

  Alt 3. Mai 2008, 13:41
Delphi-Quellcode:
unit DkComponent;

interface

uses
  Classes, StdCtrls;

type
  TDkComponent = class( TComponent )
   private
    FComboBox : TComboBox;
   protected
    procedure Notification
              ( pComponent : TComponent; pOperation : TOperation );
              reintroduce;
              virtual;
   published
    property ComboBox
              : TComboBox
              read FComboBox
              write FComboBox;
  end;

procedure Register;

implementation

procedure Register;
begin
  RegisterComponents( 'Test', [ TDkMailAccount ] );
end;

{ TDkComponent }
procedure TDkComponent.Notification
          ( pComponent : TComponent; pOperation : TOperation );
begin
  inherited Notification( pComponent, pOperation );
  if ( pOperation = opRemove )
     and ( FComboBox <> nil )
     and ( pComponent = Self.ComboBox ) then
    Self.ComboBox := nil;
end;

end.
Jetzt funktioniert das Löschen ohne Exception. Und die geebrte "Notifcation" werde ich mir noch mal ganz in Ruhe ansehen. Man kann ja nur daraus lernen.

Wirklich vielen Dank für die Unterstützung.
  Mit Zitat antworten Zitat
Apollonius

Registriert seit: 16. Apr 2007
2.325 Beiträge
 
Turbo Delphi für Win32
 
#9

Re: EntwZeit - Subkomponente löschen - Exception wird ausgel

  Alt 3. Mai 2008, 13:55
Das dürfte eigentlich nicht funktionieren. Du solltest statt reintroduce override verwenden.

Außerdem kannst du deine If-Abfrage etwas vereinfachen.

Gewöhnlich verwendet man für die Eigenschaft den Custom*-Typ. Dadurch wird gewährleistet, dass auch weiterentwickelte Comboboxen benutzt werden können.
Wer erweist der Welt einen Dienst und findet ein gutes Synonym für "Pointer"?
"An interface pointer is a pointer to a pointer. This pointer points to an array of pointers, each of which points to an interface function."
  Mit Zitat antworten Zitat
christian_r
(Gast)

n/a Beiträge
 
#10

Re: EntwZeit - Subkomponente löschen - Exception wird ausgel

  Alt 3. Mai 2008, 14:40
Die hier gepostete Klasse ist nur eine Beispielklasse.

Variante 1 der Doku. Viele meiner Methoden erhalten veränderte Parameterzuweisungen, dann funktioniert "override" nicht mehr. Muss ja identisch sein.

Variante 2 der Doku. Ich könnte die Methode umbenennen. Aber das will ich ja nicht, ich will die geerbte ja überschreiben.

Variante 3 der Doku. Mir bleibt also nur "reintroduce" um zumindest die Warnung zu verstecken. Allerdings weiß ich nicht, ob ich die überschriebene Methode auch als "virtual" deklarieren muss, oder ob das grundsätzlich von Elternklassen mit vererbt wird.

Ansonsten war die ComboBox nur ein Versuchsobjekt. Im Ernstfall hätte ich die Custom* verwendet.

Edit: Wegen der If-Abfrage denk ich erstmal selber nach. Ist eine rein logische Geschicht.
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


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 11:29 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