Autor Beitrag
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19315
Erhaltene Danke: 1747

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Mo 29.11.10 21:37 
user profile iconnorics hat folgendes geschrieben Zum zitierten Posting springen:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
function TForm1.GetUser: String;
 var CompName : Array [1..20of Char;
     SizeD : DWord;
     i:Integer;
 begin
 SizeD := 15;
 GetUserName( @CompName, SizeD );
   begin
   Result := '';
   for I := 1 to Length(CompName) do
     if CompName[i] <> #0 then Result := Result + CompName[i] ;
   end;
 result:=CompName;
 end;
:autsch:
Da kannst du dir die Schleife auch komplett sparen...
Außerdem ist Length(CompName) durch das feste Array eh immer gleich. Warum du ein Array der Länge 20 definierst und dann als Größe 15 übergibst, ist mir allerdings ein Rätsel.

Außerdem ist die maximale Länge UNLEN als 255 oder so definiert...

Jedenfalls schau dir doch bitte einmal die Dokumentation an... Du bekommst die Anzahl der Zeichen schließlich auf dem Silbertablett.
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Mo 29.11.10 21:51 
Ein feste Buffergröße festzulegen ist schlecht. Du sagst ja selber, dass du nicht weißt, wie groß er sein muss.

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
function GetCurrUserName: string;
var
  Size              : DWORD;
begin
  Size := MAX_COMPUTERNAME_LENGTH + 1;
  SetLength(Result, Size);
  if GetUserName(PChar(Result), Size) then
    SetLength(Result, Size)
  else
    Result := '';
end;

Und am Ende gegeben falls noch Trim aufrufen um unnötige Steuerzeichen zu entfernen.
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19315
Erhaltene Danke: 1747

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Mo 29.11.10 21:54 
user profile iconLuckie hat folgendes geschrieben Zum zitierten Posting springen:
ausblenden Delphi-Quelltext
1:
2:
  if GetUserName(PChar(Result), Size) then
    SetLength(Result, Size)
Nicht ganz, da bist du auf genau das reingefallen, was glaube ich du mal in der DP gepostet hattest. ;-)
Dass nämlich beim Computernamen in der Größenangabe das Nullzeichen nicht dabei ist, hier aber schon. Also:
ausblenden Delphi-Quelltext
1:
SetLength(Result, Size - 1)					
;-)
Und dann kann man sich das Trim auch sparen.
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Mo 29.11.10 22:05 
Hm, dann muss ich meine Funktion in meinem Archiv mal überprüfen.
delphi10
ontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic star
Beiträge: 447
Erhaltene Danke: 2

W2K, XP, Vista64, Win7 64
RAD-Studio 2010
BeitragVerfasst: Mo 29.11.10 23:20 
user profile iconnorics hat folgendes geschrieben Zum zitierten Posting springen:
Hallo Zusammen,

ich möchte mir gerne meinen Dateinamen aus verschiedenen Kriterien zusammen bauen. In meinem Fall ist es der UserName und eine Auswahl aus der Listbox. Es wird nur der GetUser angezeigt. Wenn ich den GetUser weglasse, wird der Rest korrekt übernommen. Beides zusammen geht nicht.

(GetUser+'_'+IntToStr(ds[listbox1.itemindex+1].lfdnr)+'.txt');

Hat jemand eine Idee?

Viele Grüsse


Versuch das mal:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
// Result enthält den Usernamen + #0
// also Result := GetUser;
If Result[length(Result)+1] = #0 then
 Result := copy(Result,1,length(Result)-1);
 Showmessage(Result+'_'+IntToStr(ds[listbox1.itemindex+1].lfdnr)+'.txt');

Gruß delphi10

_________________
Salus populi suprema lex esto
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Mo 29.11.10 23:28 
Ihr macht mich noch wahnsinnig. Warum versucht ihr krampfhaft Trim nicht zu verwenden, sondern entwickelt andauernd eure eigenen frickel Lösungen?
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19315
Erhaltene Danke: 1747

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Di 30.11.10 00:16 
user profile icondelphi10 hat folgendes geschrieben Zum zitierten Posting springen:
// Result enthält den Usernamen + #0
Aber auch nur, wenn man die API-Funktion falsch benutzt. :roll:
Siehe oben...

user profile iconLuckie hat folgendes geschrieben Zum zitierten Posting springen:
Warum versucht ihr krampfhaft Trim nicht zu verwenden, sondern entwickelt andauernd eure eigenen frickel Lösungen?
Im Nachhinein Trim zu verwenden, weil man die Funktion falsch aufruft, ist aber auch nicht gerade sauber.

Deshalb hier einmal die laut Dokumentation korrekte Variante:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
function GetCurrUserName: string;
const
  UNLEN = 256;
var
  BufferSize: DWORD;
begin
  BufferSize := UNLEN + 1;
  SetLength(Result, BufferSize);
  if GetUserName(PChar(Result), BufferSize) then
    SetLength(Result, BufferSize - 1)
  else
    Result := '';
end;
Damit funktioniert es auch korrekt.

