Embarcadero Delphi - riptutorial.com · Inhaltsverzeichnis Über 1 Kapitel 1: Erste Schritte mit...

50
Embarcadero Delphi #delphi

Transcript of Embarcadero Delphi - riptutorial.com · Inhaltsverzeichnis Über 1 Kapitel 1: Erste Schritte mit...

Page 1: Embarcadero Delphi - riptutorial.com · Inhaltsverzeichnis Über 1 Kapitel 1: Erste Schritte mit Embarcadero Delphi 2 Bemerkungen 2 Versionen 2 Examples 3 Hallo Welt 3 Zeigen Sie

Embarcadero Delphi

#delphi

Page 2: Embarcadero Delphi - riptutorial.com · Inhaltsverzeichnis Über 1 Kapitel 1: Erste Schritte mit Embarcadero Delphi 2 Bemerkungen 2 Versionen 2 Examples 3 Hallo Welt 3 Zeigen Sie

Inhaltsverzeichnis

Über 1

Kapitel 1: Erste Schritte mit Embarcadero Delphi 2

Bemerkungen 2

Versionen 2

Examples 3

Hallo Welt 3

Zeigen Sie "Hello World" mithilfe der VCL 4

Show 'Hello World' mit WinAPI MessageBox 4

Plattformübergreifende Hello World mit FireMonkey 4

Kapitel 2: Aktualisierte TDataSet-Daten in einem Hintergrundthread abrufen 6

Bemerkungen 6

Examples 6

FireDAC-Beispiel 6

Kapitel 3: Andere Programme ausführen 9

Examples 9

CreateProcess 9

Kapitel 4: Animationen in Firemonkey verwenden 11

Examples 11

Rotierender Dreieck 11

Kapitel 5: Einen Thread ausführen, während die GUI ansprechend bleibt 12

Examples 12

Responsive GUI mit Threads für die Hintergrundarbeit und PostMessage zum Berichten von Thr 12

Faden 12

Bilden 14

Kapitel 6: Für Loops 16

Syntax 16

Bemerkungen 16

Examples 16

Einfach für die Schleife 16

Zeichen einer Zeichenfolge durchlaufen 17

Page 3: Embarcadero Delphi - riptutorial.com · Inhaltsverzeichnis Über 1 Kapitel 1: Erste Schritte mit Embarcadero Delphi 2 Bemerkungen 2 Versionen 2 Examples 3 Hallo Welt 3 Zeigen Sie

Umkehrung der Schleife 17

Für eine Schleife mit einer Aufzählung 18

Für in Reihe 18

Kapitel 7: Generics 20

Examples 20

Sortieren Sie ein dynamisches Array mit dem generischen TArray.Sort 20

Einfache Verwendung von TList 20

Absteigend von TList es spezifisch machen 20

Sortieren Sie eine TList 21

Kapitel 8: Leicht entfernbare Laufzeitfehlerprüfungen erstellen 22

Einführung 22

Examples 22

Triviales Beispiel 22

Kapitel 9: Schleifen 24

Einführung 24

Syntax 24

Examples 24

Brechen Sie in Loops und fahren Sie fort 24

Wiederhole bis 25

Während tun 25

Kapitel 10: Schnittstellen 27

Bemerkungen 27

Examples 27

Schnittstelle definieren und implementieren 27

Implementierung mehrerer Schnittstellen 28

Vererbung für Schnittstellen 28

Eigenschaften in Schnittstellen 29

Kapitel 11: TStringList-Klasse 31

Examples 31

Einführung 31

Schlüsselwertpaarung 31

Kapitel 12: Verwendung von RTTI in Delphi 34

Page 4: Embarcadero Delphi - riptutorial.com · Inhaltsverzeichnis Über 1 Kapitel 1: Erste Schritte mit Embarcadero Delphi 2 Bemerkungen 2 Versionen 2 Examples 3 Hallo Welt 3 Zeigen Sie

Einführung 34

Bemerkungen 34

Examples 34

Grundlegende Klasseninformationen 34

Kapitel 13: Verwendung von try außer und zum Schluss 36

Syntax 36

Examples 36

Einfaches try..finally Beispiel, um Speicherlecks zu vermeiden 36

Ausnahmesichere Rückgabe eines neuen Objekts 36

Try-endlich verschachtelt in Try-Exceptions 37

Try-Ausnahme verschachtelt in Try-finally 37

Try-finally mit 2 oder mehr Objekten 38

Kapitel 14: Zeichenketten 39

Examples 39

String-Typen 39

Zeichenketten 39

Zeichen 40

Groß-und Kleinschreibung 40

Zuordnung 40

Referenzzählung 41

Kodierungen 41

Kapitel 15: Zeitintervallmessung 43

Examples 43

Verwenden der Windows-API GetTickCount 43

TStopwatch-Datensatz verwenden 43

Credits 45

Page 5: Embarcadero Delphi - riptutorial.com · Inhaltsverzeichnis Über 1 Kapitel 1: Erste Schritte mit Embarcadero Delphi 2 Bemerkungen 2 Versionen 2 Examples 3 Hallo Welt 3 Zeigen Sie

Über

You can share this PDF with anyone you feel could benefit from it, downloaded the latest version from: embarcadero-delphi

It is an unofficial and free Embarcadero Delphi ebook created for educational purposes. All the content is extracted from Stack Overflow Documentation, which is written by many hardworking individuals at Stack Overflow. It is neither affiliated with Stack Overflow nor official Embarcadero Delphi.

The content is released under Creative Commons BY-SA, and the list of contributors to each chapter are provided in the credits section at the end of this book. Images may be copyright of their respective owners unless otherwise specified. All trademarks and registered trademarks are the property of their respective company owners.

Use the content presented in this book at your own risk; it is not guaranteed to be correct nor accurate, please send your feedback and corrections to [email protected]

https://riptutorial.com/de/home 1

Page 6: Embarcadero Delphi - riptutorial.com · Inhaltsverzeichnis Über 1 Kapitel 1: Erste Schritte mit Embarcadero Delphi 2 Bemerkungen 2 Versionen 2 Examples 3 Hallo Welt 3 Zeigen Sie

Kapitel 1: Erste Schritte mit Embarcadero Delphi

Bemerkungen

Delphi ist eine Universalsprache, die auf einem Object Pascal-Dialekt basiert, dessen Wurzeln von Borland Turbo Pascal stammen. Es wird mit einer eigenen IDE geliefert, die die schnelle Anwendungsentwicklung (RAD) unterstützt.

Es ermöglicht die plattformübergreifende native (kompilierte) Anwendungsentwicklung aus einer einzigen Codebasis. Derzeit werden folgende Plattformen unterstützt: Windows, OSX, iOS und Android.

Es gibt zwei visuelle Rahmenbedingungen:

VCL: Visual Component Library, die speziell für die Windows-Entwicklung entwickelt wurde und native Steuerelemente von Windows umschließt.

FMX: FireMonkey-Plattformübergreifendes Framework für alle unterstützten Plattformen•

Versionen

AusführungNumerische Version

Produktname Veröffentlichungsdatum

1 1,0 Borland Delphi 1995-02-14

2 2,0 Borland Delphi 2 1996-02-10

3 3,0 Borland Delphi 3 1997-08-05

4 4,0 Borland Delphi 4 1998-07-17

5 5,0 Borland Delphi 5 1999-08-10

6 6,0 Borland Delphi 6 2001-05-21

7 7,0 Borland Delphi 7 2002-08-09

8 8,0 Borland Delphi 8 für .NET 2003-12-22

2005 9,0 Borland Delphi 2005 2004-10-12

2006 10,0 Borland Delphi 2006 2005-11-23

2007 11,0 CodeGear Delphi 2007 2007-03-16

https://riptutorial.com/de/home 2

Page 7: Embarcadero Delphi - riptutorial.com · Inhaltsverzeichnis Über 1 Kapitel 1: Erste Schritte mit Embarcadero Delphi 2 Bemerkungen 2 Versionen 2 Examples 3 Hallo Welt 3 Zeigen Sie

AusführungNumerische Version

Produktname Veröffentlichungsdatum

2009 12,0 CodeGear Delphi 2009 2008-08-25

2010 14,0Embarcadero RAD Studio 2010

2009-08-15

XE 15,0Embarcadero RAD Studio XE

2010-08-30

XE2 16,0Embarcadero RAD Studio XE2

2011-09-02

XE3 17,0Embarcadero RAD Studio XE3

2012-09-03

XE4 18,0Embarcadero RAD Studio XE4

2013-04-22

XE5 19,0Embarcadero RAD Studio XE5

2013-09-11

XE6 20,0Embarcadero RAD Studio XE6

2014-04-15

XE7 21,0Embarcadero RAD Studio XE7

2014-09-02

XE8 22,0Embarcadero RAD Studio XE8

2015-04-07

10 Seattle 23,0Embarcadero RAD Studio 10 Seattle

2015-08-31

10.1 Berlin 24,0Embarcadero RAD Studio 10.1 Berlin

2016-04-20

10.2 Tokio 25,0Embarcadero RAD Studio 10.2 Tokio

2017-03-22

Examples

Hallo Welt

Dieses Programm, das in einer Datei mit dem Namen HelloWorld.dpr gespeichert ist, wird in eine Konsolenanwendung übersetzt, die "Hello World" an die Konsole druckt:

https://riptutorial.com/de/home 3

Page 8: Embarcadero Delphi - riptutorial.com · Inhaltsverzeichnis Über 1 Kapitel 1: Erste Schritte mit Embarcadero Delphi 2 Bemerkungen 2 Versionen 2 Examples 3 Hallo Welt 3 Zeigen Sie

program HelloWorld; {$APPTYPE CONSOLE} begin WriteLn('Hello World'); end.

Zeigen Sie "Hello World" mithilfe der VCL

Dieses Programm verwendet VCL, die standardmäßige UI-Komponentenbibliothek von Delphi, um "Hello World" in ein Meldungsfeld zu drucken. Die VCL umschließt die meisten häufig verwendeten WinAPI-Komponenten. Auf diese Weise können sie viel einfacher verwendet werden, z. B. ohne dass Sie mit Fenstergriffen arbeiten müssen.

