Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Systemfehler. Code: 1400 Ungültiges Fensterhandle (https://www.delphipraxis.net/118595-systemfehler-code-1400-ungueltiges-fensterhandle.html)

Bootscreen 11. Aug 2008 11:32


Systemfehler. Code: 1400 Ungültiges Fensterhandle
 
Moinsen

und wiedermal ich ^^

Diesmal habe cih das Problem das ich beim schließen meines Programmes folgenden Fehler bekomme:

http://img372.imageshack.us/img372/2...blage01kd4.jpg

Der Fehler tritt immer dann auf wenn ich im Programm meine Funktion in einem Thread starte. Starte ich die Funktion ohne Thread kommt kein Fehler.

Der Fehler kommt auch nur dann wenn ich folgenden Bereich drin lasse (kommentiere ich ihn aus geht es wieder).
Delphi-Quellcode:
   for iiii := 0 to ListBox4.Count -1 do
            begin
                Form1.Memo1.Lines.Clear;
                Form1.Memo1.Lines.Text := '';
                ListBox3.Items.Clear;
                ListBox2.Items.Clear;  
                Filename := ListBox4.Items.Strings[iiii];
                Memo1.Lines.LoadFromFile('Datanorm\'+Filename);
                for iii := 0 to Memo1.Lines.Count-1 do
                begin
                   datanormsatz := TStringList.Create;
                    line := Memo1.Lines[iii];
                    Split(';',line,datanormsatz);
                    if datanormsatz[0] = 'A' then
                        ListBox3.Items.Add(line);
                    if datanormsatz[0] = 'T' then
                        ListBox2.Items.Add(line);
                   datanormsatz.free;
                end;
               Label5.Caption := IntToStr(Listbox3.Count-1);

          Memo2.Lines.Add('Beginne Import von: '+ Filename);
                WriteLog('Beginne Import von: '+ Filename);
                //db_import;

            end;
Hoffe ihr seht wo mein Fehler liegt. kann euch auch gerne noch den Rest des Codes zeigen.

Aurelius 11. Aug 2008 11:33

Re: Systemfehler. Code: 1400 Ungültiges Fensterhandle
 
Läuft dieser Code innerhalb des Threades? Das wäre sehr ungünstig, in einem thread greift man nicht auf VCL-Komponenten zu.

mkinzler 11. Aug 2008 11:35

Re: Systemfehler. Code: 1400 Ungültiges Fensterhandle
 
In welcher Zeile (Debugger)?

Bootscreen 11. Aug 2008 11:36

Re: Systemfehler. Code: 1400 Ungültiges Fensterhandle
 
Er nennt mir keine Zeile.

Wieso greift man in einem Thread nicht auf VCL-Komponennten zu???

DeddyH 11. Aug 2008 11:37

Re: Systemfehler. Code: 1400 Ungültiges Fensterhandle
 
Weil die VCL nicht threadsafe ist. Ein Zugriff kann bzw. darf nur über Aufruf von Synchronize erfolgen.

mkinzler 11. Aug 2008 11:37

Re: Systemfehler. Code: 1400 Ungültiges Fensterhandle
 
Zitat:

Wieso greift man in einem Thread nicht auf VCL-Komponennten zu???
Weil die VCL (noch) nicht threadsicher ist.

Bootscreen 11. Aug 2008 11:41

Re: Systemfehler. Code: 1400 Ungültiges Fensterhandle
 
Ich versteh zwar grad nicht wieso aber ok.

Kann mir vllt jemand sagen wie ich es anstelle ohne auf die VCL zurückzugreifen?
Derzeit lade ich eine Textdatei runter, lade sie in ein memofeld splite dieses dann in zwei listen felder und splite dann weiter.

und ich ehrlich gesagt keine ahnung wie ich das ohne das memofeld und die lsitboxen anstellen soll


//edit: desweiteren habe ich auch eine progressbar die ich im thread aktualiesire. wie sol cih das alles denn machen wenn ich in einem thread nicht darauf zugreifen kann, darf, soll?

DeddyH 11. Aug 2008 11:54

Re: Systemfehler. Code: 1400 Ungültiges Fensterhandle
 
Schau mal in die Hilfe zu TThread.Synchronize

Bernhard Geyer 11. Aug 2008 12:12

Re: Systemfehler. Code: 1400 Ungültiges Fensterhandle
 
Zitat:

Zitat von mkinzler
Zitat:

Wieso greift man in einem Thread nicht auf VCL-Komponennten zu???
Weil die VCL (noch) nicht threadsicher ist.

Letztendlich ist es aber die WinAPI die für GDI/Fenster-Handles eine Thread-Affinität hat so das nur vom erzeugenden Thread auf ein GDI/Fensterhandle zugegriffen werden darf.

mkinzler 11. Aug 2008 12:24

Re: Systemfehler. Code: 1400 Ungültiges Fensterhandle
 
Mal sehen, was die kommende Threadlibrary von CodeGear bringt

Bootscreen 11. Aug 2008 13:13

Re: Systemfehler. Code: 1400 Ungültiges Fensterhandle
 
Oh man ich glaub ich schmeiß das mit den Threads wieder über den haufen.

Gibt es eine andere Möglichkeit mit der ich Funktionen aufrufen kann und das Programm in der zwischenzeit nicht einfriert?
Ich hatte irgendwo mal was von ProcessMessages oder so gelesen. Wäre das noch eine alternative mit der ich diese ganzen Probleme nicht habe?

DeddyH 11. Aug 2008 13:18

Re: Systemfehler. Code: 1400 Ungültiges Fensterhandle
 
Das heißt Application.ProcessMessages (Unit Forms) und bewirkt, dass bei einem Aufruf die Botschaftswarteschlange abgearbeitet wird. Allerdings verlangsamt dies Dein Programm. Wenn Du also eine große Anzahl an Daten hast, solltest Du Application.ProcessMessages nur alle z.B. 100 Sätze aufrufen.

Bootscreen 11. Aug 2008 14:37

Re: Systemfehler. Code: 1400 Ungültiges Fensterhandle
 
naja soviele nachrichten ahb ich nicht.

http://img512.imageshack.us/img512/2...lage01snu0.jpg

so schaut halt mein programm imoment aus, das untere ist ein memo feld wo halt die nachrichten was gemacht wird und eventuelle fehler hinzugefügt werden, aber das wars auch an anchrichten.
aber ich würde halt auch gerne die statusbar und die anzahl x von y nutzen. wäre das mit Application.ProcessMessages machbar ohne dass das programm elendig alngsam wird? (was es egtl eh schon durch den datenbank zugriff ist)

DeddyH 11. Aug 2008 14:43

Re: Systemfehler. Code: 1400 Ungültiges Fensterhandle
 
Wie gesagt, abhängig von der Datenmenge sollte man Application.ProcessMessages behutsam einsetzen. Wenn es aber nur eine Handvoll Daten sind, kannst Du es auch hinter jede Änderung von sichtbaren Komponenten (z.B. Position der Progressbar) setzen. Probier halt mal ein bisschen rum, bis Du den für Dich richtigen Wert ermittelt hast.

Bootscreen 11. Aug 2008 14:55

Re: Systemfehler. Code: 1400 Ungültiges Fensterhandle
 
ok also muss ich im programm aus z.b.
Delphi-Quellcode:
Memo1.Lines.Add('Beginne Download');
Delphi-Quellcode:
Memo1.Lines.Add('Beginne Download');
Application.ProcessMessages;
machen?

DeddyH 11. Aug 2008 15:01

Re: Systemfehler. Code: 1400 Ungültiges Fensterhandle
 
So in etwa. Ich würde allerdings alle veränderlichen Komponenten mit den jeweils neuen Werten bestücken (also das Memo, die Progressbar etc.) und anschließend einmalig Application.ProcessMessages aufrufen.

automatix 12. Aug 2008 07:59

Re: Systemfehler. Code: 1400 Ungültiges Fensterhandle
 
Hallo!

Oder wenn Du weiterhin einen Thread verwenden willst, könnte es etwa so aussehen (Nicht getestet, einfach runtergetippt). Nicht schön, aber ...

Delphi-Quellcode:
unit ThreadDummy;

interface

uses
  SysUtils, Classes;

type
  TThreadDummy = class(TThread)
  private
    { Private-Deklarationen }
    FFileCount: Integer;
    FFileIndex: Integer;
    FFileName: string;
     FLine: string;
    procedure GetFileCount;
    procedure GetFileName;
    procedure Listbox2Add;
    procedure Listbox3Add;
    procedure Split(const aParam1: string;
                    const aParam2: string;
                    const aParam3: TStrings);
  protected
    procedure Execute; override;
  end;

implementation

{ Wichtig: Methoden und Eigenschaften von Objekten in visuellen Komponenten dürfen
  nur in einer Methode namens Synchronize aufgerufen werden, z.B.

      Synchronize(UpdateCaption);

  und UpdateCaption könnte folgendermaßen aussehen:

    procedure TThreadDummy.UpdateCaption;
    begin
      Form1.Caption := 'Aktualisiert in einem Thread';
    end; }

uses
   FormStart;

{ TThreadDummy }

procedure TThreadDummy.Execute;
var
   files, lines: Integer;
  data, datanormsatz: TStringList;
begin
  { Thread-Code hier einfügen }

  data := nil;
   datanormsatz := nil;
  try
    data := TStringList.Create;
    datanormsatz := TStringList.Create;

    Synchronize(GetFileCount);
    for files := 0 to FFileCount do begin
        Synchronize(Form1.ListBox1.Clear);
        Synchronize(Form1.ListBox2.Clear);
        FFileIndex := files;
        Synchronize(GetFileName);
       data.LoadFromFile('Path' + FFileName);
      for lines := 0 to data.Count - 1 do begin
         datanormsatz.Clear;
        FLine := data[lines];
        Split(';', FLine, datanormsatz);
        if datanormsatz[0] = 'A' then
          Synchronize(Listbox3Add);
        if datanormsatz[0] = 'T' then
          Synchronize(Listbox2Add);
      end;
    end;
  finally
     FreeAndNil(data);
    FreeAndNil(datanormsatz);
  end;
end;

procedure TThreadDummy.GetFileCount;
begin
   FFileCount := Form1.ListBox4.Count;
end;

procedure TThreadDummy.GetFileName;
begin
   FFileName := Form1.ListBox1.Items[FFileIndex];
end;

procedure TThreadDummy.Listbox2Add;
begin
  Form1.ListBox2.Items.Add(FLine);
end;

procedure TThreadDummy.Listbox3Add;
begin
  Form1.ListBox3.Items.Add(FLine);
end;

procedure TThreadDummy.Split(const aParam1: string;
                             const aParam2: string;
                             const aParam3: TStrings);
begin
   // Do split
end;
Grüße


Alle Zeitangaben in WEZ +1. Es ist jetzt 14:12 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz