| Autor |
Beitrag |
Tino
      

Beiträge: 9839
Erhaltene Danke: 45
Windows 8.1
Delphi XE4
|
Verfasst: Di 20.07.04 15:09
Hallo!
Ich benutze die folgende Procedure um mir alle Fenstertitel in eine Stringlist einfügen zu lassen:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30:
| Function EnumWindowsToStrings (aStrings: tStrings): Boolean;
Function EnumWindowsProc (aHandle: HWND; aList: tStrings): Bool; stdcall; export; Var Title: Array[0..255] Of Char; Begin EnumWindowsProc := True; If GetWindowText (aHandle, @Title, 255) > 0 Then If IsWindowVisible (aHandle) And (String (Title) <> '') Then If aList.Add (String (Title)) = -1 Then ; End;
Begin EnumWindowsToStrings := False;
Assert (Assigned (aStrings)); If Not Assigned (aStrings) Then Exit;
aStrings.BeginUpdate; Try If Not EnumWindows (@EnumWindowsProc, Integer (aStrings)) Then Exit; Finally aStrings.EndUpdate; End;
EnumWindowsToStrings := True; End; |
Wenn ich diese Funktion ganz normal in meiner Anwendung aufrufe klappt auch alles perfekt. Wenn ich allerdings diese Funktion innerhalb eines Threads (in der überschriebenen Execute Methode) ausführe funktioniert es nicht. Die Funktion EnumWindows wird zwar aufgerufen aber danach passiert nichts mehr. Laut dem Debugger wird auch ein paar mal die EnumWindowsProc Procedure aufgerufen.
Woran kann das liegen?
Gruß
Tino
|
|
maxk
      
Beiträge: 1696
Erhaltene Danke: 1
Win XP, Debian Lenny
Delphi 6 Personal
|
Verfasst: Di 20.07.04 15:17
Also bei mir funktioniert's mit deinem Code! //Edit: Und zwar mit TListBox.Items
_________________ Ein Computer wird das tun, was Du programmierst - nicht das, was Du willst.
Zuletzt bearbeitet von maxk am Di 20.07.04 15:22, insgesamt 1-mal bearbeitet
|
|
Udontknow
      
Beiträge: 2596
Win7
D2006 WIN32, .NET (C#)
|
Verfasst: Di 20.07.04 15:20
Hallo!
Ich denke, das hängt davon ab, was für einen TStrings-Nachfahren du da übergibst. Wenn du z.B. Memo.Lines übergibst, so ist das fatal, denn sämtliche Beeinflussungen von Steuer-Elementen wie ein Memo, eine Listbox etc. sind nicht threadsicher und müssen daher per Synchronize mit dem VCL-Hauptthread synchronisiert werden.
Edit: @MaxK: Hast du es in einem separaten Thread aufgerufen?
Cu,
Udontknow
|
|
Tino 
      

Beiträge: 9839
Erhaltene Danke: 45
Windows 8.1
Delphi XE4
|
Verfasst: Di 20.07.04 15:27
Ich habe tStringList benutzt. Ich benutze also keine VCL Komponente.
So sieht die Implementierung von Exceute des Threads aus:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21:
| Procedure tTestThread.Execute; Var SL: tStringList; Begin fStop := False;
SL := tStringList.Create; Try
SL.Clear; If EnumWindowsToStrings (SL) Then ;
Finally SL.Free; End; End; |
Gruß
Tino
|
|
Udontknow
      
Beiträge: 2596
Win7
D2006 WIN32, .NET (C#)
|
Verfasst: Di 20.07.04 15:37
Also, bei mir funktioniert da alles, mein gesetzter Breakpoint bei SL.Free wird problemlos angesprungen, und zu diesem Zeitpunkt beinhaltet SL auch tatsächlich die Bezeichnungen der Fenster.
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22:
| procedure TForm1.Button1Click(Sender: TObject); var T:TTestThread; begin T:=TTestThread.Create(True); T.FreeOnTerminate:=True; T.Resume; end;
Procedure tTestThread.Execute; Var SL: tStringList; Begin SL := tStringList.Create; Try SL.Clear; EnumWindowsToStrings (SL); Finally SL.Free; End; End; |
Der Knackpunkt ist: Wie gibst du denn die Sachen dann zurück an den Haupt-Thread, der damit ja bestimmt was anfangen soll (darstellen)?
|
|
Tino 
      

Beiträge: 9839
Erhaltene Danke: 45
Windows 8.1
Delphi XE4
|
Verfasst: Do 22.07.04 09:42
So, gestern Abend habe ich nur rausgefunden woran es lag. Im Testprogramm habe ich direkt in der Projektdatei (dpr) das Threadobjekt initialisiert und gestartet. Da dort noch kein Application.Run aufgerufen wurde funktionierte das ganze tThread Objekt nicht wie erwartet.
Danke für Eure Antworten!
Gruß
Tino
|
|
Udontknow
      
Beiträge: 2596
Win7
D2006 WIN32, .NET (C#)
|
Verfasst: Do 22.07.04 10:20
Nutzt du evtl. die Synchronize-Routine? Dann ist es nämlich klar, Synchronize wartet, bis der VCL-Haupt-Thread erneut in seine ProcessMessages-Routine gelangt (und das tut er nur, wenn Application.Run aufgerufen wurde).
Cu,
Udontknow
|
|
maxk
      
Beiträge: 1696
Erhaltene Danke: 1
Win XP, Debian Lenny
Delphi 6 Personal
|
Verfasst: Do 22.07.04 10:36
| Tino hat folgendes geschrieben: | Da dort noch kein Application.Run aufgerufen wurde funktionierte das ganze tThread Objekt nicht wie erwartet. |
Komisch ich habe den Thread in FormCreate gestartet, das geschieht doch eigentlich auch für Application.Run, oder? Aber in Zusammenhang mit Udontknows Antwort würde es logisch klingen
_________________ Ein Computer wird das tun, was Du programmierst - nicht das, was Du willst.
|
|
Tino 
      

Beiträge: 9839
Erhaltene Danke: 45
Windows 8.1
Delphi XE4
|
Verfasst: So 25.07.04 20:24
| Udontknow hat folgendes geschrieben: | | Nutzt du evtl. die Synchronize-Routine? Dann ist es nämlich klar, Synchronize wartet, bis der VCL-Haupt-Thread erneut in seine ProcessMessages-Routine gelangt (und das tut er nur, wenn Application.Run aufgerufen wurde). |
Sorry, wegen der späten Antwort. Ja, ich habe Synchronize-Objekte benutzt. Und beim Debuggen war auch zu sehen das dort irgendetwas nicht stimmt. Ich denke also du hast recht
Danke für die Aufklärung!
Gruß
Tino
|
|