Um eine Abhängigkeit aufzunehmen (wie in diesem Fall Vcl.Dialogs ), fügen Sie den uses einschließlich einer durch Kommas getrennten Liste von Einheiten hinzu, die mit einem Semikolon enden.

program HelloWindows; uses Vcl.Dialogs; begin ShowMessage('Hello Windows'); end.

Show 'Hello World' mit WinAPI MessageBox

Dieses Programm verwendet die Windows-API (WinAPI), um "Hello World" in ein Meldungsfeld zu drucken.

Um eine Abhängigkeit aufzunehmen (wie in diesem Fall Windows ), fügen Sie den Anwendungsblock einschließlich einer durch Kommas getrennten Liste von Einheiten hinzu, die mit einem Semikolon enden.

program HelloWorld; uses Windows; begin MessageBox(0, 'Hello World!', 'Hello World!', 0); end.

Plattformübergreifende Hello World mit FireMonkey

XE2

program CrossPlatformHelloWorld;

https://riptutorial.com/de/home 4

Page 9: Embarcadero Delphi - riptutorial.com · Inhaltsverzeichnis Über 1 Kapitel 1: Erste Schritte mit Embarcadero Delphi 2 Bemerkungen 2 Versionen 2 Examples 3 Hallo Welt 3 Zeigen Sie

uses FMX.Dialogs; {$R *.res} begin ShowMessage('Hello world!'); end.

Die meisten von Delphi unterstützten Plattformen (Win32 / Win64 / OSX32 / Android32 / iOS32 / iOS64) unterstützen auch eine Konsole, sodass das WriteLn Beispiel gut zu ihnen passt.

Für die Plattformen, für die eine GUI erforderlich ist (jedes iOS-Gerät und einige Android-Geräte), funktioniert das obige FireMonkey-Beispiel gut.

Erste Schritte mit Embarcadero Delphi online lesen: https://riptutorial.com/de/delphi/topic/599/erste-schritte-mit-embarcadero-delphi

https://riptutorial.com/de/home 5

Page 10: Embarcadero Delphi - riptutorial.com · Inhaltsverzeichnis Über 1 Kapitel 1: Erste Schritte mit Embarcadero Delphi 2 Bemerkungen 2 Versionen 2 Examples 3 Hallo Welt 3 Zeigen Sie

Kapitel 2: Aktualisierte TDataSet-Daten in einem Hintergrundthread abrufen

Bemerkungen

Dieses FireDAC-Beispiel und die anderen, die ich einreichen möchte, vermeiden die Verwendung nativer Aufrufe zum asynchronen Öffnen der Datenmenge.

Examples

FireDAC-Beispiel

Das folgende Codebeispiel zeigt eine Möglichkeit, Datensätze von einem MSSQL-Server in einem Hintergrundthread mithilfe von FireDAC abzurufen. Getestet für Delphi 10 Seattle

Wie geschrieben:

Der Thread ruft Daten mit seiner eigenen TFDConnection und TFDQuery ab und überträgt die Daten in einem Aufruf von Sychronize () an die FDQuery des Formulars.

Die Ausführung ruft die Daten nur einmal ab. Es kann geändert werden, um die Abfrage wiederholt als Antwort auf eine vom VCL-Thread bereitgestellte Nachricht auszuführen.

Code:

type TForm1 = class; TFDQueryThread = class(TThread) private FConnection: TFDConnection; FQuery: TFDQuery; FForm: TForm1; published constructor Create(AForm : TForm1); destructor Destroy; override; procedure Execute; override; procedure TransferData; property Query : TFDQuery read FQuery; property Connection : TFDConnection read FConnection; property Form : TForm1 read FForm; end; TForm1 = class(TForm) FDConnection1: TFDConnection; FDQuery1: TFDQuery; DataSource1: TDataSource; DBGrid1: TDBGrid; DBNavigator1: TDBNavigator; Button1: TButton;

https://riptutorial.com/de/home 6

Page 11: Embarcadero Delphi - riptutorial.com · Inhaltsverzeichnis Über 1 Kapitel 1: Erste Schritte mit Embarcadero Delphi 2 Bemerkungen 2 Versionen 2 Examples 3 Hallo Welt 3 Zeigen Sie

procedure FormDestroy(Sender: TObject); procedure Button1Click(Sender: TObject); procedure FormCreate(Sender: TObject); private public QueryThread : TFDQueryThread; end; var Form1: TForm1; implementation {$R *.dfm} { TFDQueryThread } constructor TFDQueryThread.Create(AForm : TForm1); begin inherited Create(True); FreeOnTerminate := False; FForm := AForm; FConnection := TFDConnection.Create(Nil); FConnection.Params.Assign(Form.FDConnection1.Params); FConnection.LoginPrompt := False; FQuery := TFDQuery.Create(Nil); FQuery.Connection := Connection; FQuery.SQL.Text := Form.FDQuery1.SQL.Text; end; destructor TFDQueryThread.Destroy; begin FQuery.Free; FConnection.Free; inherited; end; procedure TFDQueryThread.Execute; begin Query.Open; Synchronize(TransferData); end; procedure TFDQueryThread.TransferData; begin Form.FDQuery1.DisableControls; try if Form.FDQuery1.Active then Form.FDQuery1.Close; Form.FDQuery1.Data := Query.Data; finally Form.FDQuery1.EnableControls; end; end; procedure TForm1.FormDestroy(Sender: TObject); begin QueryThread.Free; end;

https://riptutorial.com/de/home 7

Page 12: Embarcadero Delphi - riptutorial.com · Inhaltsverzeichnis Über 1 Kapitel 1: Erste Schritte mit Embarcadero Delphi 2 Bemerkungen 2 Versionen 2 Examples 3 Hallo Welt 3 Zeigen Sie

procedure TForm1.Button1Click(Sender: TObject); begin if not QueryThread.Finished then QueryThread.Start else ShowMessage('Thread already executed!'); end; procedure TForm1.FormCreate(Sender: TObject); begin FDQuery1.Open; QueryThread := TFDQueryThread.Create(Self); end; end.

Aktualisierte TDataSet-Daten in einem Hintergrundthread abrufen online lesen: https://riptutorial.com/de/delphi/topic/4114/aktualisierte-tdataset-daten-in-einem-hintergrundthread-abrufen

https://riptutorial.com/de/home 8

Page 13: Embarcadero Delphi - riptutorial.com · Inhaltsverzeichnis Über 1 Kapitel 1: Erste Schritte mit Embarcadero Delphi 2 Bemerkungen 2 Versionen 2 Examples 3 Hallo Welt 3 Zeigen Sie

Kapitel 3: Andere Programme ausführen

Examples

CreateProcess

Die folgende Funktion kapselt Code für die Verwendung von CreateProcess Windows API zum Starten anderer Programme.

Es ist konfigurierbar und kann warten, bis der aufrufende Prozess abgeschlossen ist oder sofort zurückkehrt.

Parameter:

FileName - vollständiger Pfad zur ausführbaren Datei•Params - Befehlszeilenparameter oder leere Zeichenfolge verwenden•Folder - Arbeitsordner für das aufgerufene Programm - wenn aus FileName leerer Pfad extrahiert FileName

WaitUntilTerminated - wenn die Funktion true wartet, bis der Prozess die Ausführung beendet hat

WaitUntilIdle - Wenn die Funktion true die Funktion WaitForInputIdle aufruft , und warten, bis der angegebene Prozess die Verarbeitung seiner ursprünglichen Eingabe abgeschlossen hat und keine Benutzereingaben vorliegen

RunMinimized - wenn der Prozess "True" minimiert ausgeführt wird•ErrorCode - Wenn die Funktion fehlschlägt, enthält sie den gefundenen Windows-Fehlercode•

function ExecuteProcess(const FileName, Params: string; Folder: string; WaitUntilTerminated, WaitUntilIdle, RunMinimized: boolean; var ErrorCode: integer): boolean; var CmdLine: string; WorkingDirP: PChar; StartupInfo: TStartupInfo; ProcessInfo: TProcessInformation; begin Result := true; CmdLine := '"' + FileName + '" ' + Params; if Folder = '' then Folder := ExcludeTrailingPathDelimiter(ExtractFilePath(FileName)); ZeroMemory(@StartupInfo, SizeOf(StartupInfo)); StartupInfo.cb := SizeOf(StartupInfo); if RunMinimized then begin StartupInfo.dwFlags := STARTF_USESHOWWINDOW; StartupInfo.wShowWindow := SW_SHOWMINIMIZED; end; if Folder <> '' then WorkingDirP := PChar(Folder) else WorkingDirP := nil; if not CreateProcess(nil, PChar(CmdLine), nil, nil, false, 0, nil, WorkingDirP, StartupInfo, ProcessInfo) then begin Result := false;

https://riptutorial.com/de/home 9

Page 14: Embarcadero Delphi - riptutorial.com · Inhaltsverzeichnis Über 1 Kapitel 1: Erste Schritte mit Embarcadero Delphi 2 Bemerkungen 2 Versionen 2 Examples 3 Hallo Welt 3 Zeigen Sie

ErrorCode := GetLastError; exit; end; with ProcessInfo do begin CloseHandle(hThread); if WaitUntilIdle then WaitForInputIdle(hProcess, INFINITE); if WaitUntilTerminated then repeat Application.ProcessMessages; until MsgWaitForMultipleObjects(1, hProcess, false, INFINITE, QS_ALLINPUT) <> WAIT_OBJECT_0 + 1; CloseHandle(hProcess); end; end;

Verwendung der obigen Funktion

var FileName, Parameters, WorkingFolder: string; Error: integer; OK: boolean; begin FileName := 'C:\FullPath\myapp.exe'; WorkingFolder := ''; // if empty function will extract path from FileName Parameters := '-p'; // can be empty OK := ExecuteProcess(FileName, Parameters, WorkingFolder, false, false, false, Error); if not OK then ShowMessage('Error: ' + IntToStr(Error)); end;

CreateProcess-Dokumentation

Andere Programme ausführen online lesen: https://riptutorial.com/de/delphi/topic/5180/andere-programme-ausfuhren

https://riptutorial.com/de/home 10

Page 15: Embarcadero Delphi - riptutorial.com · Inhaltsverzeichnis Über 1 Kapitel 1: Erste Schritte mit Embarcadero Delphi 2 Bemerkungen 2 Versionen 2 Examples 3 Hallo Welt 3 Zeigen Sie

