AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Nicht erkärliche EAccessVoilation

Ein Thema von I.A · begonnen am 25. Feb 2009 · letzter Beitrag vom 27. Feb 2009
Antwort Antwort
Seite 1 von 2  1 2      
I.A

Registriert seit: 14. Jan 2007
83 Beiträge
 
#1

Nicht erkärliche EAccessVoilation

  Alt 25. Feb 2009, 13:48
Hallo,

Gestern habe ich sowohl meine eigenen Datensatzmaske als auch die eines DP Users, welche er mir freundlicherweise zur Verfügung gestellt hat, getesetet.

Dabei erhalte ich eine EAccessviolation, wobei das Programm an der im Kommentar beschribenen Stelle anhält. Die Eigenschaft TWinControl.Parent existiert aber definitiv laut Delphi Hilfe.

Wenn ich deshalb debugge, um die Ursache für die Exception zu finden, erhalte ich diese an jener Stelle, wo die Eigenschaft DataSoruce zugewiesen wird. In der Methode SetDataSource, wie im Listing unten zu sehen.

Daraufhin habe ich meine eigenen Version der Datensatzmaske getestet und erhalte ebenfalls eine EAccessViolation an jener Stelle, wo

Delphi-Quellcode:
function TCR_DB_Editor.GetRealParent : TWinControl;
var MYDBCtrlGrid : TMYDBCtrlGrid;
     tmp :TWinControl;
     Flag : boolean;
begin
     Flag := false;
     tmp := self.Parent;
     result := tmp;
     //showmessage(result.Name);
     while ( tmp.Parent <> nil ) AND (Flag =false) do //Hier hält das Programm an und wirft die
     begin //Exception aus
         if Pos('dbctrl', lowercase(tmp.ClassName )) > 0 then
         begin
             MYDBCtrlGrid := TMYDBCtrlGrid(tmp);
             result := MYDBCtrlGrid.Panel;
             Flag := true;
         end;
         tmp := tmp.Parent;
     end;
end;

procedure TCR_DB_Editor.SeTDataSource(Value: TDataSource);
begin
   if value <> nil then
   begin
      FDataLink.DataSource := Value; //Hier hält der Debugger an und wirft die Exception aus
   end;
end;

// Hier mein eigener Entwurf:

procedure TDBInputMask.SetDataSource(ADataSource: TDataSource);
var
  idx: Integer;
  obj: TObject;
  edit: TDBInputLine;
  chbox: TDBCheckBox;
  cobox: TDBComboBox;
  clbox: TDBLookUpComboBox;
  rdgrp: TDBRadioGroup;
  imemo: TMemo;
  irich: TRichEdit;
  image: TImage;
begin
  if FEdits.Count > 0 then FEdits.Clear;
  if (ADataSource<>nil) and (FDataSource<>ADataSource) then
  begin
    //Hier erhalte ich die Exception, aber hier EAbstractError
    FDataSource := ADataSource;
    FDataSource.DataSet.GetFieldNames(FEdits);
    FCount := FDataSource.DataSet.FieldCount;
    for idx := 0 to FCount - 1 do
    begin
      SetLabels(idx, TDBText.Create(self));
      //SetInputs(idx, TDBEdit.Create(self));
      obj := FInputs[idx];
      if obj is TDBInputLine then
      begin
        TDBInputLine(FInputs[idx]).DataSource := FDataSource;
        TDBInputLine(FInputs[idx]).DataField := FEdits[idx];
      end;
      if obj is TDBCheckBox then
      begin
        TDBCheckBox(FInputs[idx]).DataSource := FDataSource;
        TDBCheckBox(FInputs[idx]).DataField := FEdits[idx];
      end;
    end;
  end;

procedure Tdbform.OpenDataBase;
begin
  if dlgOpen.Execute then
  begin
    FFilename := dlgOpen.Filename;
    ClientDataSet.LoadFromFile(FFilename);
    ClientDataSet.Active := true;
    //CreateMask;
    FInputMask := TDBInputMask.Create(self);
    FInputMask.Top := 312;
    FInputMask.Left := 8;
    FInputMask.Width := 425;
    FInputMask.Height := 145;
    FInputMask.DataSource := DataSource;
    //Hier erhalte ich EAbstractError;
    FInputMask.Parent := self;
  end;
