AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein GUI-Design mit VCL / FireMonkey / Common Controls Delphi Komponente verursacht Fehler beim Beenden von Delphi/Projekt
Thema durchsuchen
Ansicht
Themen-Optionen

Komponente verursacht Fehler beim Beenden von Delphi/Projekt

Ein Thema von BAMatze · begonnen am 26. Jun 2009 · letzter Beitrag vom 3. Aug 2009
Antwort Antwort
BAMatze

Registriert seit: 18. Aug 2008
Ort: Berlin
759 Beiträge
 
Turbo Delphi für Win32
 
#1

Komponente verursacht Fehler beim Beenden von Delphi/Projekt

  Alt 26. Jun 2009, 14:50
Hallo und guten Tag an alle DP´ler,

Habe in meinem vorherigen Threat hier schonmal mehrere Fehler beschrieben, die bei mir nach Verwendung einer eigenen Komponente auftreten.

Und zwar läuft alles korrekt, wenn ich meine Komponente verwende (Unit mit Komponente startet, alles kann so wie vorgesehen verwendet werden und schließt ohne Fehlermeldung). Wenn jetzt aber das Projekt geschlossen wird, treten mehrere Fehler auf, bei denen ich eure Hilfe bräucht, weil ich damit gar nichts anfangen kann.

Fehler beim Beenden von Delphi/ des Projektes:
Projekt beenden
1.) ungöltige Zeigeroperation
2.) Zugriffsverletzung bei Adresse 2000679C in Modul rtl100.bpl. Fehler bei Adresse FFFFFFFF
Delphi
3.) Fehlermeldung, die ich versenden kann (oder nicht) wegen schwerem Fehler beim Beenden von Delphi
4.) Exception EAccessViolation in Modul coreide100.bpl bei 0015EDC8.Zugriffsverletzung bei Adresse 20A8EDC8 in Modul coreide100.bpl. Lesen von Adresse 0000049C.

Habe dazu nicht wirklich etwas gefunden, die meisten Threats bezugen sich lediglich auf Fehler, die beim Beenden des Programmes auftraten.

Vieleicht kann mir jemand einen Hinweis geben, wo ich den Fehler suchen muss.

Vielen Dank
BAMatze

Edit 1: Also die Fehler kann ich erstmal beseitigen, indem ich das Speichern
FExcelWorkbook.Close(true); im Destructor weglasse. Wobei ich eigentlich ja Änderungen speichern möchte. Hat dort eventuell jemand eine Idee? Also wie ich trotzdem speichern kann?
2. Account Sero
  Mit Zitat antworten Zitat
BAMatze

Registriert seit: 18. Aug 2008
Ort: Berlin
759 Beiträge
 
Turbo Delphi für Win32
 
#2

Re: Komponente verursacht Fehler beim Beenden von Delphi/Pro

  Alt 31. Jul 2009, 14:47
Hallo noch mal an alle DP´ler,

Ich pusche dieses Thema mal aus dem Grund, da vieleicht jemand mal in der SuFu darauf stößt und ähnliche Anlaufschwierigkeiten hat, wie ich. Also die Probleme sind beseitigt, dass Delphi/ das Projekt geschlossen werden kann ohne, dass es irgendeinen Fehler gibt.
Ich gebe hier mal meinen Quellcode zum besten für ein Testprogramm (ist allerdings nicht uneigennützig, weil noch ein Problem besteht, bei dem ich ein wenig Hilfe brauche (ein Fehler besteht noch))

Delphi-Quellcode:
unit Unit1;

interface

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

type
  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

const Testname = 'Test.xls';

var
  Form1: TForm1;
  FExcelApplication: TExcelApplication;
  FExcelWorkbook: TExcelWorkbook;
  FExcelWorksheet: TExcelWorksheet;

implementation

{$R *.dfm}

procedure ExcelDatenbank_anlegen;
var sparentroot: string;
    iUserLCID: integer;