Kapitel 4: Animationen in Firemonkey verwenden

Examples

Rotierender Dreieck

Erstellen Sie eine leere Multi-Device-Anwendung (Firemonkey).1. Drop Rechteck auf Formular.2. Im Objektinspektorfenster (F11) finden Sie RotationAngle. Klicken Sie auf die Dropdown-Schaltfläche und wählen Sie "Neue TFloatAnimation erstellen".

3.

Das Objektinspektorfenster wird automatisch auf eine neu hinzugefügte TFloatAnimation umgestellt. Sie können es auch im Strukturmenü anzeigen (Umschalttaste + Alt)

F11).•

4.

Füllzeit im Objektinspektor von TFloatAnimation mit einer beliebigen Anzahl (in Sekunden). In unserem Fall nehmen wir Folgendes: 1. Lassen Sie die StartValue-Eigenschaft unverändert, und geben Sie in StopValue den Typ - 360 (Grad, damit alles rund läuft). Wir können auch die Loop-Option aktivieren (diese Animation wird so lange durchlaufen, bis sie vom Code angehalten wird).

5.

Jetzt haben wir unsere Animation eingerichtet. Es bleibt nur noch, es einzuschalten: Lassen Sie zwei Schaltflächen auf das Formular fallen, rufen Sie zuerst "Start" und dann "Stop" an. in OnClick-Ereignis der ersten Schaltfläche schreiben:

FloatAnimation1.Start;

OnClick des zweiten Tastencodes:

FloatAnimation1.Stop;

Wenn Sie den Namen Ihrer TFloatAnimation geändert haben - Ändern Sie diesen auch, wenn Sie Start und Stop aufrufen.

Führen Sie nun Ihr Projekt aus, klicken Sie auf die Schaltfläche "Start" und genießen Sie es.

Animationen in Firemonkey verwenden online lesen: https://riptutorial.com/de/delphi/topic/5383/animationen-in-firemonkey-verwenden

https://riptutorial.com/de/home 11

Page 16: Embarcadero Delphi - riptutorial.com · Inhaltsverzeichnis Über 1 Kapitel 1: Erste Schritte mit Embarcadero Delphi 2 Bemerkungen 2 Versionen 2 Examples 3 Hallo Welt 3 Zeigen Sie

Kapitel 5: Einen Thread ausführen, während die GUI ansprechend bleibt

Examples

Responsive GUI mit Threads für die Hintergrundarbeit und PostMessage zum Berichten von Threads

Um eine GUI während eines langwierigen Prozesses reaktionsfähig zu halten, sind entweder sehr aufwendige "Rückrufe" erforderlich, um der GUI die Verarbeitung ihrer Nachrichtenwarteschlange zu ermöglichen, oder die Verwendung von (Hintergrund) (Worker) -Threads.

Es ist normalerweise kein Problem, eine beliebige Anzahl von Threads zu starten, um einige Arbeit zu erledigen. Der Spaß beginnt, wenn Sie die GUI Zwischen- und Endergebnisse anzeigen oder über den Fortschritt berichten möchten.

Das Anzeigen von Elementen in der GUI erfordert die Interaktion mit Steuerelementen und / oder der Nachrichtenwarteschlange / -pumpe. Dies sollte immer im Kontext des Hauptthreads erfolgen. Niemals im Zusammenhang mit einem anderen Thread.

Es gibt viele Möglichkeiten, damit umzugehen.

Dieses Beispiel zeigt, wie Sie dies mit einfachen Threads tun können. Dadurch kann die GUI auf die Thread-Instanz zugreifen, nachdem sie fertig ist, indem Sie FreeOnTerminate auf false und melden, wenn ein Thread mit PostMessage "fertig" PostMessage .

Hinweise zu den Rennbedingungen: Verweise auf die Arbeitsthreads werden im Formular in einem Array gespeichert. Wenn ein Thread abgeschlossen ist, wird die entsprechende Referenz im Array auf Null gesetzt.

Dies ist eine potenzielle Quelle für Rennbedingungen. Die Verwendung eines booleschen Typs "Running" erleichtert die Feststellung, ob noch Threads vorhanden sind, die abgeschlossen werden müssen.

Sie müssen entscheiden, ob Sie diese Ressource mit Sperren schützen müssen oder nicht.

In diesem Beispiel ist es so, wie es ist, keine Notwendigkeit. Sie werden nur an zwei Stellen geändert: der StartThreads Methode und der HandleThreadResults Methode. Beide Methoden laufen immer nur im Kontext des Hauptthreads. Solange Sie es auf diese Weise beibehalten und diese Methoden nicht aus dem Kontext verschiedener Threads aufrufen, gibt es für sie keine Möglichkeit, Race-Bedingungen zu erzeugen.

Faden

type

https://riptutorial.com/de/home 12

Page 17: Embarcadero Delphi - riptutorial.com · Inhaltsverzeichnis Über 1 Kapitel 1: Erste Schritte mit Embarcadero Delphi 2 Bemerkungen 2 Versionen 2 Examples 3 Hallo Welt 3 Zeigen Sie

TWorker = class(TThread) private FFactor: Double; FResult: Double; FReportTo: THandle; protected procedure Execute; override; public constructor Create(const aFactor: Double; const aReportTo: THandle); property Factor: Double read FFactor; property Result: Double read FResult; end;

Der Konstruktor setzt nur die privaten Mitglieder und setzt FreeOnTerminate auf False. Dies ist wichtig, da der Haupt-Thread die Thread-Instanz nach seinem Ergebnis abfragen kann.

Die Ausführungsmethode führt ihre Berechnung aus und sendet dann eine Nachricht an das Handle, das sie in ihrem Konstruktor erhalten hat, um zu sagen, dass sie fertig ist:

procedure TWorker.Execute; const Max = 100000000;var i : Integer; begin inherited; FResult := FFactor; for i := 1 to Max do FResult := Sqrt(FResult); PostMessage(FReportTo, UM_WORKERDONE, Self.Handle, 0); end;

Die Verwendung von PostMessage ist in diesem Beispiel unerlässlich. PostMessage "nur" eine Nachricht in die Warteschlange der Nachrichtenpumpe des Hauptthreads ein und wartet nicht darauf, dass sie verarbeitet wird. Es ist asynchron in der Natur. Wenn Sie SendMessage verwenden SendMessage , würden Sie sich selbst in eine Pickle codieren. SendMessage legt die Nachricht in die Warteschlange und wartet, bis sie verarbeitet wurde. Kurz gesagt, es ist synchron.

Die Deklarationen für die benutzerdefinierte UM_WORKERDONE-Nachricht werden wie folgt deklariert:

const UM_WORKERDONE = WM_APP + 1; type TUMWorkerDone = packed record Msg: Cardinal; ThreadHandle: Integer; unused: Integer; Result: LRESULT; end;

Die UM_WORKERDONE verwendet WM_APP als Ausgangspunkt für ihren Wert, um sicherzustellen, dass keine von Windows oder der Delphi-VCL (von MicroSoft empfohlen ) verwendeten Werte

https://riptutorial.com/de/home 13

Page 18: Embarcadero Delphi - riptutorial.com · Inhaltsverzeichnis Über 1 Kapitel 1: Erste Schritte mit Embarcadero Delphi 2 Bemerkungen 2 Versionen 2 Examples 3 Hallo Welt 3 Zeigen Sie

beeinträchtigt werden.

Bilden

Jedes Formular kann zum Starten von Threads verwendet werden. Sie müssen lediglich die folgenden Mitglieder hinzufügen:

private FRunning: Boolean; FThreads: array of record Instance: TThread; Handle: THandle; end; procedure StartThreads(const aNumber: Integer); procedure HandleThreadResult(var Message: TUMWorkerDone); message UM_WORKERDONE;

Oh, und der Beispielcode setzt die Existenz eines Memo1: TMemo; in den Deklarationen des Formulars, die es für "Protokollierung und Berichterstellung" verwendet.

Mit dem FRunning kann verhindert werden, dass die GUI während der Arbeit angeklickt wird. FThreads wird verwendet, um den Instanzzeiger und das Handle der erstellten Threads zu halten.

Die Prozedur zum Starten der Threads ist ziemlich unkompliziert. Es beginnt mit einer Prüfung, ob bereits ein Satz Threads gewartet wird. Wenn ja, wird es einfach beendet. Ist dies nicht der Fall, wird das Flag auf true gesetzt und die Threads werden mit einem eigenen Handle versehen, sodass sie wissen, wo sie ihre "Fertig" -Meldung posten sollen.

procedure TForm1.StartThreads(const aNumber: Integer); var i: Integer; begin if FRunning then Exit; FRunning := True; Memo1.Lines.Add(Format('Starting %d worker threads', [aNumber])); SetLength(FThreads, aNumber); for i := 0 to aNumber - 1 do begin FThreads[i].Instance := TWorker.Create(pi * (i+1), Self.Handle); FThreads[i].Handle := FThreads[i].Instance.Handle; end; end;

Das Handle des Threads wird auch in das Array eingefügt, weil wir dies in den Nachrichten erhalten, die uns sagen, dass ein Thread fertiggestellt ist. Wenn er sich außerhalb der Instanz des Threads befindet, ist der Zugriff etwas einfacher. Wenn das Handle außerhalb der Instanz des Threads verfügbar ist, können wir auch FreeOnTerminate auf True setzen, wenn die Instanz nicht benötigt wurde, um die Ergebnisse zu erhalten (z. B. wenn sie in einer Datenbank gespeichert wurden). In diesem Fall wäre es natürlich nicht nötig, einen Hinweis auf die Instanz zu führen.

https://riptutorial.com/de/home 14

Page 19: Embarcadero Delphi - riptutorial.com · Inhaltsverzeichnis Über 1 Kapitel 1: Erste Schritte mit Embarcadero Delphi 2 Bemerkungen 2 Versionen 2 Examples 3 Hallo Welt 3 Zeigen Sie

Der Spaß liegt in der HandleThreadResult-Implementierung:

procedure TForm1.HandleThreadResult(var Message: TUMWorkerDone); var i: Integer; ThreadIdx: Integer; Thread: TWorker; Done: Boolean; begin // Find thread in array ThreadIdx := -1; for i := Low(FThreads) to High(FThreads) do if FThreads[i].Handle = Cardinal(Message.ThreadHandle) then begin ThreadIdx := i; Break; end; // Report results and free the thread, nilling its pointer and handle // so we can detect when all threads are done. if ThreadIdx > -1 then begin Thread := TWorker(FThreads[i].Instance); Memo1.Lines.Add(Format('Thread %d returned %f', [ThreadIdx, Thread.Result])); FreeAndNil(FThreads[i].Instance); FThreads[i].Handle := nil; end; // See whether all threads have finished. Done := True; for i := Low(FThreads) to High(FThreads) do if Assigned(FThreads[i].Instance) then begin Done := False; Break; end; if Done then begin Memo1.Lines.Add('Work done'); FRunning := False; end; end;

Diese Methode sucht zuerst den Thread anhand des in der Nachricht empfangenen Handles. Wenn eine Übereinstimmung gefunden wurde, ruft es das Ergebnis des Threads mit der Instanz ab ( FreeOnTerminate war False , erinnern Sie sich daran?) Und meldet das Ergebnis des Threads. Anschließend wird es beendet: Die Instanz wird FreeOnTerminate und der FreeOnTerminate und das Handle auf null gesetzt länger relevant.

Zum Schluss wird geprüft, ob noch Threads laufen. Wenn keine gefunden wird, wird "all done" gemeldet und das FRunning Flag auf " False " gesetzt, damit ein neuer Arbeitsstapel gestartet werden kann.

Einen Thread ausführen, während die GUI ansprechend bleibt online lesen: https://riptutorial.com/de/delphi/topic/1796/einen-thread-ausfuhren--wahrend-die-gui-ansprechend-bleibt

https://riptutorial.com/de/home 15

Page 20: Embarcadero Delphi - riptutorial.com · Inhaltsverzeichnis Über 1 Kapitel 1: Erste Schritte mit Embarcadero Delphi 2 Bemerkungen 2 Versionen 2 Examples 3 Hallo Welt 3 Zeigen Sie

Kapitel 6: Für Loops

Syntax

für OrdinalVariable: = LowerOrdinalValue bis UpperOrdinalValue fangen das Ende von {Schleifenkörper} an;

für OrdinalVariable: = UpperOrdinalValue Abwärts bis LowerOrdinalValue fangen das Ende von {Schleifenkörper} an;

für EnumerableVariable in Collection begin {Loop-Body} end;•

Bemerkungen

Die for -loop-Syntax von Delphi bietet keine Möglichkeit, die Schrittmenge von 1 auf einen anderen Wert zu ändern.

Beim Schleifen mit variablen Ordinalwerten, z. B. lokalen Variablen vom Typ Integer , werden die oberen und unteren Werte nur einmal bestimmt. Änderungen an solchen Variablen haben keine Auswirkung auf die Anzahl der Schleifeniterationen.

Examples

Einfach für die Schleife

Eine for Schleife wiederholt sich vom Anfangswert bis zum Endwert.

program SimpleForLoop; {$APPTYPE CONSOLE} var i : Integer; begin for i := 1 to 10 do WriteLn(i); end.

Ausgabe:

1 2 3 4 5 6 7 8 9

https://riptutorial.com/de/home 16

Page 21: Embarcadero Delphi - riptutorial.com · Inhaltsverzeichnis Über 1 Kapitel 1: Erste Schritte mit Embarcadero Delphi 2 Bemerkungen 2 Versionen 2 Examples 3 Hallo Welt 3 Zeigen Sie

10

Zeichen einer Zeichenfolge durchlaufen

2005

Im Folgenden werden die Zeichen der Zeichenfolge s durchlaufen. Es funktioniert auf ähnliche Weise für das Schleifen der Elemente eines Arrays oder einer Gruppe, solange der Typ der Schleifensteuervariablen (in diesem Beispiel c ) dem Elementtyp des iterierten Werts entspricht.

program ForLoopOnString; {$APPTYPE CONSOLE} var s : string; c : Char; begin s := 'Example'; for c in s do WriteLn(c); end.

Ausgabe:

E x ein m p l e

Umkehrung der Schleife

Eine for Schleife durchläuft vom Startwert bis zum Endwert (als Beispiel "Countdown").

program CountDown; {$APPTYPE CONSOLE} var i : Integer; begin for i := 10 downto 0 do WriteLn(i); end.

Ausgabe:

10 9

https://riptutorial.com/de/home 17

Page 22: Embarcadero Delphi - riptutorial.com · Inhaltsverzeichnis Über 1 Kapitel 1: Erste Schritte mit Embarcadero Delphi 2 Bemerkungen 2 Versionen 2 Examples 3 Hallo Welt 3 Zeigen Sie

8 7 6 5 4 3 2 1 0

Für eine Schleife mit einer Aufzählung

Eine for Schleife durchläuft Elemente in einer Aufzählung

program EnumLoop; uses TypInfo; type TWeekdays = (Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday); var wd : TWeekdays; begin for wd in TWeekdays do WriteLn(GetEnumName(TypeInfo(TWeekdays), Ord(wd))); end.

Ausgabe:

Sonntag Montag Dienstag Mittwoch Donnerstag Freitag Samstag

Für in Reihe

Eine for Schleife durchläuft Elemente in einem Array

program ArrayLoop; {$APPTYPE CONSOLE} const a : array[1..3] of real = ( 1.1, 2.2, 3.3 ); var f : real; begin for f in a do WriteLn( f );

https://riptutorial.com/de/home 18

Page 23: Embarcadero Delphi - riptutorial.com · Inhaltsverzeichnis Über 1 Kapitel 1: Erste Schritte mit Embarcadero Delphi 2 Bemerkungen 2 Versionen 2 Examples 3 Hallo Welt 3 Zeigen Sie

end.

Ausgabe:

1,1 2,2 3,3

Für Loops online lesen: https://riptutorial.com/de/delphi/topic/4643/fur-loops

https://riptutorial.com/de/home 19

Page 24: Embarcadero Delphi - riptutorial.com · Inhaltsverzeichnis Über 1 Kapitel 1: Erste Schritte mit Embarcadero Delphi 2 Bemerkungen 2 Versionen 2 Examples 3 Hallo Welt 3 Zeigen Sie

Kapitel 7: Generics

Examples

Sortieren Sie ein dynamisches Array mit dem generischen TArray.Sort

uses System.Generics.Collections, { TArray } System.Generics.Defaults; { TComparer<T> } var StringArray: TArray<string>; { Also works with "array of string" } ... { Sorts the array case insensitive } TArray.Sort<string>(StringArray, TComparer<string>.Construct( function (const A, B: string): Integer begin Result := string.CompareText(A, B); end ));

Einfache Verwendung von TList

var List: TList<Integer>; ... List := TList<Integer>.Create; { Create List } try List.Add(100); { Add Items } List.Add(200); WriteLn(List[1]); { 200 } finally List.Free; end;

Absteigend von TList es spezifisch machen

type TIntegerList = class(TList<Integer>) public function Sum: Integer; end; ... function TIntegerList.Sum: Integer; var Item: Integer; begin Result := 0;

https://riptutorial.com/de/home 20

Page 25: Embarcadero Delphi - riptutorial.com · Inhaltsverzeichnis Über 1 Kapitel 1: Erste Schritte mit Embarcadero Delphi 2 Bemerkungen 2 Versionen 2 Examples 3 Hallo Welt 3 Zeigen Sie

for Item in Self do Result := Result + Item; end;

Sortieren Sie eine TList

var List: TList<TDateTime>; ... List.Sort( TComparer<TDateTime>.Construct( function(const A, B: TDateTime): Integer begin Result := CompareDateTime(A, B); end ) );

Generics online lesen: https://riptutorial.com/de/delphi/topic/4054/generics

https://riptutorial.com/de/home 21

Page 26: Embarcadero Delphi - riptutorial.com · Inhaltsverzeichnis Über 1 Kapitel 1: Erste Schritte mit Embarcadero Delphi 2 Bemerkungen 2 Versionen 2 Examples 3 Hallo Welt 3 Zeigen Sie

Kapitel 8: Leicht entfernbare Laufzeitfehlerprüfungen erstellen

Einführung

Dies zeigt, wie eine selbst erstellte Laufzeitfehlerüberprüfungsroutine problemlos integriert werden kann, sodass beim Ausschalten kein Code-Overhead entsteht.

Examples

Triviales Beispiel

{$DEFINE MyRuntimeCheck} // Comment out this directive when the check is no-longer required! // You can also put MyRuntimeCheck in the project defines instead. function MyRuntimeCheck: Boolean; {$IFNDEF MyRuntimeCheck} inline; {$ENDIF} begin result := TRUE; {$IFDEF MyRuntimeCheck} // .. the code for your check goes here {$ENDIF} end;

Das Konzept ist im Grunde Folgendes:

Das definierte Symbol wird verwendet, um die Verwendung des Codes zu aktivieren. Dadurch wird auch verhindert, dass der Code explizit eingebettet wird, sodass es einfacher ist, einen Haltepunkt in die Prüfroutine einzufügen.

Allerdings ist die wahre Schönheit dieser Konstruktion , wenn Sie die Prüfung wollen nicht mehr. Durch das Auskommentieren des $ DEFINE (setzen Sie "//" davor), entfernen Sie nicht nur den Prüfcode, sondern schalten auch die Inline für die Routine ein und entfernen so alle Overheads an allen Stellen, an denen Sie aufgerufen haben die Routine! Der Compiler entfernt alle Spuren Ihrer Prüfung vollständig (vorausgesetzt natürlich, dass das Inlining auf "Ein" oder "Auto" gesetzt ist).

Das obige Beispiel ist im Wesentlichen dem Konzept der "Assertions" ähnlich, und Ihre erste Zeile könnte das Ergebnis entsprechend der Verwendung auf TRUE oder FALSE setzen.

Sie können diese Konstruktionsweise jetzt aber auch für Code verwenden, der Traceprotokollierung, Metriken usw. durchführt. Zum Beispiel:

procedure MyTrace(const what: string); {$IFNDEF MyTrace} inline; {$ENDIF} begin {$IFDEF MyTrace} // .. the code for your trace-logging goes here {$ENDIF}

https://riptutorial.com/de/home 22