end;
Da nund die Exception in beiden Versionen auftritt, muss ja ein generelles Problem vorliegen. Möglicherweise ist die Methode zur Zuweisung der Datenquelle falsch. Aber wie wird ed dann richtig gemacht?

Sowohl FDataLink.DataSource als auch FDataSource sind doch letztlich nix anderes als Zeiger auf die Datenquelle. Deren Adresse hole ich von außen. Aber warum dann die Exception?

Gibt es zur Lösung des Problems ein Standardverfahren, das diese Exception vermeidet?

Bin mit meinem Latein am Ende. Warum funktioniert die Zuweisung nicht. Ich verwende für die Entwicklung Turbo Delphi Exploerer, die kostenlose Version ohne Updates.

In meiner Version erhalte ich nicht EAccessviolation, sondern EAbstractError. Deshalb noch die Definition meiner Basisklasse für meine Eingabemaske:

Delphi-Quellcode:
  TCustomInputMask = class(TScrollBox)
  private
    { Private-Deklarationen }
  protected
    { Protected-Deklarationen }
    FCount: Integer;
    FInputs: TObjectList;
    FLabels: TObjectList;
    FMasks: TStrings;
  public
    { Public-Deklarationen }
    procedure CreateLabel(ACaption: TCaption); virtual;
    procedure CreateEdit(AEditMask: String); virtual;
    procedure CreateCheckBox(ACaption: String); virtual;
    procedure CreateComboBox; virtual;
    procedure CreateMask; virtual;
    procedure CreateMemo; virtual;
    procedure CreateRadioGroup(ACaptions: TStrings); virtual;
    procedure CreateRichEdit; virtual;
  end;

//Hier noch die Definition meiner eigenen Datensatzmaske.
  TDBInputMask = class(TCustomInputMask)
  //diese Klasse für Datenbankmasken verwenden
  //Feldanzahl, damit Anzahl Edits wird durch die Datenbank bestimmt
  private
    FDataSource: TDataSource;
    FEdits: TStrings; //Feldnamen nach Anzeigereihenfolge
    function GetInputs(Index: Integer): TObject;
    function GetLabels(Index: Integer): TDBText;
    function GetMasks(Index: Integer): String;
    function GetDataSource: TDataSource;

    procedure SetCount(ACount: Integer);
    procedure SetInputs(Index: Integer; AInput: TObject);
    procedure SetLabels(Index: Integer; ALabel: TDBText);
    procedure SetMasks(Index: Integer; AMask: String);

    procedure SetDataSource(ADataSource: TDataSource);
  public
    constructor Create(AOwner: TComponent);
    procedure CreateLabel(ACaption: TCaption); override;
    procedure CreateLabelCaptions(ACaptions: TStrings);
    procedure CreateEdit(AEditMask: String); override;
    procedure CreateCheckBox(ACaption: String); override;
    procedure CreateComboBox; override;
    procedure CreateMask; override;
    procedure CreateMemo; override;
    procedure CreateRadioGroup(ACaptions: TStrings); override;
    procedure CreateRichEdit; override;
    destructor Destroy; override;

    property Count: Integer read FCount write SetCount;
    property DataSource: TDataSource read GetDataSource write SetDataSource;
    property Inputs[Index: Integer]: TObject read GetInputs write SetInputs;
    property Masks[Index: Integer]: String read GetMasks write SetMasks; default;
  end;
Die virtuellen Methoden waren vorher als virtual; abstract; deklariert. Wegen der EAbstractError Exception habe ich diese Methoden virtual; definiert und im Implementationsteil stehen leere Methodenrümpfe. Dennoch werde ich die Exception nicht los.

Weil aber bei der Einen Version die Exception, wenn auch EAccessviolation, statt EAbstractError, wie bei der Anderen Version während der Zuweisung der Datenquelle ausgelöst wird, habe ich die Frage in diesen Thread gepackt. Denn ich vermute, das die Fehlerursache irgendwo im Softwaredesign liegt. Egal, welche Exception letzlich ausgelöst wird.

