Entwickler-Ecke

Dateizugriff - Frage zu FAQ-Beitrag: Windows-/System-Verzeichnis ermitteln


JayK - So 31.07.05 20:09
Titel: Frage zu FAQ-Beitrag: Windows-/System-Verzeichnis ermitteln
Hallo,

user profile iconTino hat folgendes geschrieben:
In manchen Fällen benötigt man das Windows- und/oder das Systemverzeichnis. Mit den folgenden Funktionen bekommt man diese Verzeichnisse als String zurück:

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:
function GetWinDir: String
const 
  UNLEN = MAX_PATH; 
var 
  Size: DWORD; 
begin 
  Size := UNLEN + 1
  SetLength (Result, Size); 
  if GetWindowsDirectory (PChar (Result), Size) <> 0 then 
    SetLength (Result, StrLen (PChar (Result)))
  else 
    Result := ''
end

function GetSysDir: String
const 
  UNLEN = MAX_PATH; 
var 
  Size: DWORD; 
begin 
  Size := UNLEN + 1
  SetLength (Result, Size); 
  if GetSystemDirectory (PChar (Result), Size) <> 0 then 
    SetLength (Result, StrLen (PChar (Result)))
  else 
    Result := ''
end;


Bei mir wird der Bezeichner StrLen nicht gefunden und Tino hat auch keine uses-Klausel hingeschrieben :-(
Was muss ich da nun noch einbinden?

Schonmal Danke im vorraus,
JayK


AXMD - So 31.07.05 20:12

Probier mal Windows und SysUtils aus. Ansonsten sollte das normale Length() auch gehen, oder nicht?

AXMD


JayK - So 31.07.05 20:36

user profile iconAXMD hat folgendes geschrieben:
Ansonsten sollte das normale Length() auch gehen, oder nicht?

Ja. Tut es. :-D Danke.

Fräge mich bloß, warum Tino dann nicht einfach Length() genommen hat??? :nixweiss:


SMO - So 31.07.05 20:55

user profile iconJayK hat folgendes geschrieben:
Fräge mich bloß, warum Tino dann nicht einfach Length() genommen hat??? :nixweiss:

StrLen (aus der Unit SysUtils) ist für PChars gedacht, wogegen Length für normale Delphi Strings ist. Wenn man nun Length auf einen PChar anwendet, erzeugt der Compiler Code, der den PChar erst in einen String konvertiert und dann von diesem die Länge ausliest. StrLen arbeitet direkt mit dem PChar und ist deshalb hier vorzuziehen, weil effizienter.


JayK - So 31.07.05 21:43

Oha! Na dann änder ich das mal zurück und binde in der Unit die SysUtils ein...


SMO - So 31.07.05 22:29

Naja, bei so einer unkritischen Funktion fällt das gar nicht ins Gewicht. Da müsste man GetWinDir schon millionenmal aufrufen. :lol:

Noch effizienter wäre übrigens diese Implementierung:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
function GetWinDir: string;
var
  Size: UINT;
begin
  Size := GetWindowsDirectory(nil0);  // Benötigte Puffergröße ermitteln
  if Size > 0 then
  begin
    SetLength(Result, Size - 1);
    GetWindowsDirectory (PChar(Result), Size);
  end
  else
    Result := '';
end;

Statt erstmal Speicher für MAX_PATH+1 Zeichen anzufordern und kurz darauf den Speicher auf die tatsächliche Länge zu korrigieren, wird Result direkt auf die tatsächliche Länge gesetzt, welche vorher mit "GetWindowsDirectory(nil, 0)" ermittelt wurde.
"SetLength(Result, Size - 1)" mag auf den ersten Blick vielleicht seltsam erscheinen, geht aber problemlos. Jedenfalls mit der gegenwärtigen Implementierung von Delphi-Strings, weil sie immer zusätzlich ein #0 Zeichen am Ende hängen haben. ;)