Bonjour andrebernard
En effet, etonnante coincidence, quand j'ai acheté purebasic (c'est a dire il y'a quelques mois), j'avais l'intention
de realiser le meme projet que le tien, un programme du meme genre que keynote, je me suis cependant rendu compte que
la tache aurait necessité beaucoups de temps car il fallait gerer un treeview, creer des convertisseur de format du
genre html vers rtf et vice versa, gerer ca dans une base de donnéé (pas evident avec purebasic au passage), compresser
les donnees, colorier les textes (encore pas evident avec pureb). certaines de ces taches peuvent etre realisé avec des
librairies existante que j'ai trouvé mais j'aurais perdu la possibilite du multiplateforme (linux), mais surtout le
plus important, c'est que le programme devait pouvoir etre utilisé a partir d'une cle usb. Devant la tache et avant de
reinventer la roue, je me suis demandé s'il n'existait pas un programme deja fait, j'ai trouvé keynote, ce programme
est tout simplement ideal avec quelques limitations (import html defaillant, gestion images lourdes), mais en fin de
compte apres un usage intensif, j'ai trouvé que le programme correspondait a mes besoins, et depuis je l'utilise pour
tous, gestion de codes sources de divers languages, carnet d'adresse, bookmark de site, trucs et astuces de tous type,
la fonction de recherche est assez efficace. concretement, j'ai donc laisser tomber le projet...
Depuis, j'ai trouvé d'autres programmes du meme genre :
Softnote :
www.softchris.com freeware tres prometteur, avantage utilise la base de donnee opensource firebird (connu et
reconnu pour sa fiabilité) d'ou la possibilite de gerer une grande masse de donnee avec une rapidite raisonnable...
TreeDBNotes :
www.softviewer.com freeware et commercial
Treepad :
http://www.treepad.com/ la version freeware est sans interet (trop limité), par contre la version commercial
vaut le coup si on accepte d'investir quelques dollars...
Pour le reste j'aimerais bien t'aider, mais je n'ai pas beaucoup de temps en ce moment, cependant concernant les dlls
avec pureb, j'ai une doc que j'avais referencé dans keynote, c'est en allemand mais le code est claire, sinon va voir
sur le site de l'auteur, peut etre qu'il y'a une version anglaise :
*** Debut ICI ***************************************************************
DLL-Tutorial
Auf Nachfrage ist dieses kleine Tutorial entstanden. Als Vorraussetzung nehme ich die Beschreibung zur DLL-Erstellung
in der PureBasic Hilfe. Ausserdem wird hier nicht die Erstellung sondern das Aufrufen der DLL’s an Hand von Beispielen
erklärt.
Wir übernehmen vorerst einmal das Beispiel aus der Hilfe und erweitern es noch ein bisschen:
Global ReturnString.s
ProcedureDLL.s MyFunction(var.s, Long.l)
ReturnString.s = var + " " + Str(Long)
ProcedureReturn ReturnString.s
EndProcedure
Dieses Beispiel kompilieren wir zu einer DLL namens „TestDLL.dll“. Dafür muss in den Compiler-Optionen das Executable
Format auf „Shared DLL“ eingestellt und das ganze ganz normal kompiliert werden (am besten in den Compilers\ - Ordner
vom PB-Verzeichnis, damit die DLL einfach verfügbar ist).
Nun kommen wir zum Aufruf der DLL:
Zuerst muss sie mit OpenLibrary() geöffnet werden:
If OpenLibrary(0, "TestDLL.dll")
Debug 1
EndIf
Nicht vergessen zu testen, ob sie wirklich geladen werden kann! Man könnte das ganze auch so machen (mit #PB_Any):
Lib.l = OpenLibrary(#PB_Any, "TestDLL.dll")
If IsLibrary(Lib)
Debug 1
EndIf
Dies kann bei grossen Projekten nützlich sein, jedoch werde ich hier die erste Variante wählen. Man kann es auch ganz
einfach umbauen. Einfach den Anfang wie oben nehmen und alle 0 (Nulls) bei Befehlen wie CallFunction(0,...) mit „Lib“
ersetzen (IsLibrary() wird später erklärt).
Nun ist die DLL im Speicher geladen und die folgenden Funktionen können benutzt werden:
CallCFunction
CallCFunctionFast
CallFunction
CallFunctionFast
CloseLibrary
CountLibraryFunctions
ExamineLibraryFunctions
IsFunction
IsFunctionEntry
IsLibrary
LibraryFunctionAddress
LibraryFunctionName
LibraryID
NextLibraryFunction
OpenLibrary
Die CallCFunctionX werde ich hier nicht beschreiben, da sie eigentlich nicht Windows Standard ist.
Nun werden wir mal als Übung ‚alle’ Funktionen der Library auslesen und ausgeben:
If OpenLibrary(0, "TestDLL.dll")
AnzahlFunktionen.l = CountLibraryFunctions(0)
Debug "Anzahl Funktionen: "+Str(AnzahlFunktionen)
If ExamineLibraryFunctions(0)
While NextLibraryFunction()
Debug "Name der Funktion: "+LibraryFunctionName()
Debug "Adresse der Funktion: "+Str(LibraryFunctionAddress())
Wend
EndIf
EndIf
CountLibraryFunctions(0) gibt einfach die Anzahl an Funktionen einer geladenen DLL zurück.
If ExamineLibraryFunctions(0) ladet die Funktionsinformationen der DLL um die einzelnen Funktionen nacheinander
durchzugehen.
While NextLibaryFunction(): Übersetzt: Während es eine nächste Funktion gibt. Diese Funktion schaut also, ob es eine
nächste Funktion gibt in dieser DLL und gibt 1 zurück wenn „ja“. Diese Funktion darf nur nach ExamineLibraryFunctions()
aufgerufen werden und geht die gefundenen Funktionen der Reihe nach durch.
LibraryFunctionName() gibt nun den Namen dieser Funktion zurück. Dieser Name kann für CallFunction() benutzt werden.
LibraryFunctionAddress() gibt die Speicheradresse dieser Funktion zurück. Diese Adresse kann für den Aufruf mit
CallFunctionFast() benutzt werden.
Nun wissen wir aber diese obigen Informationen schon und können die Funktion MyFunction() eigentlich direkt ansprechen:
If OpenLibrary(0, "TestDLL.dll")
Adresse.l = IsFunction(0, "MyFunction")
Debug PeekS(CallFunction(0, "MyFunction", "Das ist die Nummer", 42))
Debug PeekS(CallFunctionFast(Adresse, "Das ist die Nummer", 42))
EndIf
IsFunction() überprüft hier, ob die Funktion wirklich existiert und gibt dann ihre Speicheradresse zurück, die man bei
CallFunctionFast() benutzen kann.
CallFunction() ruft die Funktion mit ihrem Namen auf und ist langsamer als CallFunctionFast(). Die Parameter werden
dabei nach der LibraryID und dem Funktions-namen (achtung! auf Gross- und Kleinschreibung achten) mit Kommas abgetrennt
angegeben. Zuerst der String, dann die Zahl.
CallFunctionFast() funktioniert gleich, nur muss hier anstatt der Name und die LibraryID nur die Adresse der Funktion
angegeben werden.
Vielleicht wundern sie sich, warum man PeekS() verwenden muss um einen String als Resultat zu erhalten. Das liegt
daran, dass eine Funktion in einer DLL keinen Rückgabetyp angibt und PureBasic desshalb nicht weiss, von welchem Typ
der Rückgabewert ist. Zurückgegeben wird also einfach die Adresse des Strings, womit der String schnell mit PeekS()
abgerufen werden kann.
Aus diesem Grund schreibt man gerne eine kleine Wrapper-Prozedur, die wie folgt aussehen könnte:
Procedure.s MyFunction(var.s, Long.l)
ProcedureReturn PeekS(CallFunction(0, "MyFunction", var, Long))
EndProcedure
Diese Funktion ist natürlich langsamer, wegen dem Doppelfunktionsaufruf und dem benutzen von CallFunction anstelle von
CallFunctionFast. Letzteres kann leicht geändert werden, aber das überlasse ich ihnen.
Nun folgt noch eine kleine Beschreibung der Fehlenden Funktionen:
CloseLibrary
Diese Funktion ist v.a. nützlich, wenn sie mehrere DLLs laden. Da PB die Library automatisch beim Beenden des Programms
schliesst, ist sie nicht nötig, aber doch noch schön. Ausserdem sollte sie beim Auftreten eines Fehlers im Programm
aufgerufen werden (benutze OnError-Lib).
IsFunctionEntry
Dazu kann ich nicht mehr sagen als in der Hilfe steht, ich habe sie noch nie benutzt!
IsLibrary
Diese Funktion sollte nach dem Öffnen der Library zum Testen, ob die Library wirklich bereit ist, benutzt werden.
LibraryID
Gibt das Api – Handle zurück, welches für die Windows API verwendet werden kann.
Laden von Windows DLLs
Das Laden von Windows DLLs funktioniert ziemlich gleich wie oben, nur dass die Informationen dafür aus der Win32Help,
MSDN oder sonst wo entnommen werden müssen.
(
http://msdn.com)
Das Laden am Beispiel der Api-Funktion timeGetTime() (die in PB zwar auch mit timeGetTime_() aufgerufen werden kann
(ist ja nur ein Beispiel)):
Im MSDN steht folgendes:
DWORD timeGetTime(VOID);
und
Requirements
Windows NT/2000/XP: Included in Windows NT 3.1 and later.
Windows 95/98/Me: Included in Windows 95 and later.
Header: Declared in Mmsystem.h; include Windows.h.
Library: Use Winmm.lib.
Die obere Linie beschreibt die Funktion, Rückgabewert DWORD (in PB = Long), Name und Parameterliste VOID (was soviel
heisst wie: keine Parameter).
Bei den Requirements verrät uns das Library, welche Library wir laden müssen, nur heisst die nicht Winmm.lib sondern
Winmm.dll .
Und nun zum Code:
If OpenLibrary(0, "Winmm.dll")
Debug CallFunction(0, "timeGetTime")
Debug timeGetTime_()
EndIf
Die Library kann also einfach mit dem Namen geladen werden (ohne Ordnerangabe und nichts) und die Funktion wie vorher
mit CallFunction() aufgerufen werden. Daneben der Vergleich zu der ‚integrierten’ Funktion von PB (timeGetTime_()).
Manchmal steht auch noch so was wie:
GetTempPathW is supported by the Microsoft Layer for Unicode.
Z.B. bei der WinAPI-Funktion GetTempPath(), das bedeutet, dass es zwei Versionen von ihr gibt. Nämlich eine normale und
eine Unicode-Variante. Die normale Variante ist markiert durch ein A und die Unicode-Variante durch ein W:
GetTempPathA() und GetTempPathW(), dabei wird in PureBasic nur die A Variante unterstütz!
Hier das Beispiel:
Procedure.s GetTempPath()
lib = OpenLibrary(#PB_Any, "Kernel32.dll")
If IsLibrary(lib)
A$ = Space(1024)
CallFunction(lib, "GetTempPathA", 1024,A$)
CloseLibrary(lib)
ProcedureReturn A$
Else
ProcedureReturn ""
EndIf
EndProcedure
So das war’s vorerst mal.
Danke fürs Zuhören und viel Spass noch!
euer Remi
© by Remi Meier Jan. 2005
E-Mail:
remi_meier@gmx.ch
Website:
http://www.remimeier.ch.vu
*** Fin ICI ***************************************************************