Braucht Ihr, um helfen zu können noch mehr Quelltext? Dann teilt mir das bitte hier mit und ich werde die Quellen liefern. Die Datensatzmaske ist nichts sonderlich geheimes.
  Mit Zitat antworten Zitat
mkinzler
(Moderator)

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

Re: Nicht erkärliche EAccessVoilation

  Alt 25. Feb 2009, 13:50
Hat den der Parent einen Parent?
Markus Kinzler
  Mit Zitat antworten Zitat
I.A

Registriert seit: 14. Jan 2007
83 Beiträge
 
#3

Re: Nicht erkärliche EAccessVoilation

  Alt 25. Feb 2009, 14:21
Zitat von mkinzler:
Hat den der Parent einen Parent?
Davon gehe ich aus. Der Parent wäre das Formular, das die Datensatzmaske anzeigen soll.

Ist das Problem dort zu suchen oder wird zur Unterstützung bei der Fehlersuche noch Quelltext gebraucht? Ich dachte, das hier ein generelles Problem vorkliegt, weil der Fehler in beiden Versionen der Datensatzmaske auftritt. Beide Male bei der Zuweisung der Datenquelle. Der fremde Quelltext stammt von einem DP User. Leider habe ich keine Vorgaben erhalten, wie der Quelltext zu behandeln ist, bezüglich seiner Veröffentlichung. Zeigen kann ich daher nur meinen eigenen uneingeschränkt, so das zur Fehlerbehebung beiträgt.

In der Methode wird ja, wie im Quelltext zu sehen, abgefragt, ob value<>nil ist:

if value <> nil then
begin
FDataLink.DataSource := Value;
end;

Auch ich frage in meiner Version ab, ob ein Zeiger ungleich NIL übergeben wird.

if (ADataSource<>nil) and (FDataSource<>ADataSource) then
begin
FDataSource := ADataSource;

Wenn ich debugge, kommt die Exception bei der Zuweisung der Datenquelle. Im Hauptprogramm folgt nach Zuweisung der Datenquelle die Zuweisung der Eigenschaft Parent, weshalb der Cursor bei normalem Programmstart dort stehen bleibt.

Biem Debuggen im Einzelschrittbetrieb meckert das Programm bei Zuweisung der Datenquelle und das in beiden Versionen der Datensatzmaske, sowohl in der fremden als auch in meiner eigenen.
  Mit Zitat antworten Zitat
nuclearping

Registriert seit: 7. Jun 2008
708 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#4

Re: Nicht erkärliche EAccessVoilation

  Alt 25. Feb 2009, 14:32
Wenn FDataLink nil ist, krachts auch bei der Zuweisung der DataSource. Egal ob "value" nil ist. Genauso wenn Self.Parent nil ist. Dann kannst du nicht auf Self.Parent.Parent zugreifen (tmp.Parent).
  Mit Zitat antworten Zitat
I.A

Registriert seit: 14. Jan 2007
83 Beiträge
 
#5

Re: Nicht erkärliche EAccessVoilation

  Alt 25. Feb 2009, 15:32
Zitat:
Wenn FDataLink nil ist, krachts auch bei der Zuweisung der DataSource. Egal ob "value" nil ist. Genauso wenn Self.Parent nil ist. Dann kannst du nicht auf Self.Parent.Parent zugreifen (tmp.Parent).
Ähmmm, wie ist das denn dann hier:

Delphi-Quellcode:
  if (ADataSource<>nil) and (FDataSource<>ADataSource) then
  begin
    FDataSource := ADataSource;
Und der Parent wird hier zugewiesen? In meiner eigenen Version!
Delphi-Quellcode:
    FInputMask := TDBInputMask.Create(self);
    FInputMask.Top := 312;
    FInputMask.Left := 8;
    FInputMask.Width := 425;
    FInputMask.Height := 145;
    FInputMask.DataSource := DataSource;
    FInputMask.Parent := self;