Page 27: Embarcadero Delphi - riptutorial.com · Inhaltsverzeichnis Über 1 Kapitel 1: Erste Schritte mit Embarcadero Delphi 2 Bemerkungen 2 Versionen 2 Examples 3 Hallo Welt 3 Zeigen Sie

end; ... MyTrace('I was here'); // This code overhead will vanish if 'MyTrace' is not defined. MyTrace( SomeString ); // So will this.

Leicht entfernbare Laufzeitfehlerprüfungen erstellen online lesen: https://riptutorial.com/de/delphi/topic/10541/leicht-entfernbare-laufzeitfehlerprufungen-erstellen

https://riptutorial.com/de/home 23

Page 28: Embarcadero Delphi - riptutorial.com · Inhaltsverzeichnis Über 1 Kapitel 1: Erste Schritte mit Embarcadero Delphi 2 Bemerkungen 2 Versionen 2 Examples 3 Hallo Welt 3 Zeigen Sie

Kapitel 9: Schleifen

Einführung

Delphi-Sprache bietet 3 Arten von Schleifen

for - iterator für feste Reihenfolge über Ganzzahl, String, Array oder Aufzählung

repeat-until - Quit-Bedingung wird nach jeder Runde geprüft, wobei die Schleife mindestens einmal ausgeführt wird

while do do-Bedingung vor jeder Runde überprüft wird, kann die Schleife niemals ausgeführt werden

Syntax

für OrdinalVariable: = LowerOrdinalValue bis UpperOrdinalValue fangen das Ende von {Schleifenkörper} an;

für OrdinalVariable: = UpperOrdinalValue Abwärts bis LowerOrdinalValue fangen das Ende von {Schleifenkörper} an;

