Entwickler-Ecke
Windows API - Eigenes Thread-Handle ermitteln
Heiko - Mo 25.12.06 20:05
Titel: Eigenes Thread-Handle ermitteln
Hallo Leuts,
inzwischen habe ich mich daran gewöhnt mit Threads zu arbeiten, da dadurch die GUI noch weiterhin flüssig reagiert, obwohl es noch genug zu tun gibt ;). Leider haben Threads den Nachteil, dass sie immer das maximum an Ressourcen verbrauchen, außer wenn man den mit sleep oder GetMessage abbremst. Da ja mein Thread auch mit dem Rest kummunizieren soll, habe ich mit für GetMessage entschieden, da ich dort auch keine Synchronisation zur Kommunikation brauche.
ICh stehe jetzt aber vor dem Problem das Thread-Handle zu bekommen, was ja BeginThread zurückgibt, aber leider nicht dem Thread selber mitteilt. Weiß einer von euch wie man aus dem Thread heraus ohne Synchronisation an das Thread-Handle kommt?
Grüße Heiko
BenBE - Mo 25.12.06 20:11
GetCurrentThread ;-)
Heiko - Di 26.12.06 10:57
Habe ich auch schon probiert, aber da bekomme ich den maximalen Cardinal zurück, stimmt also nicht :(.
Delete - Di 26.12.06 11:28
Sollte aber nicht der Fall sein:
Zitat: |
GetCurrentThread
Retrieves a pseudo handle for the calling thread. |
Heiko - Di 26.12.06 12:08
Luckie hat folgendes geschrieben: |
Sollte aber nicht der Fall sein:
Zitat: | GetCurrentThread
Retrieves a pseudo handle for the calling thread. |
|
Das hatte ich bei MSDN auch gelesen, aber trotzdem bekomme ich nonsense zurück :(.
Mein Code:
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:
| procedure TestThread(var ThreadID: Cardinal); var Thread: Integer; msg: tagMSG; begin Thread:=GetCurrentThread; while GetMessage(msg, Thread, 0, 0) do begin if msg.message = WM_CREATE then begin Form1.Caption:='sdf'; end; end; CloseHandle(Thread); end;
procedure TForm1.FormCreate(Sender: TObject); var ThreadID: Cardinal; Thread: Integer; begin Thread:=BeginThread(nil, 0, @TestThread, @ThreadID, 0, ThreadID); ShowMessage(IntToStr(Thread)); SendMessage(Thread, WM_CREATE, 0, 0); end; |
BenBE - Di 26.12.06 13:58
Kannst Du mal kurz sagen, was GetLastError meldet? Bitte vor dem GetCurrentThread-Aufruf mit SetLastError auf 0 setzen, da die VCL häufig genug auch Fehlercodes ignoriert ...
Heiko - So 28.12.08 21:56
Um den Thread wieder auszugraben: GetLastError liefert 0 zurück und der Wert ist nicht MaxCardinal sondern -2 als Cardinal dargestellt.
Ich frage mich gerade nur: soll "pseudo handle" heißen, dass es nicht zum empfangen von Nachrichten geeignet ist, oder wie soll man es interpretieren?
Oder wie würdet ihr Messages im Thread empfangen?
jaenicke - So 28.12.08 22:19
Ich würde einfach TThread benutzen. ;-)
Dort kannst du z.B. die WndProc überschreiben. Und das Handle hast du auch direkt.
delfiphan - So 28.12.08 22:23
GetCurrentThreadId vielleicht? Ob das dem entspricht, was du suchst, weiss ich jetzt nicht. Ist jedenfalls eine systemweit eindeutige Id.
Heiko - So 28.12.08 22:25
delfiphan hat folgendes geschrieben : |
GetCurrentThreadId vielleicht? Ob das dem Handle entspricht weiss ich nicht. Ist jedenfalls eine systemweit eindeutige Id. |
Leider nein. Die Werte sind verschieden, die da herauskommen.
@TThread: Mal schauen, wie die das gemacht haben.
Delete - So 28.12.08 22:48
Versuch mal THandle als Datentyp zu nehmen. Das ist ein Cardinal in Delphi.
C#-Quelltext
1:
| HANDLE WINAPI GetCurrentThread(void); |
Und was ein Pseudohandle ist, wird in der Hilfe auch erklärt:
Zitat: |
A pseudo handle is a special constant that is interpreted as the current thread handle. The calling thread can use this handle to specify itself whenever a thread handle is required. |
Moderiert von
Narses: C in CS-Tag gewandelt
Heiko - So 28.12.08 22:59
Luckie hat folgendes geschrieben : |
Versuch mal THandle als Datentyp zu nehmen. Das ist ein Cardinal in Delphi.
[c]HANDLE WINAPI GetCurrentThread(void);[/c] |
THandle ist auch nur ein Cardinal, von daher ist es wurscht, solange 32Bit 32Bit sind ;).
Luckie hat folgendes geschrieben : |
Und was ein Pseudohandle ist, wird in der Hilfe auch erklärt: |
Äh ja: ich verstehe es so, dass es damals selber an sich arbeiten kann (komischer Ausdruck, ich weiß ;) ) - aber es klingt für mich so, als ob es ein anderes Handle sein könnte als das, worüber es von außen zu erreichen ist.
Heiko - Di 30.12.08 00:00
ICh habe mir jetzt mal TThread genauer angeschaut, also wie die es dort geregelt haben. Die übergeben einfach beim erzeugen die eigene Klasse und kommen so an das Handle ran.
Nun ich habe es ebenso gemacht, allerdings empfängt er nix auf dem Handle. Habe ich einen Fehler drin oder ist das Handle einfach nicht dafür geeignet?
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: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64:
| unit DanSo;
interface
uses Windows,
DanSo_Messages,
fmod;
type TDanSoPlayer = class(TObject) private FHandle: THandle; public constructor Create; procedure WndProc; destructor Destroy; override; end;
implementation
function DanSoPlayerThread(DanSoPlayer: TDanSoPlayer): Integer; begin DanSoPlayer.WndProc; Result:=0; end;
constructor TDanSoPlayer.Create; var ThreadID: Cardinal; begin FHandle:=BeginThread(nil, 0, @DanSoPlayerThread, Pointer(Self), 0, ThreadID); end;
destructor TDanSoPlayer.Destroy; begin SendMessage(FHandle, WM_DanSo_Destroy, 0, 0); WaitForSingleObject(FHandle, INFINITE); if FHandle <> 0 then CloseHandle(FHandle); end;
procedure TDanSoPlayer.WndProc; var msg: tagMSG; begin while GetMessageW(msg, FHandle, 0, 0) do begin case msg.message of WM_DanSo_Destroy: begin break; end; end; TranslateMessage(msg); DispatchMessageW(msg); end; end;
end. |
@Luckie: THandle=Cardinal - ich hab nochmal nachgeschaut ;)
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2025 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!