Die Inputmaske ist im Grunde ein Nachkomme von TScrollBox. Ist in dieser das Feld Parent = NIL. Wie aber kommt eine Scrollbox aus der Komponentenpalette auf das Delphi Formular? Weist Delphi nicht intern auch der Eigenschaft Parent das Formular zu, auf dem sie platziert wird? Wenn ich hier falsch liege, muss ich mal ganz OT fragen, was macht denn dann Delphi mit der dfm Datei? Geschieht die entscheidende Zuweisung da wesentlich anders. Kann man das mit eigenem Quelltext auch so machen, wenn man die Komponente zur Laufzeit erzeugt? Ich dachte immer, Delphi liest die dfm-Datei und macht daraus das gleiche, was ich mache, wenn ich die Kompo zur Laufzeit erzeuge. Scheint aber Deiner knappen Auskunft nach nicht so zu sein. Biitte bitte hilf mir weiter. Ich weiß wirklich nicht, wo ich nach dem Fehler suchen soll.

Bei Honaraversprechen müsste ich allerdings vorher wissen, wieviel Geld man für die fertige Datensatzmaske als Delphi Komponente auf dem Markt verlangen könnte. Wäre eine echte Alternative, da auch ich noch immer nach einer passenden Lehrstelle suche. Da käme eine kommerzielle Vermarktbarkeit einer selber geschiebenen Delphi Komponente wie gerufen. Hast Du vielleicht ne Ahnung, welche Firmen so was brauchen könnten und was solch eine Komponente dann noch können müsste?
Dann wäre die Sache einfacher, weil ich dann einen Anreiz für Deine bzw. Eure Hilfe bieten könnte.

Wenn aber die Kompo nicht verkäuflich ist, dann bitte bitte lasst Gnade walten und sgt mir wenigstens, wie ich den Fehler eingrenzen kann.

Kann ja sein, das Parent in:

Delphi-Quellcode:
if value <> nil then
   begin
      FDataLink.DataSource := Value;
den Wert NIL hat. Aber hier:

Delphi-Quellcode:
constructor TCR_DB_Editor.Create(AOwner: TComponent);
begin
   inherited Create(AOwner); UpdatingControls := false;
   ControlStyle := ControlStyle + [csReplicatable];
   FControlList := TStringList.Create;
   FDataLink := TCR_DB_EditorLink.Create(self);
end;
wird dem FDataLink doch eine Adresse zugewiesen. Der Debugger meckert diese Stelle zumindest nicht an. Außerdem meckert der Debugger im Einzelschrittbetrieb nicht bei Parent, sondern bei FDataLink.DataSource.

[edit=mkinzler]Delphi-Tags ergänzt Mfg, mkinzler[/edit]
  Mit Zitat antworten Zitat
Benutzerbild von SirThornberry
SirThornberry
(Moderator)

Registriert seit: 23. Sep 2003
Ort: Bockwen
12.235 Beiträge
 
Delphi 2006 Professional
 
#6

Re: Nicht erkärliche EAccessVoilation

  Alt 25. Feb 2009, 15:47
Könntest du bitte die vollständige Fehlermeldung posten? (Sorry falls ich es übersehen habe)
Denn die vollständige Meldung enthält Adressen die bei der Suche nach der Ursache mehr als hilfreich sind.
Jens
Mit Source ist es wie mit Kunst - Hauptsache der Künstler versteht's
  Mit Zitat antworten Zitat
I.A

Registriert seit: 14. Jan 2007
83 Beiträge
 
#7

Re: Nicht erkärliche EAccessVoilation

  Alt 26. Feb 2009, 13:16
Hallo!

Zitat von SirThornberry:
Könntest du bitte die vollständige Fehlermeldung posten? (Sorry falls ich es übersehen habe)
Denn die vollständige Meldung enthält Adressen die bei der Suche nach der Ursache mehr als hilfreich sind.
Kann ich selbstverständlich.

Hier die Fehlermeldung:

//FInputMask := TCR_DB_Editor.Create(self);
FInputMask := TDBInputMask.Create(self);

Modul laden: ntshrui.dll. Ohne Debug-Infos. Basisadresse: $76940000. Prozess desktopdd.exe (1544)
Modul laden: ATL.DLL. Ohne Debug-Infos. Basisadresse: $76AD0000. Prozess desktopdd.exe (1544)
Modul laden: NETAPI32.dll. Ohne Debug-Infos. Basisadresse: $71BA0000. Prozess desktopdd.exe (1544)
Thread-Start: Thread-ID: 1640. Prozess desktopdd.exe (1544)
Thread-Start: Thread-ID: 1636. Prozess desktopdd.exe (1544)
Modul laden: SHDOCVW.dll. Ohne Debug-Infos. Basisadresse: $71000000. Prozess desktopdd.exe (1544)
Erste Gelegenheit für Exception bei $77E4D756. Exception-Klasse EAbstractError mit Meldung 'Abstrakter Fehler'. Prozess desktopdd.exe (1544)


