Autor Beitrag
Biergeneral
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 35

WIN XP
Delphi 7 Ent., Delphi 2007 Ent., C/C++ (Eclipse)
BeitragVerfasst: So 20.04.08 19:27 
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:
ausblenden 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..

ausblenden 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..
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: So 20.04.08 20:12 
ausblenden Delphi-Quelltext
1:
strDispose(str);					

Du schmeißt ja auch alles gleich wieder weg oder täusche ich mich da?
Biergeneral Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 35

WIN XP
Delphi 7 Ent., Delphi 2007 Ent., C/C++ (Eclipse)
BeitragVerfasst: 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.

ausblenden Delphi-Quelltext
1:
2:
3:
4:
  var
    str: PAnsiChar;
  begin
    str := StrAlloc(10); //z.B. eine Länge von 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:
ausblenden Delphi-Quelltext
1:
  Str = #0 #0 #2 #55 #123 #5 #5 #10 #10 #55					


Jetzt hab ich Idiot folgendes gemacht :-D

ausblenden 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 :-)