begin
  sparentroot := ExtractFilePath(ParamStr(0));
  iUserLCID := GetUserDefaultLCID;
  FExcelApplication := TExcelApplication.Create(Nil);
  FExcelApplication.Workbooks.Add(emptyparam, iUserLCID);
  FExcelWorkbook := TExcelWorkbook.create(Nil);
  FExcelWorkbook.ConnectTo(FExcelApplication.ActiveWorkbook as ExcelWorkbook);
  FExcelWorkbook.Worksheets.Add(emptyParam, emptyParam, emptyParam, emptyParam, iUserLCID);
  FExcelWorksheet := TExcelWorksheet.create(Nil);
  FExcelWorksheet.ConnectTo(FExcelWorkbook.ActiveSheet as ExcelWorksheet);
  FExcelWorksheet.Cells.Item[3,1] := 'Hallo';
  FExcelWorksheet.Cells.Item[3,2] := 'dies';
  FExcelWorksheet.Cells.Item[3,3] := 'ist';
  FExcelWorksheet.Cells.Item[3,4] := 'ein';
  FExcelWorksheet.Cells.Item[3,5] := 'Test';
  FExcelWorkbook.Close(true, sparentroot + Testname, emptyParam, iUserLCID); // Speichert die Änderungen in Excel } //Speicherleck
  FExcelWorksheet.Free;
  FExcelWorkbook.Free;
  FExcelApplication.Free;
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  if not (csDesigning in Self.ComponentState) then
    begin
      FExcelWorkbook.Close(true); // Speicherleck
      FExcelWorksheet.Free;
      FExcelWorkbook.Free;
      FExcelApplication.Free;
    end;
end;

procedure TForm1.FormCreate(Sender: TObject);
var iUserLCID: integer;
    DWResult: DWORD;
begin
  if not FileExists(Testname) then ExcelDatenbank_anlegen;
  iUserLCID := GetUserDefaultLCID;
  // Wenn die Datenbank extern über Excel geöffnet ist dann wird sie geschlossen.
  // wenn diese Datei nicht geschlossen wird, dann kommt es zu einer Exception!!!
  if FindWindow('XLMain','Microsoft Excel - ' + TestName) <> 0 then
      SendMessageTimeout(FindWindow('XLMain','Microsoft Excel - ' + TestName), WM_CLOSE, 0, 0,
      SMTO_ABORTIFHUNG or SMTO_NORMAL, 5000, DWResult);
  FExcelApplication := TExcelApplication.Create(Nil);
  FExcelWorkbook := TExcelWorkbook.create(Nil);
  FExcelWorksheet := TExcelWorksheet.create(Nil);
  // vorhandener Exceldatei laden !!! wichtig !!! Die Anzahl der emtyParam ist Office-Versions abhängig
  FExcelApplication.Workbooks.Open(ExtractFilePath(ParamStr(0)) + TestName, emptyParam, emptyParam, emptyParam, emptyParam
                          , emptyParam, emptyParam, emptyParam, emptyParam, emptyParam, emptyParam, emptyParam, emptyParam
                          , emptyParam, emptyParam, iUserLCID);
  // Excel soll NICHT angezeigt werden
  FExcelApplication.visible[iUserLCID] := true;
  // verbinden des Workbooks und des Worksheets mit der in der exc geladenen Datei
  FExcelWorkbook.ConnectTo(FExcelApplication.ActiveWorkbook);
  FExcelWorksheet.ConnectTo(FExcelWorkbook.ActiveSheet as ExcelWorksheet);
end;

end.
Wer diesen Quellcode ohne FastMM4 testet, wird kein Problem feststellen. Allerdings sind noch 2 Speicherlecks vorhanden, welche ich gern beseitigen würde und zwar beim Speichern. Das Speichern funktioniert allerdings. Wieso treten aber Speicherlecks auf?
2. Account Sero
  Mit Zitat antworten Zitat
kalmi01
(Gast)

n/a Beiträge
 
#3

Re: Komponente verursacht Fehler beim Beenden von Delphi/Pro

  Alt 31. Jul 2009, 15:04
Hi,

nur mal so aus der Hüfte geschossen:

im FromCreate erzeugst Du Deine FExcel...
im FormClose schliesst Du diese

soweit OK, aber in ExcelDatenbank_anlegen machst Du das Gleiche noch mal.
Das muss in die Hose gehen !