Und hier die Meldungen, wenn ich die Fremdbibliothek verwende:

FInputMask := TCR_DB_Editor.Create(self);
//FInputMask := TDBInputMask.Create(self);


Modul laden: SETUPAPI.dll. Ohne Debug-Infos. Basisadresse: $76620000. Prozess desktopdd.exe (400)
Modul laden: ntshrui.dll. Ohne Debug-Infos. Basisadresse: $76940000. Prozess desktopdd.exe (400)
Modul laden: ATL.DLL. Ohne Debug-Infos. Basisadresse: $76AD0000. Prozess desktopdd.exe (400)
Modul laden: NETAPI32.dll. Ohne Debug-Infos. Basisadresse: $71BA0000. Prozess desktopdd.exe (400)
Thread-Start: Thread-ID: 404. Prozess desktopdd.exe (400)
Thread-Start: Thread-ID: 1740. Prozess desktopdd.exe (400)
Thread-Start: Thread-ID: 428. Prozess desktopdd.exe (400)
Modul laden: SHDOCVW.dll. Ohne Debug-Infos. Basisadresse: $71000000. Prozess desktopdd.exe (400)
Thread-Start: Thread-ID: 956. Prozess desktopdd.exe (400)
Erste Gelegenheit für Exception bei $77E4D756. Exception-Klasse EAccessViolation mit Meldung 'Zugriffsverletzung bei Adresse 004D1A93 in Modul 'desktopdd.exe'. Lesen von Adresse 00000030'. Prozess desktopdd.exe (400)

Die Klasse TCR_DB_Editor ist die Klasse der fremden Eingabemaske.

Die Klasse TDBInputmask ist meine eigene Eingabemaske.

Wenn ich hier:
Delphi-Quellcode:
function TCR_DB_Editor.GetRealParent : TWinControl;
var MYDBCtrlGrid : TMYDBCtrlGrid;
     tmp :TWinControl;
     Flag : boolean;
begin
     Flag := false;
     tmp := self.Parent;
     result := tmp;
     //showmessage(result.Name);
     while (tmp <> nil) AND ( tmp.Parent <> nil ) AND (Flag =false) do
     begin
         if Pos('dbctrl', lowercase(tmp.ClassName )) > 0 then
         begin ...
die zusätzliche Bedingung (tmp <> nil) einbaue, erhalte ich eine EInvalidOperation

@nuclearping
Zitat von nuclearping:
Wenn FDataLink nil ist, krachts auch bei der Zuweisung der DataSource. Egal ob "value" nil ist. Genauso wenn Self.Parent nil ist. Dann kannst du nicht auf Self.Parent.Parent zugreifen (tmp.Parent).
Er hat wohl doch Recht damit. Aber nun erhalte ich die EInvalidoperation, wenn auch an ganz anderer Stelle, die mir zunächst auch nicht einleuchten will. Fehlersuche ist doch eine Herausforderung.

Modul laden: ntshrui.dll. Ohne Debug-Infos. Basisadresse: $76940000. Prozess desktopdd.exe (1760)
Modul laden: ATL.DLL. Ohne Debug-Infos. Basisadresse: $76AD0000. Prozess desktopdd.exe (1760)
Modul laden: NETAPI32.dll. Ohne Debug-Infos. Basisadresse: $71BA0000. Prozess desktopdd.exe (1760)
Thread-Start: Thread-ID: 1640. Prozess desktopdd.exe (1760)
Thread-Start: Thread-ID: 1636. Prozess desktopdd.exe (1760)
Thread-Start: Thread-ID: 1500. Prozess desktopdd.exe (1760)
Modul laden: SHDOCVW.dll. Ohne Debug-Infos. Basisadresse: $71000000. Prozess desktopdd.exe (1760)
Thread-Start: Thread-ID: 1532. Prozess desktopdd.exe (1760)
Erste Gelegenheit für Exception bei $77E4D756. Exception-Klasse EInvalidOperation mit Meldung 'Element '' hat kein übergeordnetes Fenster'. Prozess desktopdd.exe (1760)