für EnumerableVariable in Collection begin {Loop-Body} end;•wiederholen Sie {loop-body} bis {break-condition};•while {Bedingung} begin {Endet {Loop-Body};•

Examples

Brechen Sie in Loops und fahren Sie fort

program ForLoopWithContinueAndBreaks; {$APPTYPE CONSOLE} var var i : integer; begin for i := 1 to 10 do begin if i = 2 then continue; (* Skip this turn *) if i = 8 then break; (* Break the loop *) WriteLn( i ); end; WriteLn('Finish.'); end.

Ausgabe:

1 3

https://riptutorial.com/de/home 24

Page 29: Embarcadero Delphi - riptutorial.com · Inhaltsverzeichnis Über 1 Kapitel 1: Erste Schritte mit Embarcadero Delphi 2 Bemerkungen 2 Versionen 2 Examples 3 Hallo Welt 3 Zeigen Sie

4 5 6 7 Fertig.

Wiederhole bis

program repeat_test; {$APPTYPE CONSOLE} var s : string; begin WriteLn( 'Type a words to echo. Enter an empty string to exit.' ); repeat ReadLn( s ); WriteLn( s ); until s = ''; end.

Dieses kurze Beispiel wird auf der Konsole gedruckt. Geben Sie Type a words to echo. Enter an empty string to exit. , warten Sie auf den Benutzertyp, wiederholen Sie die Echo-Eingabe und warten Sie die Eingabe in einer Endlosschleife erneut ab - bis der Benutzer den leeren String eingibt.

Während tun

program WhileEOF; {$APPTYPE CONSOLE} uses SysUtils; const cFileName = 'WhileEOF.dpr'; var F : TextFile; s : string; begin if FileExists( cFileName ) then begin AssignFile( F, cFileName ); Reset( F ); while not Eof(F) do begin ReadLn(F, s); WriteLn(s); end; CloseFile( F ); end else WriteLn( 'File ' + cFileName + ' not found!' ); end.

In diesem Beispiel wird der Textinhalt der WhileEOF.dpr Datei mit der While not(EOF) Bedingung

https://riptutorial.com/de/home 25

Page 30: Embarcadero Delphi - riptutorial.com · Inhaltsverzeichnis Über 1 Kapitel 1: Erste Schritte mit Embarcadero Delphi 2 Bemerkungen 2 Versionen 2 Examples 3 Hallo Welt 3 Zeigen Sie

While not(EOF) WhileEOF.dpr . Wenn die Datei leer ist, wird die ReadLn-WriteLn Schleife nicht ausgeführt.

Schleifen online lesen: https://riptutorial.com/de/delphi/topic/9931/schleifen

https://riptutorial.com/de/home 26

Page 31: Embarcadero Delphi - riptutorial.com · Inhaltsverzeichnis Über 1 Kapitel 1: Erste Schritte mit Embarcadero Delphi 2 Bemerkungen 2 Versionen 2 Examples 3 Hallo Welt 3 Zeigen Sie

Kapitel 10: Schnittstellen

Bemerkungen

Schnittstellen werden verwendet, um die benötigten Informationen und die erwartete Ausgabe von Methoden und Klassen zu beschreiben, ohne Informationen über die explizite Implementierung bereitzustellen.

Klassen können Schnittstellen implementieren , und Schnittstellen können voneinander erben . Wenn eine Klasse eine Schnittstelle implementiert , bedeutet dies, dass alle von der Schnittstelle bereitgestellten Funktionen und Prozeduren in der Klasse vorhanden sind.

Ein besonderer Aspekt von Interfaces in Delphi ist, dass Instanzen von Interfaces über ein Lebensdauermanagement verfügen, das auf der Referenzzählung basiert. Die Lebensdauer von Klasseninstanzen muss manuell verwaltet werden.

Unter Berücksichtigung all dieser Aspekte können Schnittstellen verwendet werden, um verschiedene Ziele zu erreichen:

Mehrere verschiedene Implementierungen für Operationen bereitstellen (z. B. Speichern in einer Datei, Datenbank oder Senden als E-Mail, alle als Schnittstelle "SaveData")

Reduzieren Sie Abhängigkeiten, verbessern Sie die Entkopplung und machen Sie so den Code besser wartbar und überprüfbar

Arbeiten Sie mit Instanzen in mehreren Einheiten, ohne sich durch das Lifetime-Management zu stören (obwohl auch hier Fallstricke vorhanden sind, passen Sie auf!)

Examples

Schnittstelle definieren und implementieren

Eine Schnittstelle wird wie eine Klasse deklariert, jedoch ohne Zugriffsmodifizierer ( public , private , ...). Außerdem sind keine Definitionen zulässig, daher können Variablen und Konstanten nicht verwendet werden.

Schnittstellen sollten immer über eine eindeutige Kennung verfügen, die durch Drücken von Strg + Umschalttaste + G generiert werden kann.

IRepository = interface ['{AFCFCE96-2EC2-4AE4-8E23-D4C4FF6BBD01}'] function SaveKeyValuePair(aKey: Integer; aValue: string): Boolean; end;

Um eine Schnittstelle zu implementieren, muss der Name der Schnittstelle hinter der Basisklasse hinzugefügt werden. Außerdem sollte die Klasse ein Nachkomme von TInterfacedObject (dies ist wichtig für die Lebenszeitverwaltung ).

https://riptutorial.com/de/home 27

Page 32: Embarcadero Delphi - riptutorial.com · Inhaltsverzeichnis Über 1 Kapitel 1: Erste Schritte mit Embarcadero Delphi 2 Bemerkungen 2 Versionen 2 Examples 3 Hallo Welt 3 Zeigen Sie

TDatabaseRepository = class(TInterfacedObject, IRepository) function SaveKeyValuePair(aKey: Integer; aValue: string): Boolean; end;

Wenn eine Klasse eine Schnittstelle implementiert, muss sie alle in der Schnittstelle deklarierten Methoden und Funktionen enthalten. Andernfalls wird sie nicht kompiliert.

Bemerkenswert ist, dass Zugriffsmodifizierer keinen Einfluss haben, wenn der Anrufer mit der Schnittstelle arbeitet. Zum Beispiel können alle Funktionen der Schnittstelle als strict private Member implementiert werden, sie können jedoch auch von einer anderen Klasse aufgerufen werden, wenn eine Instanz der Schnittstelle verwendet wird.

Implementierung mehrerer Schnittstellen

Klassen können mehr als eine Schnittstelle implementieren, anstatt von mehreren Klassen zu erben ( Multiple Inheritance ), was für Delphi-Klassen nicht möglich ist. Um dies zu erreichen, muss der Name aller Schnittstellen durch Kommas getrennt hinter der Basisklasse hinzugefügt werden.

Natürlich muss die implementierende Klasse auch die von jeder der Schnittstellen deklarierten Funktionen definieren.

IInterface1 = interface ['{A2437023-7606-4551-8D5A-1709212254AF}'] procedure Method1(); function Method2(): Boolean; end; IInterface2 = interface ['{6C47FF48-3943-4B53-8D5D-537F4A0DEC0D}'] procedure SetValue(const aValue: TObject); function GetValue(): TObject; property Value: TObject read GetValue write SetValue; end; TImplementer = class(TInterfacedObject, IInterface1, IInterface2) // IInterface1 procedure Method1(); function Method2(): Boolean; // IInterface2 procedure SetValue(const aValue: TObject); function GetValue(): TObject property Value: TObject read GetValue write SetValue; end;

Vererbung für Schnittstellen

Schnittstellen können voneinander erben, genau wie Klassen auch. Eine implementierende Klasse muss also Funktionen der Schnittstelle und aller Basisschnittstellen implementieren. Auf diese Weise weiß der Compiler jedoch nicht, dass die implizierende Klasse auch die Basisschnittstelle

https://riptutorial.com/de/home 28

Page 33: Embarcadero Delphi - riptutorial.com · Inhaltsverzeichnis Über 1 Kapitel 1: Erste Schritte mit Embarcadero Delphi 2 Bemerkungen 2 Versionen 2 Examples 3 Hallo Welt 3 Zeigen Sie

implementiert. Er kennt nur die explizit aufgeführten Schnittstellen. Aus diesem Grund würde die Verwendung as ISuperInterface auf TImplementer nicht funktionieren. Dies führt in der üblichen Praxis auch dazu, alle Basisschnittstellen explizit zu implementieren (in diesem Fall TImplementer = class(TInterfacedObject, IDescendantInterface, ISuperInterface) ).

ISuperInterface = interface ['{A2437023-7606-4551-8D5A-1709212254AF}'] procedure Method1(); function Method2(): Boolean; end; IDescendantInterface = interface(ISuperInterface) ['{6C47FF48-3943-4B53-8D5D-537F4A0DEC0D}'] procedure SetValue(const aValue: TObject); function GetValue(): TObject; property Value: TObject read GetValue write SetValue; end; TImplementer = class(TInterfacedObject, IDescendantInterface) // ISuperInterface procedure Method1(); function Method2(): Boolean; // IDescendantInterface procedure SetValue(const aValue: TObject); function GetValue(): TObject property Value: TObject read GetValue write SetValue; end;

Eigenschaften in Schnittstellen

Da die Deklaration von Variablen in Schnittstellen nicht möglich ist, kann die "schnelle" Art der Definition von Eigenschaften ( property Value: TObject read FValue write FValue; ) nicht verwendet werden. Stattdessen müssen auch Getter und Setter (jeweils nur bei Bedarf) in der Schnittstelle deklariert werden.

IInterface = interface(IInterface) ['{6C47FF48-3943-4B53-8D5D-537F4A0DEC0D}'] procedure SetValue(const aValue: TObject); function GetValue(): TObject; property Value: TObject read GetValue write SetValue; end;

Bemerkenswert ist, dass die implementierende Klasse die Eigenschaft nicht deklarieren muss. Der Compiler würde diesen Code akzeptieren:

TImplementer = class(TInterfacedObject, IInterface) procedure SetValue(const aValue: TObject); function GetValue(): TObject end;

https://riptutorial.com/de/home 29

Page 34: Embarcadero Delphi - riptutorial.com · Inhaltsverzeichnis Über 1 Kapitel 1: Erste Schritte mit Embarcadero Delphi 2 Bemerkungen 2 Versionen 2 Examples 3 Hallo Welt 3 Zeigen Sie

Ein Nachteil ist jedoch, dass auf diese Eigenschaft nur über eine Instanz der Schnittstelle zugegriffen werden kann, nicht über die Klasse selbst. Durch das Hinzufügen der Eigenschaft zur Klasse wird außerdem die Lesbarkeit erhöht.

Schnittstellen online lesen: https://riptutorial.com/de/delphi/topic/4885/schnittstellen

https://riptutorial.com/de/home 30

Page 35: Embarcadero Delphi - riptutorial.com · Inhaltsverzeichnis Über 1 Kapitel 1: Erste Schritte mit Embarcadero Delphi 2 Bemerkungen 2 Versionen 2 Examples 3 Hallo Welt 3 Zeigen Sie

Kapitel 11: TStringList-Klasse

Examples

Einführung

TStringList ist ein Nachkomme der TStrings-Klasse der VCL. TStringList kann zum Speichern und Bearbeiten von Strings verwendet werden. Obwohl ursprünglich für Strings vorgesehen, können mit dieser Klasse auch beliebige Objekttypen bearbeitet werden.

TStringList wird in VCL häufig verwendet, wenn der Zweck besteht, eine Liste von Strings zu verwalten. TStringList unterstützt eine Vielzahl von Methoden, die ein hohes Maß an Anpassung und einfache Handhabung bieten.

Das folgende Beispiel zeigt das Erstellen, Hinzufügen von Strings, das Sortieren, Abrufen und Freigeben eines TStringList-Objekts.

procedure StringListDemo; var MyStringList: TStringList; i: Integer; Begin //Create the object MyStringList := TStringList.Create(); try //Add items MyStringList.Add('Zebra'); MyStringList.Add('Elephant'); MyStringList.Add('Tiger'); //Sort in the ascending order MyStringList.Sort; //Output for i:=0 to MyStringList.Count - 1 do WriteLn(MyStringList[i]); finally //Destroy the object MyStringList.Free; end; end;

TStringList bietet eine Vielzahl von Benutzerfällen, einschließlich der Bearbeitung von Zeichenfolgen, dem Sortieren, der Indexierung, der Schlüsselwertpaarung und der Trennung von Trennzeichen.

Schlüsselwertpaarung

Sie können eine TStringList verwenden, um Schlüssel-Wert-Paare zu speichern. Dies kann

https://riptutorial.com/de/home 31

Page 36: Embarcadero Delphi - riptutorial.com · Inhaltsverzeichnis Über 1 Kapitel 1: Erste Schritte mit Embarcadero Delphi 2 Bemerkungen 2 Versionen 2 Examples 3 Hallo Welt 3 Zeigen Sie

nützlich sein, wenn Sie beispielsweise Einstellungen speichern möchten. Eine Einstellung besteht aus einem Schlüssel (der ID der Einstellung) und dem Wert. Jedes Schlüssel-Wert-Paar wird in einer Zeile der StringList im Format Key = Value gespeichert.

procedure Demo(const FileName: string = ''); var SL: TStringList; i: Integer; begin SL:= TStringList.Create; try //Adding a Key-Value pair can be done this way SL.Values['FirstName']:= 'John'; //Key is 'FirstName', Value is 'John' SL.Values['LastName']:= 'Doe'; //Key is 'LastName', Value is 'Doe' //or this way SL.Add('City=Berlin'); //Key ist 'City', Value is 'Berlin' //you can get the key of a given Index IF SL.Names[0] = 'FirstName' THEN begin //and change the key at an index SL.Names[0]:= '1stName'; //Key is now "1stName", Value remains "John" end; //you can get the value of a key s:= SL.Values['City']; //s now is set to 'Berlin' //and overwrite a value SL.Values['City']:= 'New York'; //if desired, it can be saved to an file IF (FileName <> '') THEN begin SL.SaveToFile(FileName); end; finally SL.Free; end; end;

In diesem Beispiel hat die Stringliste den folgenden Inhalt, bevor sie zerstört wird:

1stName=John LastName=Doe City=New York

Hinweis zur Leistung

Unter der Haube TStringList führt die Schlüsselsuche durch, indem alle Elemente direkt durchlaufen werden, innerhalb jedes Elements nach einem Trennzeichen gesucht wird und der Namensanteil mit dem angegebenen Schlüssel verglichen wird. Es muss nicht gesagt werden, dass dies einen großen Einfluss auf die Leistung hat. Daher sollte dieser Mechanismus nur an unkritischen, selten wiederholten Orten verwendet werden. In Fällen, in denen es auf die Leistung ankommt, sollten Sie TDictionary<TKey,TValue> von System.Generics.Collections , die die Hashtabellensuche implementieren, oder die Schlüssel in sortierter TStringList mit Werten

https://riptutorial.com/de/home 32

Page 37: Embarcadero Delphi - riptutorial.com · Inhaltsverzeichnis Über 1 Kapitel 1: Erste Schritte mit Embarcadero Delphi 2 Bemerkungen 2 Versionen 2 Examples 3 Hallo Welt 3 Zeigen Sie

speichern, die als Object -s gespeichert sind, und den binären Suchalgorithmus verwenden.

TStringList-Klasse online lesen: https://riptutorial.com/de/delphi/topic/6045/tstringlist-klasse

https://riptutorial.com/de/home 33

Page 38: Embarcadero Delphi - riptutorial.com · Inhaltsverzeichnis Über 1 Kapitel 1: Erste Schritte mit Embarcadero Delphi 2 Bemerkungen 2 Versionen 2 Examples 3 Hallo Welt 3 Zeigen Sie

Kapitel 12: Verwendung von RTTI in Delphi

Einführung

Delphi stellte vor mehr als einem Jahrzehnt Runtime Type Information (RTTI) bereit. Doch auch heute sind sich viele Entwickler der Risiken und Vorteile nicht voll bewusst.

Kurz gesagt, Runtime-Typ-Informationen sind Informationen zum Datentyp eines Objekts, der zur Laufzeit in den Speicher gesetzt wird.

Mit RTTI können Sie feststellen, ob der Typ eines Objekts dem Typ einer bestimmten Klasse oder einer ihrer Nachkommen entspricht.

Bemerkungen

RTTI IN DELPHI - ERKLÄRT

Die Laufzeit-Typinformationen in Delphi - kann dies alles für Sie tun? Artikel von Brian Long bietet eine großartige Einführung in die RTTI-Funktionen von Delphi. Brian erklärt, dass die RTTI-Unterstützung in Delphi in erster Linie hinzugefügt wurde, damit die Entwurfszeitumgebung ihre Arbeit erledigen kann, dass Entwickler jedoch auch die Möglichkeit haben können, bestimmte Code-Vereinfachungen zu erreichen. Dieser Artikel bietet auch einen guten Überblick über die RTTI-Klassen sowie einige Beispiele.

Beispiele sind: Lesen und Schreiben von beliebigen Eigenschaften, allgemeine Eigenschaften ohne gemeinsamen Vorfahren, Kopieren von Eigenschaften von einer Komponente in eine andere usw.

Examples

Grundlegende Klasseninformationen

In diesem Beispiel wird ClassType , wie die Vorfahren einer Komponente mithilfe der ClassType und ClassParent Eigenschaften ClassType werden. Es verwendet eine Schaltfläche Button1: TButton und ein Listenfeld ListBox1: TListBox in einem Formular TForm1 .

Wenn der Benutzer auf die Schaltfläche klickt, werden der Name der Klasse der Schaltfläche und die Namen der übergeordneten Klassen zum Listenfeld hinzugefügt.

procedure TForm1.Button1Click(Sender: TObject) ; var ClassRef: TClass; begin ListBox1.Clear; ClassRef := Sender.ClassType; while ClassRef <> nil do begin

https://riptutorial.com/de/home 34

Page 39: Embarcadero Delphi - riptutorial.com · Inhaltsverzeichnis Über 1 Kapitel 1: Erste Schritte mit Embarcadero Delphi 2 Bemerkungen 2 Versionen 2 Examples 3 Hallo Welt 3 Zeigen Sie

ListBox1.Items.Add(ClassRef.ClassName) ; ClassRef := ClassRef.ClassParent; end; end;

Das Listenfeld enthält die folgenden Zeichenfolgen, nachdem der Benutzer auf die Schaltfläche geklickt hat:

TButton•TButtonControl•TWinControl•TControl•TComponent•TPersistent•TObject•

Verwendung von RTTI in Delphi online lesen: https://riptutorial.com/de/delphi/topic/9578/verwendung-von-rtti-in-delphi

https://riptutorial.com/de/home 35

Page 40: Embarcadero Delphi - riptutorial.com · Inhaltsverzeichnis Über 1 Kapitel 1: Erste Schritte mit Embarcadero Delphi 2 Bemerkungen 2 Versionen 2 Examples 3 Hallo Welt 3 Zeigen Sie

Kapitel 13: Verwendung von try außer und zum Schluss

Syntax

Try-Exception: try [Anweisungen] außer [[[[bei E: ExceptionType do-Anweisung]] [else-Anweisung] | [Anweisungen] Ende;

Try-finally: try [Anweisungen] finally [Anweisungen] end;

1.

Examples

Einfaches try..finally Beispiel, um Speicherlecks zu vermeiden

Verwenden Sie try - zum finally , um Ressourcenlecks (wie Speicher) zu vermeiden, falls während der Ausführung eine Ausnahme auftritt.

Die folgende Prozedur speichert eine Zeichenfolge in einer Datei und verhindert, dass die TStringList .

procedure SaveStringToFile(const aFilename: TFilename; const aString: string); var SL: TStringList; begin SL := TStringList.Create; // call outside the try try SL.Text := aString; SL.SaveToFile(aFilename); finally SL.Free // will be called no matter what happens above end; end;

Unabhängig davon, ob beim Speichern der Datei eine Ausnahme auftritt, wird SL freigegeben. Jede Ausnahme geht an den Anrufer.

Ausnahmesichere Rückgabe eines neuen Objekts

Wenn eine Funktion ein Objekt zurückgibt (im Gegensatz zur Verwendung eines Objekts, das vom Aufrufer übergeben wurde), ist zu beachten, dass eine Ausnahme das Objekt nicht verliert.

function MakeStrings: TStrings; begin // Create a new object before entering the try-block. Result := TStringList.Create; try // Execute code that uses the new object and prepares it for the caller. Result.Add('One');

https://riptutorial.com/de/home 36

Page 41: Embarcadero Delphi - riptutorial.com · Inhaltsverzeichnis Über 1 Kapitel 1: Erste Schritte mit Embarcadero Delphi 2 Bemerkungen 2 Versionen 2 Examples 3 Hallo Welt 3 Zeigen Sie

MightThrow; except // If execution reaches this point, then an exception has occurred. We cannot // know how to handle all possible exceptions, so we merely clean up the resources // allocated by this function and then re-raise the exception so the caller can // choose what to do with it. Result.Free; raise; end; // If execution reaches this point, then no exception has occurred, so the // function will return Result normally. end;

Naive Programmierer versuchen möglicherweise, alle Ausnahmetypen abzufangen und nil aus einer solchen Funktion zurückzugeben. nil ist jedoch nur ein Spezialfall der generell unmutigen Praxis, alle Ausnahmetypen zu erfassen, ohne sie zu behandeln.

Try-endlich verschachtelt in Try-Exceptions

Ein try - finally - Block kann innerhalb eines try - mit except Blocks - verschachtelt sein.

try AcquireResources; try UseResource; finally ReleaseResource; end; except on E: EResourceUsageError do begin HandleResourceErrors; end; end;

Wenn innerhalb von UseResource eine Ausnahme auftritt, UseResource Ausführung zu ReleaseResource . Wenn die Ausnahme ein EResourceUsageError , springt die Ausführung zum Ausnahmehandler und ruft HandleResourceErrors . Ausnahmen eines anderen Typs überspringen den Ausnahmebehandler oben und blasen bis zum nächsten try - except Blockieren des Aufrufstapels.

Ausnahmen in AcquireResource oder ReleaseResource dazu, dass die Ausführung an den Ausnahmebehandler geht und den finally Block überspringt, entweder weil der entsprechende try Block noch nicht eingegeben wurde oder weil der finally Block bereits eingegeben wurde.

Try-Ausnahme verschachtelt in Try-finally

Ein try - except Block kann innerhalb eines try - finally Blocks verschachtelt sein.

AcquireResource; try UseResource1; try UseResource2;

https://riptutorial.com/de/home 37

Page 42: Embarcadero Delphi - riptutorial.com · Inhaltsverzeichnis Über 1 Kapitel 1: Erste Schritte mit Embarcadero Delphi 2 Bemerkungen 2 Versionen 2 Examples 3 Hallo Welt 3 Zeigen Sie

except on E: EResourceUsageError do begin HandleResourceErrors; end; end; UseResource3; finally ReleaseResource; end;

Wenn in UseResource2 ein EResourceUsageError auftritt, UseResource2 Ausführung zum Ausnahmehandler und ruft HandleResourceError . Die Ausnahme wird als behandelt betrachtet, sodass die Ausführung weiterhin bei UseResource3 und dann bei ReleaseResource .

Wenn in UseResource2 eine Ausnahme eines anderen Typs auftritt, wird der hier angegebene Ausnahmebehandler nicht UseResource3 Ausführung springt dann über den Aufruf von UseResource3 und geht direkt zum finally Block, in dem ReleaseResource aufgerufen wird. Danach springt die Ausführung zum nächsten anwendbaren Ausnahmebehandlungsprogramm, da die Ausnahmebedingung den Aufrufstapel aufbläst.

Wenn bei einem anderen Aufruf im obigen Beispiel eine Ausnahme auftritt, werden HandleResourceErrors nicht aufgerufen. Dies liegt daran, dass keine der anderen Aufrufe innerhalb des try Blocks erfolgt, der diesem Ausnahmehandler entspricht.

Try-finally mit 2 oder mehr Objekten

Object1 := nil; Object2 := nil; try Object1 := TMyObject.Create; Object2 := TMyObject.Create; finally Object1.Free; Object2.Free; end;

Wenn Sie die Objekte nicht mit " nil außerhalb des try-finally Blocks initialisieren, wird beim try-finally Block ein AV ausgelöst, da das Objekt nicht null ist (da es nicht initialisiert wurde) und wird eine Ausnahme verursachen.

Die Free Methode prüft, ob das Objekt null ist. Wenn Sie beide Objekte mit nil initialisieren, werden Fehler vermieden, wenn Sie sie freigeben, wenn sie nicht erstellt wurden.

Verwendung von try außer und zum Schluss online lesen: https://riptutorial.com/de/delphi/topic/3055/verwendung-von-try-au-er-und-zum-schluss

https://riptutorial.com/de/home 38

Page 43: Embarcadero Delphi - riptutorial.com · Inhaltsverzeichnis Über 1 Kapitel 1: Erste Schritte mit Embarcadero Delphi 2 Bemerkungen 2 Versionen 2 Examples 3 Hallo Welt 3 Zeigen Sie

Kapitel 14: Zeichenketten

Examples

String-Typen

Delphi verfügt über die folgenden Zeichenfolgentypen (in Reihenfolge der Beliebtheit):

ArtMaximale Länge

Mindestmaß Beschreibung

string 2 GB 16 BytesEine verwaltete Zeichenfolge. Ein Alias für AnsiString durch Delphi 2007 und ein Alias für UnicodeString ab Delphi 2009.

UnicodeString 2 GB 16 BytesEine verwaltete Zeichenfolge im UTF-16-Format.

AnsiString 2 GB 16 BytesEine verwaltete Zeichenfolge im vor-Unicode-ANSI-Format. Ab Delphi 2009 enthält es einen expliziten Codepage-Indikator.

UTF8String 2 GB 16 BytesEin verwalteter String im UTF-8-Format, der als AnsiString mit einer UTF-8-Codepage implementiert ist.

ShortString255 Zeichen

2 BytesEine ältere, nicht verwaltete Saite mit fester Länge und sehr wenig Aufwand

WideString 2 GB 4 BytesFür COM-Interop vorgesehen, eine verwaltete Zeichenfolge im UTF-16-Format. Entspricht dem Windows- BSTR Typ.

UnicodeString und AnsiString sind Referenzzähler und Copy-on-Write (COW). ShortString und WideString werden nicht als Referenz gezählt und haben keine COW-Semantik.

Zeichenketten

uses System.Character; var S1, S2: string; begin S1 := 'Foo'; S2 := ToLower(S1); // Convert the string to lower-case S1 := ToUpper(S2); // Convert the string to upper-case

https://riptutorial.com/de/home 39

Page 44: Embarcadero Delphi - riptutorial.com · Inhaltsverzeichnis Über 1 Kapitel 1: Erste Schritte mit Embarcadero Delphi 2 Bemerkungen 2 Versionen 2 Examples 3 Hallo Welt 3 Zeigen Sie

Zeichen

2009

uses Character; var C1, C2: Char; begin C1 := 'F'; C2 := ToLower(C1); // Convert the char to lower-case C1 := ToUpper(C2); // Convert the char to upper-case

Die uses sollte System.Character wenn die Version XE2 oder höher ist.

Groß-und Kleinschreibung

uses SysUtils; var S1, S2: string; begin S1 := 'Foo'; S2 := LowerCase(S1); // S2 := 'foo'; S1 := UpperCase(S2); // S1 := 'FOO';

Zuordnung

Zuweisen von string zu verschiedenen String-Typen und wie sich die Laufzeitumgebung in Bezug auf sie verhält. Speicherzuordnung, Referenzzählung, indizierter Zugriff auf Zeichen und Compiler-Fehler, falls zutreffend beschrieben.

var SS5: string[5]; {a shortstring of 5 chars + 1 length byte, no trailing `0`} WS: Widestring; {managed pointer, with a bit of compiler support} AS: ansistring; {ansistring with the default codepage of the system} US: unicodestring; {default string type} U8: UTF8string;//same as AnsiString(65001) A1251: ansistring(1251); {ansistring with codepage 1251: Cryllic set} RB: RawbyteString; {ansistring with codepage 0: no conversion set} begin SS5:= 'test'; {S[0] = Length(SS254) = 4, S[1] = 't'...S[5] = undefined} SS5:= 'test1'; {S[0] = 5, S[5] = '1', S[6] is out of bounds} SS5:= 'test12'; {compile time error} WS:= 'test'; {WS now points to a constant unicodestring hard compiled into the data segment} US:= 'test'+IntToStr(1); {New unicode string is created with reference count = 1} WS:= US; {SysAllocateStr with datacopied to dest, US refcount = 1 !} AS:= US; {the UTF16 in US is converted to "extended" ascii taking into account the codepage in AS possibly losing data in the process} U8:= US; {safe copy of US to U8, all data is converted from UTF16 into UTF8} RB:= US; {RB = 'test1'#0 i.e. conversion into RawByteString uses system default codepage} A1251:= RB; {no conversion takes place, only reference copied. Ref count incremented }

https://riptutorial.com/de/home 40

Page 45: Embarcadero Delphi - riptutorial.com · Inhaltsverzeichnis Über 1 Kapitel 1: Erste Schritte mit Embarcadero Delphi 2 Bemerkungen 2 Versionen 2 Examples 3 Hallo Welt 3 Zeigen Sie

Referenzzählung

Das Zählen von Referenzen auf Strings ist Thread-sicher. Sperren und Ausnahmebehandler werden verwendet, um den Prozess abzusichern. Betrachten Sie den folgenden Code mit Kommentaren, die angeben, wo der Compiler zur Kompilierzeit Code einfügt, um Referenzzählungen zu verwalten:

procedure PassWithNoModifier(S: string); // prologue: Increase reference count of S (if non-negative), // and enter a try-finally block begin // Create a new string to hold the contents of S and 'X'. Assign the new string to S, // thereby reducing the reference count of the string S originally pointed to and // brining the reference count of the new string to 1. // The string that S originally referred to is not modified. S := S + 'X'; end; // epilogue: Enter the `finally` section and decrease the reference count of S, which is // now the new string. That count will be zero, so the new string will be freed. procedure PassWithConst(const S: string); var TempStr: string; // prologue: Clear TempStr and enter a try-finally block. No modification of the reference // count of string referred to by S. begin // Compile-time error: S is const. S := S + 'X'; // Create a new string to hold the contents of S and 'X'. TempStr gets a reference count // of 1, and reference count of S remains unchanged. TempStr := S + 'X'; end; // epilogue: Enter the `finally` section and decrease the reference count of TempStr, // freeing TempStr because its reference count will be zero.

Wie oben gezeigt, erfordert das Einführen einer temporären lokalen Zeichenfolge zum Speichern der Änderungen an einem Parameter den gleichen Aufwand wie das direkte Durchführen von Änderungen an diesem Parameter. Das Deklarieren einer Zeichenfolge const nur das Zählen von Referenzen, wenn der Zeichenfolgenparameter wirklich schreibgeschützt ist. Um zu vermeiden, dass Implementierungsdetails außerhalb einer Funktion durchsickern, sollten Sie immer einen der Parameter const , var oder out für den String verwenden.

Kodierungen

String-Typen wie UnicodeString, AnsiString, WideString und UTF8String werden mit ihrer jeweiligen Codierung in einem Speicher gespeichert (weitere Informationen finden Sie unter String-Typen). Das Zuweisen eines Typs eines Strings in einen anderen kann zu einer Konvertierung führen. Der Typ string ist so konzipiert, dass er unabhängig von der Codierung ist. Sie sollten niemals seine interne Darstellung verwenden.

Die Klasse Sysutils.TEncoding stellt die Methode GetBytes zum Konvertieren von string in TBytes (Array von Bytes) und GetString zum Konvertieren von TBytes in string TBytes . Die Klasse Sysutils.TEncoding bietet auch viele vordefinierte Kodierungen als Klasseneigenschaften.

https://riptutorial.com/de/home 41

Page 46: Embarcadero Delphi - riptutorial.com · Inhaltsverzeichnis Über 1 Kapitel 1: Erste Schritte mit Embarcadero Delphi 2 Bemerkungen 2 Versionen 2 Examples 3 Hallo Welt 3 Zeigen Sie

Eine Möglichkeit, mit Codierungen umzugehen, besteht darin, in Ihrer Anwendung nur den string Typ zu verwenden und jedes Mal, wenn Sie eine bestimmte Codierung verwenden müssen, TEncoding zu verwenden - normalerweise bei E / A-Operationen, DLL-Aufrufen usw.

procedure EncodingExample; var hello,response:string; dataout,datain:TBytes; expectedLength:integer; stringStream:TStringStream; stringList:TStringList; begin hello := 'Hello World!Привет мир!'; dataout := SysUtils.TEncoding.UTF8.GetBytes(hello); //Conversion to UTF8 datain := SomeIOFunction(dataout); //This function expects input as TBytes in UTF8 and returns output as UTF8 encoded TBytes. response := SysUtils.TEncoding.UTF8.GetString(datain); //Convertsion from UTF8 //In case you need to send text via pointer and length using specific encoding (used mostly for DLL calls) dataout := SysUtils.TEncoding.GetEncoding('ISO-8859-2').GetBytes(hello); //Conversion to ISO 8859-2 DLLCall(addr(dataout[0]),length(dataout)); //The same is for cases when you get text via pointer and length expectedLength := DLLCallToGetDataLength(); setLength(datain,expectedLength); DLLCall(addr(datain[0]),length(datain)); response := Sysutils.TEncoding.GetEncoding(1250).getString(datain); //TStringStream and TStringList can use encoding for I/O operations stringList:TStringList.create; stringList.text := hello; stringList.saveToFile('file.txt',SysUtils.TEncoding.Unicode); stringList.destroy; stringStream := TStringStream(hello,SysUtils.TEncoding.Unicode); stringStream.saveToFile('file2.txt'); stringStream.Destroy; end;

Zeichenketten online lesen: https://riptutorial.com/de/delphi/topic/3957/zeichenketten

https://riptutorial.com/de/home 42

Page 47: Embarcadero Delphi - riptutorial.com · Inhaltsverzeichnis Über 1 Kapitel 1: Erste Schritte mit Embarcadero Delphi 2 Bemerkungen 2 Versionen 2 Examples 3 Hallo Welt 3 Zeigen Sie

Kapitel 15: Zeitintervallmessung

Examples

Verwenden der Windows-API GetTickCount

Die Windows-API-Funktion GetTickCount gibt die Anzahl der Millisekunden zurück, seit das System (Computer) gestartet wurde. Das einfachste Beispiel lautet:

var Start, Stop, ElapsedMilliseconds: cardinal; begin Start := GetTickCount; // do something that requires measurement Stop := GetTickCount; ElapsedMillseconds := Stop - Start; end;

Beachten Sie, dass GetTickCount 32-Bit- DWORD - DWORD sodass alle 49,7 Tage DWORD werden. Um das Wrapping zu vermeiden, können Sie entweder GetTickCount64 (verfügbar seit Windows Vista) oder spezielle Routinen zur Berechnung der Tick-Differenz verwenden:

function TickDiff(StartTick, EndTick: DWORD): DWORD; begin if EndTick >= StartTick then Result := EndTick - StartTick else Result := High(NativeUInt) - StartTick + EndTick; end; function TicksSince(Tick: DWORD): DWORD; begin Result := TickDiff(Tick, GetTickCount); end;

Auf GetTickCount diese Routinen falsche Ergebnisse, wenn das Intervall von zwei GetTickCount Aufrufen von GetTickCount die 49,7-Tage-Grenze überschreitet.

So konvertieren Sie Millisekunden in Sekunden:

var Start, Stop, ElapsedMilliseconds: cardinal; begin Start := GetTickCount; sleep(4000); // sleep for 4 seconds Stop := GetTickCount; ElapsedMillseconds := Stop - Start; ShowMessage('Total Seconds: ' +IntToStr(round(ElapsedMilliseconds/SysUtils.MSecsPerSec))); // 4 seconds end;

TStopwatch-Datensatz verwenden

https://riptutorial.com/de/home 43

Page 48: Embarcadero Delphi - riptutorial.com · Inhaltsverzeichnis Über 1 Kapitel 1: Erste Schritte mit Embarcadero Delphi 2 Bemerkungen 2 Versionen 2 Examples 3 Hallo Welt 3 Zeigen Sie

Aktuelle Versionen von Delphi werden mit dem TStopwatch- Datensatz geliefert , der für die Zeitintervallmessung dient. Verwendungsbeispiel:

uses System.Diagnostics; var StopWatch: TStopwatch; ElapsedMillseconds: Int64; begin StopWatch := TStopwatch.StartNew; // do something that requires measurement ElapsedMillseconds := StopWatch.ElapsedMilliseconds; end;

Zeitintervallmessung online lesen: https://riptutorial.com/de/delphi/topic/2425/zeitintervallmessung

https://riptutorial.com/de/home 44

Page 49: Embarcadero Delphi - riptutorial.com · Inhaltsverzeichnis Über 1 Kapitel 1: Erste Schritte mit Embarcadero Delphi 2 Bemerkungen 2 Versionen 2 Examples 3 Hallo Welt 3 Zeigen Sie

Credits

S. No

Kapitel Contributors

1Erste Schritte mit Embarcadero Delphi

Charlie H, Community, Dalija Prasnikar, Florian Koch, Jeroen Wiert Pluimers, René Hoffmann, RepeatUntil, Rob Kennedy, Vadim Shakun, w5m, Y.N, Zam

2

Aktualisierte TDataSet-Daten in einem Hintergrundthread abrufen

MartynA

3Andere Programme ausführen

Dalija Prasnikar

4Animationen in Firemonkey verwenden

Alexander Petrosyan

5Einen Thread ausführen, während die GUI ansprechend bleibt

Fr0sT, Jerry Dodge, Johan, kami, LU RD, Marjan Venema

6 Für LoopsFilipe Martins, Jeroen Wiert Pluimers, John Easley, René Hoffmann, Rob Kennedy, Siendor, Y.N

7 Generics Rob Kennedy, Steffen Binas, Uli Gerhardt

8Leicht entfernbare Laufzeitfehlerprüfungen erstellen

Alex T

9 Schleifen Y.N

10 Schnittstellen Florian Koch, Willo van der Merwe

11 TStringList-Klasse Charlie H, Fabricio Araujo, Fr0sT, KaiW

12Verwendung von RTTI in Delphi

Petzy, René Hoffmann

13Verwendung von try außer und zum Schluss

EMBarbosa, Fabio Gomes, Johan, MrE, Nick Hodges, Rob Kennedy, Shadow

14 ZeichenkettenAlekXL, Dalija Prasnikar, EMBarbosa, Fabricio Araujo, Johan, Radek Hladík, René Hoffmann, RepeatUntil, Rob Kennedy, Rudy Velthuis

https://riptutorial.com/de/home 45