@user profile iconLuckie: MAX_COMPUTERNAME_LENGTH ist die falsche Konstante. Benutzernamen können durchaus länger als 15 Zeichen sein. UNLEN als Maximallänge ist in der API als 256 definiert.
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Di 30.11.10 00:25 
Ächtz, langsam wird es peinlich. Ist irgendwo ein Schreibtisch in der Nähe zum darunter Kriechen? :roll:
delphi10
ontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic star
Beiträge: 447
Erhaltene Danke: 2

W2K, XP, Vista64, Win7 64
RAD-Studio 2010
BeitragVerfasst: Di 30.11.10 00:39 
user profile iconjaenicke hat folgendes geschrieben Zum zitierten Posting springen:
user profile icondelphi10 hat folgendes geschrieben Zum zitierten Posting springen:
// Result enthält den Usernamen + #0
Aber auch nur, wenn man die API-Funktion falsch benutzt. :roll:
Siehe oben...
Deshalb hier einmal die laut Dokumentation korrekte Variante:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
function GetCurrUserName: string;
const
  UNLEN = 256;
var
  BufferSize: DWORD;
begin
  BufferSize := UNLEN + 1;
  SetLength(Result, BufferSize);
  if GetUserName(PChar(Result), BufferSize) then
    SetLength(Result, BufferSize - 1)
  else
    Result := '';
end;
Damit funktioniert es auch korrekt.

Wieso falsch benutzt? Die API kann man nur so aufrufen, wie du es beschrieben hast. Das Ergebnis muss, will man die null weghaben, immer nachbehandelt werden. Deine Version ist allerdings eleganter.

_________________
Salus populi suprema lex esto
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Di 30.11.10 02:08 
OK, hier ist die korrigierte Funktion:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
function GetCurrentUserName: string;
const
  UNLEN = 256;
var
  Size              : DWORD;
begin
  Size := UNLEN + 1;
  SetLength(Result, Size);
  if GetUserName(PChar(Result), Size) then
    SetLength(Result, Size - 1)
  else
    raise Exception.Create(SysErrorMessage(GetLastError));
end;
Gerd Kayser
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 632
Erhaltene Danke: 121

Win 7 32-bit
Delphi 2006/XE
BeitragVerfasst: Di 30.11.10 09:46 
user profile iconnorics hat folgendes geschrieben Zum zitierten Posting springen:
Ich sehe noch nicht wo der Unterschied liegt
So gehts auch:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
function TForm1.GetUser: string;
var
  Buffer  : array [0..256of char;
  Groesse : DWord;
begin
  Groesse := SizeOf(Buffer);
  GetUserName(Buffer, Groesse);
  Result := Buffer;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  ShowMessage(GetUser + '_' + IntToStr(ListBox1.ItemIndex + 1) + '.txt');
end;
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Di 30.11.10 12:32 
Der Unterschied liegt darin, dass ich das Ergebnis auf die tatsächliche Größe zu recht stutze und so verhindere, dass noch Müll mit ausgeliefert wird. Außerdem habe ich einer Fehlerbehandlung, die eine Exception wirft, wenn was schief geht. Bei dir würde einfach Müll zurückgegeben.

Für diesen Beitrag haben gedankt: jaenicke
Gerd Kayser
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 632
Erhaltene Danke: 121

Win 7 32-bit
Delphi 2006/XE
BeitragVerfasst: Di 30.11.10 18:05 
user profile iconLuckie hat folgendes geschrieben Zum zitierten Posting springen:
Der Unterschied liegt darin, dass ich das Ergebnis auf die tatsächliche Größe zu recht stutze und so verhindere, dass noch Müll mit ausgeliefert wird. Außerdem habe ich einer Fehlerbehandlung, die eine Exception wirft, wenn was schief geht. Bei dir würde einfach Müll zurückgegeben.
Da liegst Du aber falsch.
1. Durch "Result := Buffer;" werden nur die relevanten Bytes ohne #0 übertragen.
2. Das Array of Char hat als erstes Zeichen ein #0. Wird GetUserName z. B. mit Groesse = 3 aufgerufen, obwohl der Name länger ist, dann bleibt das Array mit der #0 als erstem Zeichen unverändert. Nur der Wert der Variablen Groesse ändert sich. Result ist dann ein LeerString, enthält also auch in diesem Fall keinen Müll.
3. Wenn der Buffer 256 Bytes groß sein soll (siehe UNLEN), das Array auch mindestens so groß ist (in meinem Beispiel 257 Bytes), die Groesse richtig an die Funktion übermittelt wird, was soll dann schief gehen? Wenn trotz richtigem Aufruf etwas dennoch schief laufen sollte, hat der Anwender wohl ein größeres Problem, das aber nicht an der Anwendung liegt, sondern wohl eher an Windows. Man kann sich auch zu Tode prüfen.
bummi
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 1248
Erhaltene Danke: 187

XP - Server 2008R2
D2 - Delphi XE
BeitragVerfasst: Di 30.11.10 18:21 
da bin ich froh daß meine 10 Jahre alte Funktion bis XE durchgehalten hat.
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
Function Get_UserName:String;
var
  p:Pchar;
  dw:Dword;
begin
  dw:=255;
  p:=stralloc(dw);
  GetUsername(p,dw);
  Result:=StrPas(p);
  strdispose(p);
end;

_________________
Das Problem liegt üblicherweise zwischen den Ohren H₂♂
DRY DRY KISS