Biergeneral - So 20.04.08 19:27
Titel: Verständnisfrage EnumWindows (bzw. zur Callbackmethode)
Hallo,
ich hab gerade an einer Stelle EnumWindows verwenden müssen. Dabei ist ein für mich unverständliches Problem in der Callback-Methode aufgetaucht. Vielleicht kann mir einer erklären, warum das so wie ich es erst versucht hatte nicht funktioniert.
Zunächst mein erster Versuch:
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:
| function EnumProc(hwnd: Hwnd; List: TStrings) : boolean ; stdcall; var str: PAnsiChar; begin Result := Assigned(List); if Result then begin str := StrAlloc(GetWindowTextLength(hwnd)); try if GetWindowText(hwnd, str, Length(str)) > 0 then List.AddObject(str, TObject(hwnd)); finally strDispose(str); end; end; end;
procedure Machet; var strList: TStringList; begin strList := TStringList.Create; EnumWindows(@EnumProc, Integer(strList)); strList.Free; end; |
Dabei kommen jetzt nur unsinnige Strings raus und bei Mehrfach-Aufruf der Methode verändert sich die Ergebnismenge.
Wenn ich statt des PAnsiChars ne konstante Menge z.B. ein Array[0..256] of Char nehme klappt das Ganze problemlos. Aber den Sinn dahinter seh ich nicht.
Hat irgendwer ne Erklärung parat? :-D
Grüße
[Edit]
Mäh!!
Eigene Blödheit. Nach dem Abschicken ist es mir aufgefallen =)
nem
Length(str) is natürlich Quatsch bei nem String der mit StrAlloc alloziert wurde..
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21:
| function EnumProc(hwnd: Hwnd; List: TStrings) : boolean ; stdcall; var str: PAnsiChar; len: Integer; begin Result := Assigned(List); if Result then begin len := GetWindowTextLength(hwnd)+1; if (len > 1) then begin str := StrAlloc(len); try GetWindowText(hwnd, str, len); List.AddObject(str, TObject(hwnd)); finally strDispose(str); end; end; end; end; |
So funktionierts..
Biergeneral - So 20.04.08 20:34
Das StrDispose an der Stelle ist schon richtig. Ich alloziier mir ja kurzzeitig Speicher um da den WindowText reinzuschreiben.
Das Problem lag woanders.
Delphi-Quelltext
1: 2: 3: 4:
| var str: PAnsiChar; begin str := StrAlloc(10); |
Jetzt steht in str genau das drin, was and der Speicheradresse vorher stand.
Zu einer ziemlig hohen Wahrscheinlichkeit mindestens eine 0.
Also sieht str jetzt zum Beispiel so aus:
Delphi-Quelltext
1:
| Str = #0 #0 #2 #55 #123 #5 #5 #10 #10 #55 |
Jetzt hab ich Idiot folgendes gemacht :-D
Delphi-Quelltext
1:
| GetWindowText(handle, str, Length(str)); |
Und was macht Length(str) ? :-D
Nen implizierten Cast vom PAnsiChar zu AnsiString..
Jetzt passiert folgendes.
Die Methode zum Konvertieren findet direkt am Anfang den Char #0.
#0 ist das Stopp-Zeichen für nen Nullterminierten String.
Also was gibt Length(str) zurück? :-D Mit 99% Wahrscheinlichkeit ganz viel Unsinn :-)