Und im Create der Owner = NIL ist auch nicht so prickelnd. Warum darf das nicht Dein Form1 sein ?
  Mit Zitat antworten Zitat
BAMatze

Registriert seit: 18. Aug 2008
Ort: Berlin
759 Beiträge
 
Turbo Delphi für Win32
 
#4

Re: Komponente verursacht Fehler beim Beenden von Delphi/Pro

  Alt 31. Jul 2009, 15:25
Nunja da das Öffnen der Applicationen zeitlichgesehen nach einander erfolgt und das 2. Öffnen erst passiert, wenn alles schon wieder freigegeben ist (es ist also nicht verschachtelt!), rechne ich deswegen eigentlich nicht mit einem Fehler dort. Außerdem wenn die Datei Test.xls exisitert, dann wird das ganze ja auch nur einmal geöffnet.
Gestestet habe ich schonmal:
ist Test.xls vorhanden -> 1 Speicherleck, keine Exception
ist Test.xls vorhanden und die Speicherstell in FormClose auskommentiert -> alles ok
ist Test.xls nicht vorhanden -> 2 Speicherlecks, keine Exception
ist Test.xls nicht vorhanden und werden die Speicherstellen auskommentiert geben kommt es zu kein Speicherleck, allerdings wird man gefragt, ob man Speichern möchte (dies will ich ja eigentlich nicht) und ein OleFehler tritt auf nach dem 1. Schließen der Excelapplication.
2. Account Sero
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.475 Beiträge
 
Delphi 12 Athens
 
#5

Re: Komponente verursacht Fehler beim Beenden von Delphi/Pro

  Alt 31. Jul 2009, 18:02
Das Speicherleck, ist die Folge einer - sagen wir mal - ungeschickten Implementation von TOleServer und entzieht sich somit deinem Zugriff. Wenn du allerdings die Events der OleServer gar nicht brauchst, kannst du auch die Interfaces direkt verwenden:

Delphi-Quellcode:
procedure ExcelDatenbank_anlegen;
var
  sparentroot: string;
  iUserLCID: integer;
  FExcelApplication: ExcelApplication; // dies sind Interfaces, keine Klassen!
  FExcelWorkbook: ExcelWorkbook;
  FExcelWorksheet: ExcelWorksheet;
begin
  sparentroot := ExtractFilePath(ParamStr(0));
  iUserLCID := GetUserDefaultLCID;
  FExcelApplication := CoExcelApplication.Create;
  FExcelApplication.Workbooks.Add(emptyparam, iUserLCID);
  FExcelWorkbook := FExcelApplication.ActiveWorkbook;
  FExcelWorkbook.Worksheets.Add(emptyParam, emptyParam, emptyParam, emptyParam, iUserLCID);
  FExcelWorksheet := FExcelWorkbook.ActiveSheet as ExcelWorksheet;
  FExcelWorksheet.Cells.Item[3,1] := 'Hallo';
  FExcelWorksheet.Cells.Item[3,2] := 'dies';
  FExcelWorksheet.Cells.Item[3,3] := 'ist';
  FExcelWorksheet.Cells.Item[3,4] := 'ein';
  FExcelWorksheet.Cells.Item[3,5] := 'Test';
  FExcelWorkbook.Close(true, sparentroot + Testname, emptyParam, iUserLCID); // Speichert die Änderungen in Excel }
end;
Uwe Raabe
  Mit Zitat antworten Zitat
BAMatze

Registriert seit: 18. Aug 2008
Ort: Berlin
759 Beiträge
 
Turbo Delphi für Win32
 
#6

Re: Komponente verursacht Fehler beim Beenden von Delphi/Pro

  Alt 31. Jul 2009, 19:18
Danke dir Uwe, werde es morgen gleich mal probieren. Muss hier zu Hause erstmal alles runterladen.
2. Account Sero
  Mit Zitat antworten Zitat
BAMatze

Registriert seit: 18. Aug 2008
Ort: Berlin
759 Beiträge
 
Turbo Delphi für Win32
 
#7

Re: Komponente verursacht Fehler beim Beenden von Delphi/Pro

  Alt 3. Aug 2009, 08:49
Hallo und Guten Morgen an alle DP´ler,

