Einzelnen Beitrag anzeigen

Benutzerbild von Neutral General
Neutral General

Registriert seit: 16. Jan 2004
Ort: Bendorf
5.219 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#2

AW: Verknüpfung mit WinApi ?

  Alt 23. Sep 2014, 14:40
Hallo,

PChar/PWideChars sind quasi nur Strings.

Delphi-Quellcode:
procedure TForm3.Button1Click(Sender: TObject);
begin
  CreateSymbolicLink('C:\Users\Benutzer\Desktop\Testlink.png', 'C:\Users\Benutzer\Pictures\Bild.png', 0);
end;
Das erzeugt eine Verknüpfung namens "Testlink.png" zur Datei "C:\Users\Benutzer\Pictures\Bild.png" auf dem Desktop. Falls du String-Variablen hast reicht normalerweise ein einfacher Cast auf PChar. Etwas komplizierter ist wenn die API dir einen String über einen PChar zurückgeben will:

Delphi-Quellcode:
procedure TForm3.Button1Click(Sender: TObject);
var Buffer: String;
    BufferArr: Array of Char;
    BuffSize: Cardinal;
begin
  BuffSize := 200; // Wir reservieren für die API 200 Zeichen

  // Per String
  SetLength(Buffer, BuffSize); // Speicher für 200 Zeichen reservieren
  GetUserName(@Buffer[1], BuffSize); // Der API wird der Pointer auf den Buffer und die Größe übergeben
  // Die API gibt in dem Fall über die BuffSize Variable die tatsächliche Länge des Benutzernamens zurück
  // Wir kürzen unseren String nun auf diese Länge
  SetLength(Buffer, BuffSize);
  // Fertig
  Caption := Buffer;

  // Per Char-Array
  SetLength(BufferArr, BuffSize);
  GetUserName(@BufferArr[0], BuffSize);
  SetLength(BufferArr, BuffSize);

  Caption := String(PChar(@BufferArr[0]));
end;
Geht natürlich auch mit statischen Arrays, nur dass du da natürlich kein SetLength benutzen kannst.

Wenn du das da oben verstanden hast und mal ein paar APIs aufgerufen hast bekommst du ein Gefühl dafür.
Das wichtige ist, dass du oft Speicher für die API reservieren musst wie oben bei GetUsername. Wenn du den String "Buffer" übergibst ohne vorher mit SetLength den Speicher zu reservieren dann fliegt dir dein Programm um die Ohren.

Wie viel Speicher man im voraus reservieren sollte steht entweder auf MSDN oder man muss halt überlegen was man so von der API erwartet und einfach mal großzügig reservieren.
Meistens erhält man über einen Var-Parameter wie bei GetUsername oder über das Ergebnis der Funktion die tatsächlich von Windows gebrauchte/genutzte Größe.

Mir fallen grad 3 häufige Arten ein:

1)
Delphi-Quellcode:
// Buffer nachträglich auf tatsächliche Länge setzen der über den Var-Parameter BufferSize zurückkommt
ApiAufruf(@Buffer[0], BufferSize);
SetLength(Buffer, BufferSize);
2)
Delphi-Quellcode:
// Buffer nachträglich auf tatsächliche Länge setzen der über den Rückgabewert zurückkommt
RealBufferSize := ApiAufruf(@Buffer[0], BufferSize);
SetLength(Buffer, RealBufferSize);
3)
Delphi-Quellcode:
// 2 Aufrufe der API. Erst BufferSize abfragen, dann eigentlichen Aufruf machen
ApiAufruf(nil, RealBufferSize);
SetLength(Buffer, RealBufferSize);
ApiAufruf(@Buffer[0], RealBufferSize);
Michael
"Programmers talk about software development on weekends, vacations, and over meals not because they lack imagination,
but because their imagination reveals worlds that others cannot see."

Geändert von Neutral General (23. Sep 2014 um 15:03 Uhr)
  Mit Zitat antworten Zitat