Zum Inhalt springen

Programmieren mit dBASE PLUS: API-Lösungen

Aus Wikibooks


Das Application-Programming-Interface ist die Schnittstelle zwischen einem beliebigen Programm und der Aussenwelt. Diese Schnittstelle besteht aus Funktionen, die die Fähigkeiten des Programms anderen Applikationen zugänglich machen.

Das wohl bekannteste und am besten dokumentierte API ist das Windows-API! Diese Schnittstelle (mehrere tausend Funktionen) ermöglicht den Zugriff auf alle Aktivitäten, die vom Betriebssystem zur Verfügung gestellt werden: Dateiverwaltung, Userverwaltung, Fensterverwaltung aber auch z.B. direkten Zugriff auf die Hardware...

Beispiele für andere Anwendungen, die ihre Funktionalität über ein AP-Interface öffentlich machen sind: die BDE, der Report-Writer List und Label oder verschiedene Email- und FTP-Clients.

Wie diese Funktionen genutzt werden können, soll im folgenden Schritt für Schritt erläutert werden.

Wo findet man was?

[Bearbeiten]

Die erste Hürde bei der Nutzung von API-Funktionen besteht darin, die richtige zu finden! Die Funktionen haben zwar alle einen möglichst aussagekräftigen Namen, das nutzt aber leider nichts, wenn man diesen Namen erst mal nicht kennt. Es gibt kein Patentrezept, um den API-Aufruf zu entdecken, den man braucht. Hier kann man nur empfehlen, sich die Windows OLH von der dBI-Site herunterzuladen ([1]) (leider schon etwas betagt) oder im aktuellen MSDN zu suchen ([2]) (leider nicht sehr übersichtlich).

Erfahrung mit der AP-Schnittstelle zu besitzen bedeutet im Wesentlichen zu wissen, wo was steht!

Will man gar die APIs von Drittanbietern nutzen, so braucht man unbedingt deren Dokumentation. Hier kann ganz klar gesagt werden: wenn die API-Funktionen nicht sauber dokumentiert sind, kann man sie nicht nutzen!

Selbst wenn man ihren genauen Namen weiß, reicht das nicht aus, da jede Funktion sowohl einen eindeutig typisierten Rückgabewert als auch genau vorgeschriebene Eingangsparameter verlangt (diese müssen bekannt sein).

Parameter

[Bearbeiten]

Ähnlich wie dBase-Funktionen, erwarten API-Funktionen Parameter. Diese Parameter sind nicht optional wie bei dBase sondern müssen zwingend angegeben werden. Außerdem ist der Typ der Parameter vorgegeben und darf nicht geändert werden. Dies ist eine weitere Hürde für dBase-Programmierer, da hier überhaupt keine Typen vorgesehen sind. Implizit gibt es sie zwar doch (etwa wenn die dbase-Funktion "ltrim" mit einer Zahl gefüttert wird und die Fehlermeldung : "inkompatibler Datentyp " ausgegeben wird), der Typ einer Variablen ist jedoch kontext-abhängig und kann jederzeit problemlos geändert werden.

a = 9         // Variable a hat den Typ : Numerisch
a = a + " b"  // Variable a hat jetzt den Typ : Zeichen

Wie kann dBase nun wissen, welche Parameter erwartet werden und von welchem Typ diese sind? Hier kommt der für API-Aufrufe unverzichtbare Befehl "extern" ins Spiel ...

Email-Lösungen

[Bearbeiten]

Aktiven Email-Client öffnen

[Bearbeiten]

Unter Nutzung des Windows-API werden einem beim Anwender installierten und als Standard eingetragenen E-Mail-Client Daten übergeben und dieser gestartet.

Da der Entwickler nicht davon ausgehen kann, dass der Anwender immer nur einen bestimmten E-Mail-Client benutzt, muss sicher gestellt sein, dass immer derjenige gestartet wird, der auf der entsprechenden Workstation als Standard eingestellt wurde. Speziell in einer Netzwerkumgebung werden auf den verschiedenen Arbeitsstationen oft unterschiedliche Clients wie Outlook, Outlook Express, Thunderbird etc. genutzt.

