AGB  ·  Datenschutz  ·  Impressum  







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

Zugriffsverletzung, ich komm nicht drauf

Ein Thema von guidobrose · begonnen am 8. Jun 2007 · letzter Beitrag vom 11. Jun 2007
Antwort Antwort
guidobrose
(Gast)

n/a Beiträge
 
#1

Zugriffsverletzung, ich komm nicht drauf

  Alt 8. Jun 2007, 14:31
Noch einmal ich, aber ich komm jetzt nicht mehr weiter... Der Quellcode ist etwas umfangreicher, aber ich habs mal (fast) komplett hinkopiert.

Grundsätzlich gibt es ein Datenmodul "DM", in dem die Imagliste für die Toolbuttons (unter anderem) liegt. Zusätzlich werden die einzelnen "Seiten", die im Programm aufgerufen werden können (momentan nur "Uebersicht" und "Einstellungen" auf einem Nachkommen von TPanel in eine eigene Unit ausgelagert. Die meisten Komponenten werden zur Lz auf dem Panel angeordnet (muss ich so machen, weil ich in der Explorerversion die visuellen Komponenten nicht erweitern kann und ein paar Schmankerl eingebaut habe). Zudem hoffe ich den Quelltext etwas übersichtlicher zu bekommen, wenn jede Seite ihre eigene Unit hat. Es funktioniert auch ganz gut und mit etwas Hilfe aus dem Forum, habe ich auch meinen untergeordneten Toolbar auf dem Panel untergebracht. Die Imageliste wird dem Toolbar aus dem Datenmodul zugeordnet (auch auf dem Hauptformular) und hier hakt es auch, denn sobald ich die Liste dem Toolbar zuweise (TEinstellungen.Enter), habe ich zwar einen Glyph auf dem Button, aber beim Beenden des Programmes bekomme ich eine Zugriffsverletzung. Kommentiere ich diese Zeile aus, dann läuft es wieder. Komischerweise scheint die Zuweisung der Imageliste an den Toolbar des Hauptformulars kein Problem zu verursachen. Die Zuweisung in "OnShow", bzw. "Enter" ist übrigens, weil das Datenmodul in der Create-Routine noch nicht erzeugt ist.

Kann mir jemand mal unterstützend unter die Arme greifen??

Gruß.


Delphi-Quellcode:
unit ULlesy;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ToolWin, ComCtrls, StdCtrls, ExtCtrls, XTCtrls, ImgList, UDM, UUebersicht, UEinstellungen;

type
  TLlesy = class(TForm)
    TlBr: TToolBar;
    LblInformation: TLabel;
    PnlStatus: TPanel;
    ImgStatusConnection: TImage;
    ImgStatusBenutzer: TImage;
    TlBtnUebersicht: TToolButton;
    TlBtnArchiv: TToolButton;
    TlBtnDatenbank: TToolButton;
    TlBtnEinstellungen: TToolButton;
    ToolButton5: TToolButton;
    TlBtnSeparator1: TToolButton;
    TlBtnInformation: TToolButton;
    TlBtnBeenden: TToolButton;
    TlBtnVollbild: TToolButton;
    procedure FormCanResize(Sender: TObject; var NewWidth, NewHeight: Integer;
      var Resize: Boolean);
    procedure FormCreate(Sender: TObject);
    procedure FormShow(Sender: TObject);
    procedure TlBtnBeendenClick(Sender: TObject);
    procedure TlBtnInformationClick(Sender: TObject);
    procedure TlBtnEinstellungenClick(Sender: TObject);
    procedure TlBtnUebersichtClick(Sender: TObject);
    procedure TlBtnVollbildClick(Sender: TObject);
  private
    { Private-Deklarationen }
    Uebersicht: TUebersicht;
    Einstellungen: TEinstellungen;
    procedure SetPanel(VP: TVisiblePanel);
  public
    { Public-Deklarationen }
  end;

var
  Llesy: TLlesy;

implementation

uses UInfo;
{$R *.dfm}

procedure TLlesy.FormCreate(Sender: TObject);
begin
//Allgemeine Vorbesetzungen
Color:=clXTBackground;
//Weitere Fenster erzeugen
Uebersicht:=TUebersicht.Create(self,Llesy);
Einstellungen:=TEinstellungen.Create(self,Llesy);
end;

procedure TLlesy.FormShow(Sender: TObject);
begin
//Allgemeine Vorbesetzungen
TlBr.Images:=DM.ImgLst30x30;
//Wird beim Start auf TRUE gesetzt und im Infodialog wieder gelöscht.
DM.FirstStart:=True;
//Infodialog aufrufen
Information.Position:=poScreenCenter;
Information.ShowModal;
end;

procedure TLlesy.FormCanResize(Sender: TObject; var NewWidth,
  NewHeight: Integer; var Resize: Boolean);
begin
//Minimale Größe auf 800x600 begrenzen
  if (NewWidth<800) or (NewHeight<600) then
    Resize:=False;
end;

procedure TLlesy.TlBtnBeendenClick(Sender: TObject);
begin
Close;
end;

procedure TLlesy.TlBtnInformationClick(Sender: TObject);
begin
Information.Position:=poMainFormCenter;
Information.ShowModal;
end;

procedure TLlesy.SetPanel(VP: TVisiblePanel);
begin
  Uebersicht.Visible:=VP=vpUebersicht;
  Einstellungen.Visible:=VP=vpEinstellungen;
  case VP of
    vpUebersicht: LblInformation.Caption:='Übersicht: Fahrzeuge an- und abmelden';
    vpArchiv: ;
    vpDatenbank: ;
    vpEinstellungen:
      begin
        LblInformation.Caption:='Programm: Einstellungen bearbeiten';
        Einstellungen.SetFocus;
      end;
    vpSQLService: ;
  end;
end;

procedure TLlesy.TlBtnUebersichtClick(Sender: TObject);
begin
SetPanel(vpUebersicht);
end;

procedure TLlesy.TlBtnEinstellungenClick(Sender: TObject);
begin
SetPanel(vpEinstellungen);
end;

procedure TLlesy.TlBtnVollbildClick(Sender: TObject);
begin
  if not (Align=alClient) then
  begin
    DM.Anzeige.Top:=Top;
    DM.Anzeige.Left:=Left;
    DM.Anzeige.Width:=Width;
    DM.Anzeige.Height:=Height;
    Align:=alClient;
  end
  else
  begin
    Align:=alNone;
    Top:=DM.Anzeige.Top;
    Left:=DM.Anzeige.Left;
    Width:=DM.Anzeige.Width;
    Height:=DM.Anzeige.Height;
  end;
end;

end.
Delphi-Quellcode:
unit UEinstellungen;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ToolWin, ComCtrls, StdCtrls, ExtCtrls, XTCtrls, ImgList, UDM;

type
  TEinstellungen = class(TPanel)
  private
    { Private-Deklarationen }
    TlBr: TToolBar;
    TlBtnSichern: TToolButton;

    Information: TXTPanel;
    InfBenutzer: TXTEdit;
    InfComputer: TXTEdit;

    Datenbank: TXTPanel;
    DtbTreiber: TXTEdit;
    DtbServer: TXTEdit;
    DtbName: TXTEdit;

    Peripherie: TXTPanel;
    PerAmpelIP: TXTEdit;
    PerAmpelPort: TXTEdit;
    PerAnzeigeIP: TXTEdit;
    PerAnzeigePort: TXTEdit;
    procedure Enter(Sender: TObject);
  public
    { Public-Deklarationen }
    constructor Create(AOwner: TComponent; AParent: TWinControl);
  end;

implementation

constructor TEinstellungen.Create(AOwner: TComponent; AParent: TWinControl);
begin
  inherited Create(AOwner);
//Allgemeine Parameter vorbesetzen
  Parent:=AParent;
  BevelInner:=bvNone;
  BevelKind:=bkFlat;
  BevelOuter:=bvNone;
  ParentColor:=True;
  Top:=50; //Beliebiger Wert, der unterhalb vom Toolbar liegt
  Align:=alClient;
  AlignWithMargins:=True;
  Visible:=False;
  OnEnter:=Enter;
//Untergeordnete Elemente erzeugen
  TlBr:=TToolBar.Create(self);
  TlBr.Parent:=self;
  TlBr.DrawingStyle:=ComCtrls.dsGradient;
  TlBr.Height:=31;
  TlBr.ButtonHeight:=30;
  TlBr.ButtonWidth:=30;
  TlBtnSichern:=TToolButton.Create(self);
  TlBtnSichern.Parent:=TlBr;
  TlBtnSichern.ImageIndex:=6;

  Information:=TXTPanel.Create(self,self);
  Information.Caption:='Information';
  Information.Top:=35;
  Information.Height:=80;
  Information.Width:=260;
  Information.Enabled:=False;//Nur Information, keine Eingaben möglich
  InfBenutzer:=TXTEdit.Create(self,Information,30);
  InfBenutzer.Caption:='Benutzer';
  InfComputer:=TXTEdit.Create(self,Information,55);
  InfComputer.Caption:='Computer';

  Datenbank:=TXTPanel.Create(self,self);
  Datenbank.Caption:='Datenbank';
  Datenbank.Top:=125;
  Datenbank.Height:=105;
  Datenbank.Width:=260;
  DtbTreiber:=TXTEdit.Create(self,Datenbank,30);
  DtbTreiber.Caption:='Treiber';
  DtbServer:=TXTEdit.Create(self,Datenbank,55);
  DtbServer.Caption:='Server';
  DtbName:=TXTEdit.Create(self,Datenbank,80);
  DtbName.Caption:='Name';

  Peripherie:=TXTPanel.Create(self,self);
  Peripherie.Caption:='Peripherie';
  Peripherie.Top:=240;
  Peripherie.Height:=130;
  Peripherie.Width:=260;
  PerAmpelIP:=TXTEdit.Create(self,Peripherie,30);
  PerAmpelIP.Caption:='Ampel - IP';
  PerAmpelPort:=TXTEdit.Create(self,Peripherie,55);
  PerAmpelPort.Caption:='Ampel - Port';
  PerAnzeigeIP:=TXTEdit.Create(self,Peripherie,80);
  PerAnzeigeIP.Caption:='Anzeigetafel - IP';
  PerAnzeigePort:=TXTEdit.Create(self,Peripherie,105);
  PerAnzeigePort.Caption:='Anzeigetafel - Port';
end;

procedure TEinstellungen.Enter(Sender: TObject);
begin
  TlBr.Images:=DM.ImgLst24x24;
  InfBenutzer.Text:=DM.Benutzer;
  InfComputer.Text:=DM.Computer;
  DtbTreiber.Text:=DM.Datenbank.Treiber;
  DtbServer.Text:=DM.Datenbank.Server;
  DtbName.Text:=DM.Datenbank.Name;
end;

end.
  Mit Zitat antworten Zitat
Jürgen Thomas

Registriert seit: 13. Jul 2006
Ort: Berlin
750 Beiträge
 
#2

Re: Zugriffsverletzung, ich komm nicht drauf

  Alt 8. Jun 2007, 15:59
Hallo,

ich verstehe (natürlich) nicht Deine ganze Konstruktion. Ich finde aber nirgends Maßnahmen, die Du beim Closing oder im Destruktor veranlasst. Für mich sieht es so aus, als ob das Programm "selbständig" zuerst das Datenmodul auflöst und erst danach das/die Panel(s); also geht die ImageList "flöten", aber ein Panel setzt ihre Existenz noch voraus.

Verfahrensvorschlag:
  1. Erzeuge zumindest Events, die beim Closing ausgelöst werden. (Bitte selbst suchen; ich habe ihre Delphi-Namen vergessen.)
  2. Löse dort per Befehl solche Verbindungen, die "gefährdet" sind.
  3. Steuere im MainForm und ggf. in der dpr-Datei selbst, was wann aufgelöst werden soll.
Ich hoffe, ich konnte helfen. Jürgen
#D mit C# für NET, dazu Firebird
früher: Delphi 5 Pro, Delphi 2005 Pro mit C# (also NET 1.1)
Bitte nicht sauer sein, wenn ich mich bei Delphi-Schreibweisen verhaue; ich bin inzwischen an C# gewöhnt.
  Mit Zitat antworten Zitat
Benutzerbild von SirThornberry
SirThornberry
(Moderator)

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

Re: Zugriffsverletzung, ich komm nicht drauf

  Alt 8. Jun 2007, 16:03
also mir fällt als erstes auf das du Object instanzierst aber diese nicht frei gibst. Dadurch können auch AV's auftreten.
Beispiel (trifft bei dir nicht zu verdeutlicht aber das es durch events passieren kann):
Man erstellt einen Timer der alle x millisekunden das OnTimer aufruft.
Dann schließt man das form welches auch frei gegeben wird und der Timer der nicht freigegeben wurde versucht weiterhin das Event aufzurufen was aber fehlschlägt da das Form frei gegeben ist wo die Eventmethode drin steckte.

Bevor solche leichtsinnigen Fehler nicht behoben sind ist es für mich verschenkte Zeit mir den Rest anzuschauen. Mir ist es lieber du opferst erstmal Zeit zum implementieren des Freigebens und für andere grundlegende Dinge.
Jens
Mit Source ist es wie mit Kunst - Hauptsache der Künstler versteht's
  Mit Zitat antworten Zitat
Gremlin

Registriert seit: 18. Apr 2006
Ort: Im Süden
176 Beiträge
 
Delphi 7 Enterprise
 
#4

Re: Zugriffsverletzung, ich komm nicht drauf

  Alt 8. Jun 2007, 17:24
@guidobrose

Sei mir nicht böse, aber es ist leider sehr schwierig, sich in deinem Code zurechtzufinden. Wär es eventuell möglich, den gesamten Code oder einen gekürzten Code mit einer "lauffähigen" AV als Attachment (Source keine Exe) beizulegen? Danke.
Gruss Gremlin
  Mit Zitat antworten Zitat
oldmax

Registriert seit: 27. Apr 2006
Ort: Gieboldehausen
167 Beiträge
 
#5

Re: Zugriffsverletzung, ich komm nicht drauf

  Alt 10. Jun 2007, 06:09
Hi
Ok, ich weiß nicht, ob dir meine Antwort bei der Fehlerbeseitigung hilft, aber um das Datenmodul zuerst zu erzeugen und dann erst deine Form ist einfach unter Projekt->Optionen die Reihenfolge zu ändern. Erst das Datenmodul, dann die Form.
Das hilft dir zumindest, das du bei Form.Create ein gültiges Datenmodul hast.
Gruß oldmax
Noch ist mein Rechner mir zu Diensten.... ansonsten habe ich die Macht ihn zu vernichten !
  Mit Zitat antworten Zitat
guidobrose
(Gast)

n/a Beiträge
 
#6

Re: Zugriffsverletzung, ich komm nicht drauf

  Alt 11. Jun 2007, 06:03
Danke für die Antworten bisher, da ich das hier auf der Arbeit mache (normalerweise programmiere ich Steuerungen) konnte ich bislang nicht antworten.

Ich gehe auch davon aus, dass es etwas damit zu tun hat, dass das Datenmodul zuerst freigegeben wird und darum etwas "fehlt". Ich versuche jetzt erst mal das DM zuerst zu erzeugen und anschließend den Rest.
Stimmt, ich gebe keine Objekte mehr frei, aber soviel ich jetzt gelernt habe, ist bei allen Objekten mit Owner, dieser zuständig und auch in der Lage, dies zu tun, wenn die Anwendung geschlossen wird. Irre ich mich hier? Einen Destruktor für TEinstellungen hatte ich übrigens schon einmal geschrieben, das hat aber nichts gefruchtet, darum habe ich ihn wieder entfernt.

Guido
  Mit Zitat antworten Zitat
hoika

Registriert seit: 5. Jul 2006
Ort: Magdeburg
8.270 Beiträge
 
Delphi 10.4 Sydney
 
#7

Re: Zugriffsverletzung, ich komm nicht drauf

  Alt 11. Jun 2007, 07:51
Hallo,

kommentiere mal testweise die Zeile

TlBr.Images:=DM.ImgLst24x24;

aus.

Klar kommen jetzt Bildchen mehr,
aber ist dann die Scutzverletzung weg ?

Wenn ja, schreib in deinen Klassendestruktor (der zu Erzeuge ist) ein
TlBr.Images:=NIL rein


Heiko
Heiko
  Mit Zitat antworten Zitat
guidobrose
(Gast)

n/a Beiträge
 
#8

Re: Zugriffsverletzung, ich komm nicht drauf

  Alt 11. Jun 2007, 08:06
@hoika: Das hatte ich schon gemacht und dann funktionierte es auch, die Sache mit dem Destruktor hatte ich ebenfalls schon probiert, allerdings ohne Erfolg.

Die gute Nachricht: Es funktioniert jetzt!

Ich lasse das Datenmodul jetzt nicht mehr automatisch erzeugen, sondern mache das in der Create-Methode des Hauptformulars selbst. Danach war die (oder eine) Zugriffsverletzung zwar immer noch vorhanden, aber es lag jetzt daran, dass die ADOConnection (im Datenmodul) noch geöffnet war. Jetzt wird diese im Destruktor des Hauptformular geschlossen und es geht.

Danke allen Helfern.
  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 19:18 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