Einführung
Die Fähigkeiten und Funktionen
von Windows sind manchmal sehr beeindruckend, was liegt also näher, als
sich ein paar von diesen Fähigkeiten auszuborgen. Dies funktioniert auch
und im Gegensatz von anderen Möglichkeiten ganz legal, denn es gibt eine
Schnittstelle die Win32API, die es Programmen erlaubt auf die Fähigkeiten
des Betriebssystems zuzugreifen. Der Begriff Win32API steht für Windows32
Application Programming Interface (Windows32 steht hier für das 32bit
Windows also Windows9x/Me und NT/2000/XP).
Die Fähigkeiten von Windows werden als Funktion in das Visual Basic Projekt
eingebunden, die Syntax für eine solche API-Funktionseinbindung lautet
allgemein so:
[Public | Private] Declare Function name Lib "libname"
[Alias "aliasname"] [As type]
Wirkungsbereich
der API-Funktion
Mit Public oder Private wird der "Wirkungsbereich" der Funktion
festgelegt. Public ist, wie der Name schon sagt für das ganze Projekt
zugänglich, Private nur in der Prozedur in der die API-Funktion eingebunden
ist. Declare ist das Schlüsselwort, dass anzeigt, dass es sich
um eine API-Deklaration handelt. libname ist der Name der .dll
(der genaue Pfad muss nicht angegeben werden, denn Windows sucht automatisch
im System-Verzeichnis). Bei den drei Hauptbibliotheken (kernel32, user32
und gdi32) muss auch das .dll nicht angehängt werden. Alias ist
nur erforderlich, wenn der name und der aliasname nicht
übereinstimmen. Einer der häufigsten Fehler, die in Verbindung mit der
Verwendung der Win32-API gemacht werden, sind dass kein Rückgabewerttyp
deklariert wird. Der Standardtyp Variant führt häufig zu einem Fehler
oder zu einer Speicherausnahme. Die meisten API-Funktionen haben einen
Long-Datentyp als Rückgabewert. Wem das As... zu lange ist, kann im Variablennamen
gleich das Typenzeichen voranstellen (% für Integer, & für Long)
- kernel32.dll
Diese .dll enthält Funktionen,
die mit dem Kernel (Betriebssystemkern) zusammenhängen, wie z.B. zur
Speicherverwaltung oder die meisten Ein- und Ausgabefunktionen für Geräte.
Du brauchst bei dieser Bibliothek kein .dll anzuhängen.
- user32.dll
Diese .dll enthält Funktionen,
die mit der Benutzeroberfläche (Fenster,...) zusammenhängen, wie z.B.
Funktionen zur Erstellung von Fenstern, Steuerelementen und Dialogfeldern.
Du brauchst bei dieser Bibliothek kein .dll anzuhängen.
- gdi32.dll
Diese .dll enthält Funktionen,
die mit der grafischen Ausgabe auf dem Bildschirm und dem Drucker zu
tun haben, hierzu gehört auch die Textausgabe.
Du brauchst bei dieser Bibliothek kein .dll anzuhängen.
- winmm.dll
Diese .dll enthält Funktionen,
die mit Multimediafunktionen in Verbindung stehen, wie z.B. die Steuerung
von Audio-, Videogeräten und Joysticks.
Es ist das Anhängen von '.dll' erforderlich!
- shell32.dll
Diese .dll enthält Funktionen,
die mit der Benutzerschnittstelle auf einer hohen Ebene zu tun haben,
wie z.B. Drag&Drop-Operationen für Dateien oder die Verwaltung von
Verknüpfungen zwischen Dateien.
Es ist das Anhängen von '.dll' erforderlich!
Beispiel
für eine API-Deklaration
Das auf ein konkretes Beispiel anzuwenden, heißt die API-Deklaration
für einen Zugriff auf die gdi32-Biblothek (Graphic Device Interface (enthält
Funktionen für die Grafikausgabe auf dem Bildschirm und die Druckausgabe)
so:
Private Declare
Function Polygon Lib "gdi32" (ByVal hdc As Long, lpPoint As ¬
POINTAPI, ByVal nCount As Long) As Long
Aus der Bibliothek
gdi32.dll wird die Funktion Polygon importiert, diese enthält die Variablen
hdc, die vom Long-Datentyp ist, die Variable lpPoint deren Datentyp vorher
Benutzerdefiniert wurde und die Long-Variable nCount. Bei den Variablen
nCount und hdc wird mit dem Schlüsselwort ByVal die Variable als Wert
überwiesen (Das Gegenteil wäre ByRef, bei dem aus dem Variableninhalt
ein Verweis gemacht wird).
An dieser Deklaration ist gut zu sehen, dass man bei der API-Deklaration
sehr auf die Datentypen achten muss. Das API-Interface besteht aus C++-Syntax
und C++ nimmt es etwas enger mit Datentypen als Visual Basic.
Beispiel-Projekt
Polygon
Ich denke an einem kleinen Beispiel können wir unsere trockenen Theoriekenntnisse
einsetzten. Weil die Theorie sehr trocken (aber hoffentlich nicht langweilig)
war, wollen wir einmal etwas malen (lassen). Wir werden die Bibliothek
gdi32.dll dazu verwenden und die oben beschriebene Funktion Polygon zum
Zeichnen von einem kleinen Bild verwenden.
Projekt
erstellen
Starte VB und lege ein neues Projekt an, an dem dann erscheinenden
Formular soll nichts verändert werden. Wir wechseln stattdessen gleich
in die Quelltextansicht und geben als erstes die Definition des benutzerdefinierten
Datentyps POINTAPI an:
Private Type POINTAPI
X As Long
Y As Long
End Type
API-Funktion
einfügen
Nun, da VB der Datentyp bekannt ist, können wir die Funktion Polygon
in unser Projekt einfügen:
Private Declare Function Polygon Lib "gdi32" (ByVal hdc As ¬
Long, lpPoint As POINTAPI, ByVal nCount As Long) As Long
Zeichnungs-Prozedur
einfügen
Nun erstellen wir eine Prozedur, die das Zeichnen übernehmen soll:
Private Sub LoadPointArray(ByVal width As Long, ByVal Height ¬
As Long, ByVal Increment As Integer, PointArray() As POINTAPI)
Dim curidx As Integer
ReDim PointArray((Height \ Increment) + 2)
Do
curidx = curidx + 1
PointArray(curidx).X = width
PointArray(curidx).Y = Height - curidx * Increment
curidx = curidx + 1
PointArray(curidx).X = 0
PointArray(curidx).Y = curidx * Increment
Loop While curidx * Increment < Height
End Sub
Aufruf
der Funktion einfügen
Nun noch den Aufruf des Formulars zum Zeichnen Form_Paint:
Dim points() As POINTAPI
LoadPointArray ScaleWidth / Screen.TwipsPerPixelX, ScaleHeight / Screen.TwipsPerPixelY ¬
5, points()
Result = Polygon(hWnd, points(0), UBound(points) + 1)
Call Polygon(hdc, points(0), UBound(points) + 1)
End Sub
Was
zu beachten ist
Hier ist es nötig, dass X (bzw. Y) erst vom Pixel in das Visual Basic
interne Twips Größeformat umgewandelt werden muss, sonst erhält man nur
eine vergrößerte Ecke des Bildes im Fenster.
Zum
Abschluss
Und zu guter Letzt noch eine kleine Anweisung, damit dass Bild auch
noch in voller Bracht erscheint, wenn die Größe des Formulars vom Benutzer
bei Laufzeit verändert wird:
Private Sub Form_Resize()
Refresh
End Sub
Nun sollte es nach der Ausführung
so aussehen:
|