...und zwar hier:

if HorzScrollBar <> nil then HorzScrollbar.Position := 0; in dieser Methode:

Delphi-Quellcode:
procedure TCR_DB_Editor.ReOrderControls;
... Variablendeklaratioenen
begin

   //Initialisierungen, die nichts mit den Schrollbars zu tun haben

   //Das steht unmittelbar vor der strittigen Anweisung
   
   ww := Width div (2 * FElement_ListCols) ;
   if ww < FMinWidthHoriz then ww := FMinWidthHoriz;

   
   VertikalRowCounter := 0;

   //Hier tritt die Exception auf < EInvalidOperation
   //Wozu braucht der Scrollbar ein übergeordnetes Fenster,
   //um dessen Anfangsposition zuzuweisen?
   if HorzScrollBar <> nil then HorzScrollBar.Position := 0;
   if VertScrollBar <> nil then VertScrollBar.Position := 0;
end;
Nun werde ich noch mal meine eigene Eingabemaske auf Fehler "abklopfen".
  Mit Zitat antworten Zitat
Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#8

Re: Nicht erkärliche EAccessVoilation

  Alt 26. Feb 2009, 13:41
Also deine Variable temp ist vom Typ TWinControl. Wo wird denn das Objekt temp erstellt? Du fängts einfach so damit an zu arbeiten ohne es zu erzeugen. Oder habe ich da jetzt was übersehen?
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
Benutzerbild von DeddyH
DeddyH

Registriert seit: 17. Sep 2006
Ort: Barchfeld
27.625 Beiträge
 
Delphi 12 Athens
 
#9

Re: Nicht erkärliche EAccessVoilation

  Alt 26. Feb 2009, 13:43
Zitat:
tmp := self.Parent;
Es wäre ja nun Quatsch, den eigenen Parent erzeugen zu wollen. Bleibt die Frage: wäre es möglich, dass seine Klasse gar keinen Parent hat (wieso auch immer)?
Detlef
"Ich habe Angst vor dem Tag, an dem die Technologie unsere menschlichen Interaktionen übertrumpft. Die Welt wird eine Generation von Idioten bekommen." (Albert Einstein)
Dieser Tag ist längst gekommen
  Mit Zitat antworten Zitat
I.A

Registriert seit: 14. Jan 2007
83 Beiträge
 
#10

Re: Nicht erkärliche EAccessVoilation

  Alt 26. Feb 2009, 18:25
Hallo!

Zitat von DeddyH:
Zitat:
Delphi-Quellcode: markieren
tmp := self.Parent;

Es wäre ja nun Quatsch, den eigenen Parent erzeugen zu wollen. Bleibt die Frage: wäre es möglich, dass seine Klasse gar keinen Parent hat (wieso auch immer)?
Nein, die Eignschaft Parent existiert auf jeden Fall. Die Ableitungshirarchie ist laut Delphi Hilfe:

TWinControl
|
TControl (Hier wird die Eigenschaft Parent eingeführt)
|
TComponent

Zitat von Luckie:
Also deine Variable temp ist vom Typ TWinControl. Wo wird denn das Objekt temp erstellt? Du fängts einfach so damit an zu arbeiten ohne es zu erzeugen. Oder habe ich da jetzt was übersehen?
TWinControl stammt auch von TControl ab, wo die Eigenschaft Parent eingeführt wird.

an tmp wird self.parent zugewiesen. Self ist ja das Objekt selber. den Parameter self müsste ma da sogar weglassen können. Die KLasse TCR_DB_Editor, zu der die Methode gehört in der an die Variable tmp der Wert self.parent zugewiesen wird, stmmt von TSchrollBox ab, in der die Eigenschaft Parent auch definiert ist.

Das Objekt temp wird gar nicht erstellt, sondern ist nur ein Platzhalter innerhalb der Methode.

So weit, so gut, doch folgt ja dieser Code:

Delphi-Quellcode:
function TCR_DB_Editor.GetRealParent : TWinControl;
var MYDBCtrlGrid : TMYDBCtrlGrid;
     tmp :TWinControl;
     Flag : boolean;
begin
     Flag := false;
     tmp := self.Parent;
     result := tmp;
     while (tmp <> nil) AND ( tmp.Parent <> nil ) AND (Flag =false) do
     begin
         if Pos('dbctrl', lowercase(tmp.ClassName )) > 0 then
         begin
             MYDBCtrlGrid := TMYDBCtrlGrid(tmp);
             result := MYDBCtrlGrid.Panel;
             Flag := true;
         end;
         tmp := tmp.Parent;
     end;
end;
Und da haben wir unseren tmp.parent

Ich fürchte, ich sollte den Spender des Quellcodes fragen, ob ich die Unit vollständig hier posten darf. Anderenfalls werd ich wohl die Quelle erst mal gründlicher studieren müssen. Ich versteh nämlich auch noch nicht alles, was der hier programmiert hat.

MyDBCtrlGrid stammt von TDBCtrlGrid ab, hat also auch einen Parent. MyDBCtrlGrid führt die Eigenschaft Panel ein. So sollte Parent nach dieser Prozedur auf Parent von MyDBCtrlgrid zeigen.

Die Variable tmp ist somit nur eine Hilfsvariable, um in der Schleife den aktuellen Parent festzuhalten.

In wie weit dieser Parent von Bedeutung ist für die Anzeige der Eingabemaske, konnte ich noch nicht feststellen, da ich nach Hinzufügen der Bedingung (tmp <> nil), die im Original nicht enthalten war, eine EInvalidOperation - Exception erhalte.

Allerdings tritt meine Exception EInvalidOperation hier auf:

Delphi-Quellcode:
procedure TCR_DB_Editor.ReOrderControls;
... Varablendeklaratioen
begin
 //Hier wird die alte Liste mit den Eingabecontrols gelöscht, um die passenden Eingabecontrols
 //entsprechend neuer Feldreihefolge in diese Liste einzufügen

 if Element_EditHeigth > FElement_RowHight then FElement_RowHight := Element_EditHeigth +2;
   // Label und Eingabe eine Höhe: deshalb /2 1 * Elementhöhe / Spalten // // oben und unten //

   ElementBlockHight := FElement_RowHight * Pred( FControlList.Count-FElement_NonVisib ) div (2 * FElement_ListCols);
   VertikalTopMargin := Pred(Height - ElementBlockHight ) div 2;
   if VertikalTopMargin < 1 then VertikalTopMargin := 1;


   ww := Width div (2 * FElement_ListCols) ;
   if ww < FMinWidthHoriz then ww := FMinWidthHoriz;


   VertikalRowCounter := 0;

//Hier bei HorzScrollbar kommt die neue Exception
//HorzScrollBar und VertScrollBar sind ider Vorgängerklasse TScrollBox bereits definiert
//Warum tritt dann die EInvalidOperation auf
   if HorzScrollBar <> nil then HorzScrollBar.Position := 0;
   if VertScrollBar <> nil then VertScrollBar.Position := 0;
Ist es geschickter, einen neuen Thread, mit dem Thema EInvalidOperation zu eröffnen? Ich mach das mal.
----------------------------------------------------------------------------------------------------

Meine EAbstractError Exception in meinem eigenen Entwurf hängt gar nicht mit der Zuweisung der Datenquelle zusammen, sondern mit der Verwendung einer Stringliste vom Typ TStrings anstelle von TStringList. Die Variable darf dabei vom Typ TStrings sein, jedoch muss an diese eine TStringlist zugewiesen werden. Jedenfalls in Turbo Delphi.

Falsch:

Delphi-Quellcode:
var
  List: TStrings;

procedure CreateList;
begin
  List := TStrings.Create;
end;

Richtig:

Delphi-Quellcode:
var
  List: TStrings;

procedure CreateList;
begin
  List := TStringList.Create;
end;
Mit der zweiten Version der Stringliste kann unbedenklich gearbeitet werden. Die erste Variante erzeugt beim Zugriff auf die Liste eine EAbstrctError Exception.
  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 16:49 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