Leider ist es mit dieser Methode nicht möglich, Anhänge (attachments) zu verschicken. Das mailto-Protokoll auf dem die unten gezeigte Lösung basiert, ist durch folgendes Dokument spezifiziert : [3] Hierbei ist keine Eintragung für Attachments im Header vorgesehen. Das bedeutet nicht, dass einzelne Clients das Attachment-Feld im Header nicht verstehen würden, sondern dass es keine Garantie gibt, dass jedes Email-Programm Attachments verschicken kann.

Falls man darauf angewiesen ist, Anhänge zu verschicken, muss man seiner dBase-Applikation einen eigenen Email-Client zur Verfügung stellen etwa : Funcky oder ASPMail

Anmerkung: Es gibt auch eine, wenn auch kostenpflichtige, gut dokumentierte Email-DLL von Marshallsoft, mit der je nach Bedarf sogar ein eigener kompletter Email-Client programmiert werden kann. Die DLL kann kostenfrei mit den eigenen Applikationen weitergegeben werden.

Danke an Lutz Conrad für dieses Beispiel:

//Direkte Verwendung im Befehlsfenster
//SET PROCEDURE TO EMailTest.PRG ADDITIVE
//SendMail(<Empfänger>,<Betreff>,<Inhalt>,<Kopieempfänger>,<Blindkopieempfänger>)
#INCLUDE WinDef.H
#INCLUDE WinUser.H
FUNCTION SendMail(cDest,cSubject,cBody,cCC,cBCC)
LOCAL cSystem

cSystem=OS()
IF EMPTY(cDest)
   cDest="mailto:alfred@work.de"
ELSE
   cDest="mailto:"+cDest
ENDIF
IF EMPTY(cSubject)
   cSubject="EMail Test"
ENDIF
IF EMPTY(cBody)
   cBody="Hallo Zusammen"
ENDIF
IF EMPTY(cCC)
   cCC="lutz@work.de"
ENDIF
IF EMPTY(cBCC)
   cBCC="alfred@home.com"
ENDIF
cDest+=IIF(EMPTY(cSubject),""," ?Subject="+cSubject)
cDest+=IIF(EMPTY(cCC),""," &CC="+cCC)
cDest+=IIF(EMPTY(cBCC),""," &BCC="+cBCC)
cDest+=IIF(EMPTY(cBody),""," &Body="+cBody)
IF "4.0"$cSystem .OR. "4.1"$cSystem
   WinExe(cDest,1)
ELSE
   ShellExe(1,"open",cDest,NULL,NULL,NULL)
ENDIF
RETURN

FUNCTION ShellExe(hWnd,cOperation,cFile,cParam,cDir,nShow) //  Führt eine Anweisung aus
LOCAL nResult

EXTERN CHANDLE  ShellExecute(CHANDLE,CSTRING,CSTRING,CSTRING,CSTRING,CINT) shell32  FROM "ShellExecuteA"
IF EMPTY(cFile)
   nResult=0
ELSE
   IF EMPTY(hWnd)
      hWnd=1
   ENDIF
   IF EMPTY(cOperation)
      cOperation="open"
   ENDIF
   IF EMPTY(nShow)
      nShow=SW_SHOWNORMAL
   ENDIF
   nResult=ShellExecute(hWnd,cOperation,cFile,cParam,cDir,nShow)
ENDIF
RETURN (nResult>32)

FUNCTION WinExe
PARAMETER p1,p2

EXTERN CINT WinExec(cSTRING,CINT) kernel32
TRY
   WinExec([start "&p1"],p2)
CATCH (exception e)
   TRY
      WinExec('start "&p1"',p2)
   CATCH (exception e)
      TRY
         WinExec("start [&p1]",p2)
      CATCH(exception e)
         MSGBOX("String zu komplex","Achtung",16)
      ENDTRY
   ENDTRY
ENDTRY
RETURN