Habe alles nochmal ein wenig mit Uwes Hinweisen umgearbeitet und die Routine sieht jetzt wie folgt aus:

Delphi-Quellcode:
unit Unit1;

interface

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

type
  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

const Testname = 'Test.xls';

var
  Form1: TForm1;
  FExcelApplication: ExcelApplication;
  FExcelWorkbook: ExcelWorkbook;
  FExcelWorksheet: ExcelWorksheet;
  sparentroot: string;
  iUserLCID: integer;

implementation

{$R *.dfm}

procedure ExcelDatenbank_anlegen;
begin
  FExcelApplication := CoExcelApplication.Create;
  FExcelApplication.Workbooks.Add(emptyparam, iUserLCID);
  FExcelWorkbook := FExcelApplication.ActiveWorkbook;
  FExcelWorkbook.Worksheets.Add(emptyParam, emptyParam, emptyParam, emptyParam, iUserLCID);
  FExcelWorksheet := FExcelWorkbook.ActiveSheet as ExcelWorksheet;
  FExcelWorksheet.Cells.Item[3,1] := 'Hallo';
  FExcelWorksheet.Cells.Item[3,2] := 'dies';
  FExcelWorksheet.Cells.Item[3,3] := 'ist';
  FExcelWorksheet.Cells.Item[3,4] := 'ein';
  FExcelWorksheet.Cells.Item[3,5] := 'Test';
  FExcelApplication.visible[iUserLCID] := true;
end;

procedure ExcelDatenbank_oeffnen;
begin
  FExcelApplication := CoExcelApplication.Create;
  FExcelApplication.Workbooks.Open(ExtractFilePath(ParamStr(0)) + TestName, emptyParam, emptyParam, emptyParam, emptyParam
                          , emptyParam, emptyParam, emptyParam, emptyParam, emptyParam, emptyParam, emptyParam, emptyParam
                          , emptyParam, emptyParam, iUserLCID);
  FExcelApplication.visible[iUserLCID] := true;
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  // Speichern und Schließen von Excel
  FExcelApplication.ActiveWorkbook.Close(true, sparentroot + Testname, emptyParam, iUserLCID);
end;

procedure TForm1.FormCreate(Sender: TObject);
var DWResult: DWORD;
begin
  sparentroot := ExtractFilePath(ParamStr(0));
  iUserLCID := GetUserDefaultLCID;
  if FindWindow('XLMain','Microsoft Excel - ' + TestName) <> 0 then
      SendMessageTimeout(FindWindow('XLMain','Microsoft Excel - ' + TestName), WM_CLOSE, 0, 0,
      SMTO_ABORTIFHUNG or SMTO_NORMAL, 5000, DWResult);
  if not FileExists(Testname) then ExcelDatenbank_anlegen
  else ExcelDatenbank_oeffnen;
end;

end.
Es gibt keine Speicherlecks mehr aber eine Frage, wenn ich mit den Interfaces arbeite (was ich ja auch mit create mache, also sie erstellen) brauche ich dann wirklich kein Free mehr?

Vielen Dank
BAMatze
2. Account Sero
  Mit Zitat antworten Zitat
Benutzerbild von sx2008
sx2008

Registriert seit: 16. Feb 2008
Ort: Baden-Württemberg
2.332 Beiträge
 
Delphi 2007 Professional
 
#8

Re: Komponente verursacht Fehler beim Beenden von Delphi/Pro

  Alt 3. Aug 2009, 10:02
Alle folgenden Variablen gehören unter den Abschnitt private der Klasse TForm1.
Delphi-Quellcode:
  FExcelApplication: ExcelApplication; // *
  FExcelWorkbook: ExcelWorkbook; // *
  FExcelWorksheet: ExcelWorksheet; // *
  sparentroot: string;
  iUserLCID: integer;
Die mit Stern markierten Variablen sind Interface Pointer und unterliegen der Referenzzählung.
Daher ist es sinnvoll, dass diese Variable die gleiche Lebensdauer wie das Formular bekommen.
Wenn das Formular stirbt, sorgt unsichtbarer Code vom Delphicompiler dafür, dass auch die Objekte
die hinter den Interface Pointern stehen freigegeben werden.
fork me on Github
  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 11:32 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