Programmierkurs: Delphi: Erstellung einer grafischen Oberfläche weitere Themen
Möchte man irgendetwas Drucken, benutzt man das Printer-Objekt. Dazu muss man die Unit Printers in die Uses-Klausel aufnehmen. Beim Drucken kann man mit der Canvas-Eigenschaft des Druckers arbeiten (dazu muss man beachten, dass zwar FontSize der Größe des Bildschirm entspricht, alle anderen Koordinaten sich jedoch auf Druckerpunkte beziehen, die sind wesentlich kleiner als die Pixel des Bildschirms):
Printer.BeginDoc; // Druckauftrag starten Printer.Canvas.Assign(Image1.Canvas); // Canvas des Image1 übernehmen Printer.EndDoc; // Druckauftrag fertig, Ausdruck beginnen
Damit wird das Bild von Image1 gedruckt.
Möchte man seinen Druck auf verschiedene Druckerauflösungen anpassen, gibt es einen einfachen Weg:
pfactor := Printer.PageWidth / 2400;
Somit multipliziert man dann alle Koordinaten mit pfactor. Funktionsweise: 2400 ist die Breite einer DIN A4 - Seite bei 300 dpi (dots per inch). Es wird hier ermittelt, wie viel mal die Seitenbreite größer als die von 300 dpi / DIN A4. Bei einer Breite von 4800 (600 dpi / DIN A4) wird pfactor 2 sein. So hat das Ergebnis zwar eine andere Auflösung, die Elemente befinden sich aber an derselben Stelle. Möchte man nun das Image drucken, so geschieht das so:
var Bereich: TRect; begin Printer.BeginDoc; // Druckauftrag starten pfactor := Printer.PageWidth / 2400; Bereich.Top := round(10 * pfactor); Bereich.Bottom := round((10 + Image1.Height) * pfactor); Bereich.Left := round(10 * pfactor); Bereich.Right := round((10 + Image1.Width) * pfactor); Printer.Canvas.StretchDraw(Bereich, Image1.Canvas); Printer.EndDoc; // Druckauftrag fertig, Ausdruck beginnen
Alternativ zu round (runden) kann auch trunc (Dezimalstellen abschneiden) benutzt werden.
Ein zweiter Weg wäre es, den Formularinhalt zu drucken:
Form1.Print;
Tabellen
BearbeitenUnd auch wichtig sind StringGrids. TStringGrid findet man im Register Zusätzlich. Dann zieht man die StringGrid-Komponente auf das Formular. Mit der Eigenschaft FixedRows wird die Anzahl der grauen Reihen festgelegt. Dasselbe tut FixedCols für die grauen Spalten (Col = Column = Spalte). RowCount legt die Anzahl der Zeilen fest, ColCount die Anzahl der Spalten. Die wirklich wichtige Eigenschaft ist Cells. Möchte man der Zelle A1 (0; 0) den Inhalt "A1" zuweisen, so geschieht das folgendermaßen:
StringGrid1.Cells[0, 0] := 'A1'; // StringGrid1.Cells[Spalte, Zeile]
Die Nummerierung beginnt auch hier bei 0 (anders als bei den meisten Dingen unter Delphi), da es sich um eine Windows-Komponente handelt (und bei Windows ziemlich überall die Indizierung bei 0 beginnt), denn das ist Standard bei C.
Aufteilung des Formulars
BearbeitenPanels
BearbeitenPanels sind sogenannte Container, vergleichbar mit dem DIV-Tag in HTML. Sie finden das Panel in der Registerkarte "Standard". Zieht es auf euer Formular. Soll es die ganze linke Seite einnehmen, oben, unten, rechts oder alles, so müssen Sie Align verändern. Im Objektinspektor wählen Sie eines der Einträge, also:
- alClient: alles einnehmen
- alLeft: Breite wie angegeben, Höhe passt sich dem Formular an, das Panel ist immer ganz links
- alRight: Breite wie angegeben, Höhe passt sich dem Formular an, das Panel ist immer ganz rechts
- alBottom: Höhe wie angegeben, Breite passt sich dem Formular an, das Panel ist immer ganz unten
- alTop: Höhe wie angegeben, Breite passt sich dem Formular an, das Panel ist immer ganz oben
- alNone: Standardeinstellung, Left, Top, Width und Height veränderbar.
Übrigens werden Sie feststellen, dass Sie so auch die Position einer Toolbar oder Statusbar verändern können, die haben nämlich standardmäßig alTop (Toolbar) / alBottom (Statusbar).
Weiterhin kann man noch die Eigenschaft Anchors nutzen, wobei man festlegt, ob die Position der Komponente abhängig vom Abstand nach links, rechts, oben oder unten zum jeweiligen Rand ihres Parents ist.
Splitter
BearbeitenDie TSplitter-Komponente finden Sie im Register "Zusätzlich". Zieht sie auf das Formular. Align ist veränderbar. Wenn sie zum Beispiel Align alTop hat und unter einem Panel, das ebenfalls alTop hat, durch Ziehen die Größe verändern. Das ist sinnvoll, weil jeder User eine andere Vorstellung von einer "guten" Größeneinteilung hat.
Registerkarten
BearbeitenRegisterkarten werden mit der Komponente TPageControl, die sich im Register "Win32" befindet, erstellt. Um eine neue Seite zu erstellen, klicken Sie im Kontextmenü eines neuen leeren PageControls auf "Neue Seite". Das geht unendlich oft (theoretisch, da der Speicher begrenzt ist). Dabei fällt auf, dass jede Seite ein einzelnes Objekt ist, nämlich ein TTabSheet. Das heißt, wenn man dem TabSheet1 den Parent PageControl2 zuweist, der vorher PageControl1 war, kann man das PageControl ändern. So kann man Seiten auch dynamisch erstellen (siehe Komponenten dynamisch erstellen).
Weiterhin kann man die Eigenschaft des TabSheets "Caption" für eine andere Aufschrift verändern. TabIndex legt den Rang innerhalb des PageControls fest. Visible stellen Sie auf false, wenn das Item nicht sichtbar sein soll, Visible des PageControls für eine veränderte Sichtbarkeit des PageControls, siehe auch die Methoden Hide und Show.
Mit der Eigenschaft des PageControls "HotTrack" legen Sie fest, ob das Item, über dem sich die Maus befindet, mit einer dunkelblauen Schrift (clNavy) erscheinen soll. Die Eigenschaft MultiLine legt fest, ob die Tabs über mehrere Zeilen verteilt werden sollen oder ob sich am Rand zwei Buttons zum Navigieren nach links und rechts befinden sollen. Style gibt das Layout für die Komponente an.
Mit Align (beim Panel behandelt) kann man, wie bei fast allen Komponenten, die Ausrichtung festlegen.
Trackbar und Scrollbar
BearbeitenBeide Komponenten sind eine Art "Slider", um bestimmte Werte einzustellen. Sie funktionieren ziemlich gleich: Es gibt Eigenschaften für Maximal- und Minimalwerte, nämlich Max und Min. Weiterhin gibt es das Ereignis OnChange. Diese tritt dann auf, wenn etwas bewegt wurde. Mit Orientation wird die Richtung, also horizontal oder vertikal festgelegt.
Bei der Trackbar kann man bei Frequency einstellen, in welchem Abstand Markierungs-Striche gezogen werden sollen. Und es ist möglich, einen Teil zu markieren, dafür werden wie im RichEdit die Eigenschaften SelStart und SelEnd verwendet, die allerdings als Public, nicht als Published deklariert sind und so nicht im Objektinspektor auffindbar sind.
TTrackbar ist unter "Win32", TScrollbar unter "Standard" aufzufinden.
GroupBox, RadioGroup und Checkbox
BearbeitenDiese drei Komponenten sind unter "Standard" aufzufinden.
- Die GroupBox ist eine Art Panel mit anderem Aussehen
- Die RadioGroup ist eine GroupBox mit mehreren Optionsfeldern, von denen genau eins gewählt werden kann
- Die Checkbox ist ein Feld für das angeben eines Zustands, also True oder False, welcher mit der Eigenschaft Checked festgelegt wird, auch bekannt als Kontrollfeld oder Check
Die Groupbox verfügt lediglich über die Eigenschaft Caption, die den Titel angibt, ansonsten funktioniert sie wie ein Panel und dient nur der Optik.
Die RadioGroup hat die gleichen Eigenschaften wie die Groupbox. Zusätzlich verfügt sie über "Items" für die Liste der Optionen als TStringList und ItemIndex (Indizierung beginnt bei 0), die die gewählte Option angibt.
Die Checkbox hat zwei wichtige Eigenschaften: Checked für den Zustand und Caption für die Beschriftung.
Fortschritt anzeigen
BearbeitenEin Fortschritt wird mit der TProgressBar angezeigt, welche sich im Register Win32 befindet. Mit Max und Min werden obere und untere Grenze festgelegt. Mit Position wird der Fortschritt angezeigt.
Alternativ zur Progressbar kann auch die TGauge genutzt werden. Sie befindet sich im Register "Beispiele" (Samples). Mit MinValue und MaxValue werden die Grenzen angegeben. ForeColor und BackColor treffen Aussagen über die Farbwahl. Mit Font kann die Schriftart verändert werden. Die Eigenschaft Progress gibt den Fortschritt an.
Anwendungsoptionen
BearbeitenUm der Anwendung einen Titel zu verpassen, der auch dann in der Taskleiste erscheint, sowie ein Icon (was man unter anderem mit kostenlosen Tools wie dem Borland Bildeditor, LiquidIcon oder IcoFX erstellen kann), müssen Sie Projekt / Optionen / Anwendung wählen. In den drei Editierfeldern geben Sie einfach die dazugehörigen Werte ein und klicken dann auf OK.
WinXP-Themes
BearbeitenFür Delphi ab Version 7: Hier finden Sie im Register "Win32" die Komponente TXPManifest. Diese ist eine nicht-visuelle Komponente und bindet nur die Unit XPMan ein. Für ein Löschen der Komponente muss also auch die Unit aus der Uses-Klausel entfernt werden.
Für ältere Versionen vor Delphi 7: Sie müssen die Manifest- und Resourcen-Dateien etwas komplizierter selbst erstellen. Zunächst legen Sie eine Datei "WindowsXP.manifest" mit folgendem Inhalt an:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity
type="win32"
name="DelphiApplication"
version="1.0.0.0"
processorArchitecture="*"/>
<dependency>
<dependentAssembly>
<assemblyIdentity
type="win32"
name="Microsoft.Windows.Common-Controls"
version="6.0.0.0"
publicKeyToken="6595b64144ccf1df"
language="*"
processorArchitecture="*"/>
</dependentAssembly>
</dependency>
</assembly>
Die Attribute name und version können entsprechend angepasst werden. Den Rest bitte unverändert lassen.
Anschließend benötigen Sie eine Resourcen-Datei. Legen Sie dazu eine weitere Textdatei namens "WindowsXP.rc" an und tragen Sie dort folgende Zeile ein:
1 24 WindowsXP.manifest
Nun an der Eingabeaufforderung eingeben:
brcc32 WindowsXP.rc
Gegebenenfalls müssen Sie noch den Pfad zum Borland-Programmverzeichnis davor schreiben bzw. den entsprechenden Pfad vor die .rc-Datei.
Dies erstellt eine Resourcendatei namens WindowsXP.res im gleichen Verzeichnis. Damit Ihr Programm nun die Windows XP-Stile annimmt, öffnen Sie den Quelltext Ihres Hauptformulars und tragen im 'implementation-Abschnitt, nach {$R *.dfm} folgendes ein:
{$R 'WindowsXP.res'}
Hiermit wird automatisch von Delphi eine Resourcendatei erzeugt und in Ihr Programm eingebunden. Nach dem nächsten Kompilieren verwendet Ihr Programm die XP-Themes.
Tipp: |
Die .res-Datei ist wiederverwendbar. Wer auf die gespeicherten Daten über den Programmnamen und die Version keinen Wert legt, kann die Datei z.B. in den Hauptprojektordner kopieren und von dort einbinden, z.B. mit {$R '..\WindowsXP.res'}. Auf diese Weise muss man die oben genannte Prozedur nur einmal durchgehen, bzw. spart sich das Kopieren der Datei. |
---|
Arbeit mit Tasten
BearbeitenTasten können auch simuliert und abgefangen werden, als negatives Beispiel für ein Backdoor oder einen Keylogger. Allerdings kann man das auch nützlich gebrauchen. Auch, wenn man fast alles davon eleganter lösen könnte.
Simulation
BearbeitenEin Screenshot wird mit der Taste DRUCK erstellt. Man kann diesen auch per Windows-API erzeugen, allerdings können wir mit zwei Codezeilen solch einen Tastendruck simulieren:
Keybd_Event(VK_PRINT, 0, 0, 0); Keybd_Event(VK_PRINT, 0, KEYEVENTF_KEYUP, 0);
Das sollte übrigens nicht nur unter Delphi funktionieren, sondern in allen Programmiersprachen, die einen Zugriff auf die Windows-API erlauben. Übrigens sollten Sie die zweite Zeile nie vergessen, denn diese sorgt dafür, dass die Taste auch wieder losgelassen wird. Sonst bleibt Sie ewig unten! Übrigens: Ein alphanumerischer Buchstabe, wzb. A kann einfach mit Ord('A') als ID simuliert werden.
Abfrage
BearbeitenEine Abfrage kann man zum Beispiel für ein Spiel gebrauchen. Man fragt mit einem Timer alle 100 Sekunden ab (Beispiel), ob eine Taste gedrückt ist (auch das geht eleganter, Stichwort Hook: allerdings ist dann die Gefahr groß, dass ein Anti-Viren-Programm eingreift). Dazu benutzen Sie die Funktion(en) GetAsyncKeystate oder GetKeyState:
if GetAsyncKeystate(VK_LEFT) < 0 then // Nach links bewegen
Übrigens finden Sie alle Tastencodes in der Delphi-Hilfe unter dem Stichwort Virtuelle Tastencodes.
Fremdkomponenten installieren
BearbeitenSie können auch Fremdkomponenten installieren. Diese enthalten meistens zwei Arten von Packages:
- Runtime-Packages
- DesignTime-Packages
Beide haben die Dateiendung ".dpk". Man kann sie meistens folgendermaßen unterscheiden:
- Runtime-Packages: Name = [Name]R[Version].dpk
- DesignTime-Packages. Name = [Name]D[Version].dpk
Zunächst muss man den Pfad, wo diese Packages gespeichert sind, Delphi kenntlich machen. Das geschieht (unter Delphi 7) über Tools / Umgebungsoptionen / Bibliothek. Nun fügt man im Editierfeld "Bibliothekspfad" ein Semikolon (;) und den Ordner, in dem die Packages gespeichert sind, an.
Jetzt wird der Dialog geschlossen.
Nun öffnet man zuerst das Runtime-, dann das DesignTime-Package. Ein neues Fenster öffnet sich. Nun klickt man dort bei beiden jeweils auf "Kompilieren", beim DesignTime-Package zusätzlich auf "Installieren". Achtung: Es soll hintereinander geschehen, also erst das Runtime-Package fertig, dann das DesignTime-Package beginnen.
Besteht die Komponente nur aus einer Unit, erstellt man über Datei / Neu / Package ein neues Package. Nun fügt man über das grüne Plus-Symbol die entsprechende Unit hinzu und speichert das Package im selben Ordner ab. Dieses Verzeichnis wird Delphi kenntlich gemacht und wie ein DesignTime-Package anschließend geöffnet, kompiliert und installiert.
Alternativ dazu kann man auch nur den Pfad zur Unit angeben (Tools / Umgebungsoptionen / Bibliothek ...) und anschließend die Komponente über Komponente / Komponente installieren ... im Menü in das Package "dclusr.dpk" aufnehmen. Dort wird die neue Unit gewählt, kompiliert und installiert.
Benötigt man sie nur, um sie dynamisch zu erstellen (was ja sowieso nur geht, wenn man den Turbo Delphi Explorer nutzt), reicht es auch, den Pfad zur Unit anzugeben.
Erstellung einer grafischen Oberfläche Fortgeschrittene Themen | Inhaltsverzeichnis | Komponentenentwicklung |