Hier handelt es sich um Sachen aus dem letzten Jahrtausend ;). Programmiert wurden die Beispiele mit Borland Delphi 2/4 und Inprise Delphi 5. Ich verwende immernoch Delphi 5 und obwohl es so alt ist kann man die Programme problemlos auch noch auf Windows 10 laufen lassen.
Erstellt von tom am Di, 2005-03-08 11:51.
Sqlite verwendet SQL Befehle um auf eine "lokale" Datenbank zu zugreifen. Dies ist etwa vergleichbar mit dem Zugriff auf eine DBase-Datenbank. Allerdings kann man bei Sqlite direkt per SQL zugreifen und der wohl größte Vorteil ist, dass man die BDE nicht mitliefern muss um es zu nutzen.
Sqlite wird auch mit php5 mitgeliefert und man kann davon ausgehen, dass Bugs, soweit vorhanden, somit schnell erkannt und beseitigt werden.
Sqlite findest du unter: http://sqlite.org
Für Delphi gibt es auch schon eine Komponentensammlung, die mit Sqlite arbeitet (SQLITE open source components) . Diese basiert auf TDataset und somit sind alle "Datensteuerung"s-Komponenten verwendbar.
Die Komponentensammlung findest du unter http://www.aducom.com/sqlite/
Achtung: die in der aktuellen Version 2005.02.A ist eine sqlite3.dll beigelegt, die nicht funktioniert. Einfach die Dll direkt von Sqlite verwenden, dann geht es ;)
Erstellt von tom am So, 2005-03-06 21:42. Delphi erzeugt relativ große Exe-Dateien. Wenn du diese ohne großen Aufwand schrumpfen möchtest solltest du dir UPX (http://upx.sourceforge.net/) anschauen. Der Download deiner Software wird kleiner, was deine Kunden freut ;)
Erstellt von tom am So, 2005-03-06 21:09.
Wer auf Paradox-Dateien in Netzwerk zugreifen will, sollte nicht gleich verzweifeln, wenn die Meldung kommt: Die Datei sei gesperrt oder der Zugriff nicht möglich. Ich habe lange daran gebissen und dann die Lösung gefunden.
Beim Form Create tragt Ihr einfach die Zeile Session.NetFileDir='X:\MeinNetz';
ein und das war's. Achtung, vorher darf noch keine DB-Komponente auf die Datenbanken zugreifen!!! Sonst nutzt das alles nix, wenn ein 2ter Benutzer was machen will. Achso außerdem muss bei allen Benutzern das gleiche eingetragen sein - also Mappings überall gleich anlegen!
Noch etwas, den Eintrag kann man auch in der BDE-Konfig. machen aber naja, dann muss man die auch noch verwalten...
Erstellt von tom am So, 2005-03-06 21:07.
Wenn man Hintergrundbitmaps in der Coolbar verwendet verhalten sich die Toolbars, die auf der Toolbar sitzen etwas seltsam wenn man die Farbtiefe von 256 Farben einstellt. Um das ganze zu umgehen, kann man Hintergrundbitmaps mit 16 Farben verwenden, was allerdings nicht sehr schön aussieht. Wenn ich davon ausgehe, dass die Mehrzahl der Windows Benutzer heute mehr als 256 Farben haben, bin ich zu der Entscheidung gekommen diesen Benutzern einfach das Hintergrund vorzuenthalten. Also muß ich beim Formcreate die Farbetiefe ermitteln und die Bitmap aus dem Speicher entfernen. Delphi stellt leider keine eigene Function zur Verfügung um die Farbtiefe zu ermitteln aber keine Angst die folgende Function liefert die Farbtiefe:
Function GetColorDepth:byte;
{Results:
4=> 16 Farben
8=> 256 Farben
16=> 24KB Farben
24=> True Color
}
begin
Result:=GetDeviceCaps(GetDC(
GetActiveWindow),BITSPIXEL);
end;
Im FormCreate füge ich also folgende Zeile ein:
If GetColorDepth<16 then Coolbar1.bitmap:=nil;
Dies funktioniert natürlich auch, wenn man andere components verwendet, die z.B. den Formhintergrund füllen. Oder lädt zur Laufzeit unterschiedliche Bitmaps für die unterschiedlichen Farbtiefen.
Erstellt von tom am So, 2005-03-06 21:04. Delphi
Ich kenne nun einige Methoden um aus Delphi heraus andere Anwendungen zu starten. Die einfachste ist wohl Winexec. Winexec stammt aber noch aus der 16bit Zeit und deshalb nur mit Vorbehalt zu empfehlen. Die größte Schwierigkeit unter Win32 bzw. seit Delphi 2 besteht darin die eigene Anwendung solange anzuhalten, wie das andere Programm ausgeführt wird. Sicherlich braucht man das nicht immer, aber diese Routine beherrscht es :-)
function fileExec(const aCmdLine: String; aHide, aWait: Boolean): Boolean;
var
StartupInfo : TStartupInfo;
ProcessInfo : TProcessInformation;
begin
{setup the startup information for the application }
FillChar(StartupInfo, SizeOf(TStartupInfo), 0);
with StartupInfo do
begin
cb:= SizeOf(TStartupInfo);
dwFlags:= STARTF_USESHOWWINDOW or STARTF_FORCEONFEEDBACK;
if aHide
then wShowWindow:= SW_HIDE
else wShowWindow:= SW_SHOWNORMAL;
end;
Result := CreateProcess(nil,PChar(aCmdLine), nil, nil, False,
NORMAL_PRIORITY_CLASS, nil, nil, StartupInfo, ProcessInfo);
if aWait then
if Result then
begin
WaitForInputIdle(ProcessInfo.hProcess, INFINITE);
WaitForSingleObject(ProcessInfo.hProcess, INFINITE);
end;
end;
Ich muß hinzufügen, dass diese Routine nicht von mir selbst ist. Mit freundlicher Erlaubnis des Author Stefan Böther kann man die angehängten XProcs hier downloaden ;)
Anhang | Größe |
---|---|
xprocs.zip | 46.99 KB |
Erstellt von tom am So, 2005-03-06 21:01.
Daten in einer Baumdarstellung darzustellen, ist eine feine Sache, wenn man weiß wie. Die TTreeview-Component ist nicht besonders benutzerfreundlich, und so schrecken viele Programmierer davor zurück. Doch die Vorteile dieser wirklich übersichtlichen und benutzerfreundlichen Darstellungsweise alla Windows-Explorer ist nicht von der Hand zuweisen.
Ich habe für die Feburarausgabe des Delphianer ein kleines Projekt erstellt, welches die Funktionsweise von TTreeView an einem einfachen Beispiel zeigt. Der Quelltext enthält Beschreibungen zu den einzelnen Proceduren und Functions. also einfach downloaden und ausprobieren.
Anhang | Größe |
---|---|
feb99.zip | 6.7 KB |
Erstellt von tom am So, 2005-03-06 20:59.
Im letzten Excel-Beispiel habe ich gezeigt, wie einfach der Zugriff auf Excel ist und genauso einfach kann man auch auf MS-Word zugreifen und Briefe mit der Geisterhand schreiben. Auch hier werde ich nur den grundsätzlichen Zugriff erklären und wie man sich über Makroaufzeichnung den nötigen Quelltext für Delphi erarbeiten kann.
Zuerst habe ich mir folgendes Macro aufgezeichnet:
Sub Makro1()
Documents.Add
Selection.TypeText Text:= "Hallo Leute, dies ist ein Zugriff über Delphi :-)"
Selection.TypeParagraph
Selection.TypeParagraph
Selection.Font.Bold = wdToggle
Selection.Font.Size = 12
Selection.Font.Name = "Arial"
Selection.TypeText Text:="Toll oder?!"
End Sub
Mit diesem Macro erstelle ich mir meinen Delphiquelltext:
1. Als erstes muß ich die benötigte Unit in die uses clausel aufnehmen:
uses OLEAuto //in Delphi 2
uses ComObj //in Delphi 3 und 4
2. Ich deklariere die Variable MSWord für den Zugriff auf Word
var MSWord:variant;
3. Nun muß ich noch eine Verbindung mit Word herstellen und ggf. abbrechen, wenn ein Fehler auftritt.
try
Msword := CreateOleObject('Word.Application');
except
ShowMessage('WORD konnte nicht gestartet werden !');
Exit;
end;
4. Wenn ich die Verbindung erfolgreich herstellen konnte, kann ich loslegen zu schreiben:
Macrosource | Delphisource | Beschreibung |
Documents.Add | MsWord.Documents.Add; | Neue Datei, |
Selection.TypeText Text:= "Hallo Leute, dies ist ein Zugriff über Delphi :-)" | MsWord.Selection.TypeText(Text:='Hallo Leute, dies ist ein Zugriff über Delphi :-)'); | normalen Text einfügen |
Selection.TypeParagraph | MsWord.Selection.TypeParagraph | Leerzeile |
Selection.Font.Bold = wdToggle | MsWord.Selection.Font.Bold := true; | Fett |
Selection.Font.Size = 12 | MsWord.Selection.Font.Size := 12; | Fontsize=12 |
Selection.Font.Name = "Arial" | MsWord.Selection.Font.Name := 'Arial'; | Arial-Font |
Selection.TypeText Text:="Toll oder?!" | MsWord.Selection.TypeText(Text:='Toll oder?!'); | nun den formatierten Text |
4. Wenn ich die Verbindung erfolgreich herstellen konnte, kann ich loslegen zu schreiben:
Msword.visible:=true;
Fertig! Viel Spaß beim "Ghostwriting" mit Delphi in Word.
Erstellt von tom am So, 2005-03-06 20:54.
Der Umgang mit Zeichenketten ist eine wichtige Aufgabe. Delphi bringt einige Funktionen mit die zwar sehr flexibel, aber im täglichen Umgang sehr zeitintensiv sind.
Beispiel:
Ich möchte einige Informationen in einer einzigen Zeichenkette unterbringen und mit einem Zeichen separieren. Das zusammensetzen einer solchen Information ist eigentlich ganz einfach. Nehmen wir an, ich möchte mir eine Adresse mit 6 Feldern in einer Zeichenkette ablegen und mit dem Zeichen | trennen. Ich habe mehrere Adressen, deshalb lege ich alles in einer Stringliste ab.
Felder : NAME, STRASSE, PLZ, ORT, TEL, FAX, EMAIL
AdrLst:=TStringlist.create;
AdrLst.Add('Hans Mustermann|Musterweg 9|12345|Musterstadt|(012345) 7788990|(012345) 7788991|hmuster@och.com')
AdrLst.Add('Franz Mustermann|Musterweg 9|12345|Musterstadt|(012345) 7788996|(012345) 7788999|fmuster@och.com')
u.s.w.
Jetzt könntest Du frage, warum mache ich das ganze nicht als Record und speichere das als typisierte Datei ab. Ganz einfach, um mir den Aufwand mit dem Zugriff auf typisierte Dateien zu sparen und ich nicht so viele Datensätze habe, speichere ich alles in eine INI-Datei ab und hole die Daten bei Bedarf aus der INI-Datei in den Speicher (TStringlist).
Ich möchte nun die einzelnen Felder in Editfelder einlesen und bei Bedarf wieder speichern. Dazu muss ich mir noch merken auf welchem Datensatz ich stehe, welches Feld geändert wurde, umsortieren u.s.w. - das spare ich mir aber nun, denn ich wollte nur ein Beispiel dafür bringen, wozu ich Zeichenketten teilen muss. Obwohl ich im Laufe der Zeit eine Reihe von guten Stringbehandlungsroutinen als Freeware gefunden habe, habe ich mir selbst eine function gebastelt, die für diesen Fall geeignet ist:
function ValuestrNr(instr:string;seperator:char;nr:byte):string;
var tmpcnt:byte;
tmpout:string;
begin
tmpcnt:=0;tmpout:='';
while (pos(seperator,instr)>0) and (tmpcnt<nr) do
begin
inc(tmpcnt);
if tmpcnt=nr then tmpout:=copy(instr,1,pos(seperator,instr)-1);
delete(instr,1,pos(seperator,instr));
end;
if (length (instr)>0) and (tmpcnt+1=nr) then tmpout:=instr;
ValuestrNr:=tmpout;
end;
Dies ist nur eine function, um einen separierten Teilstring aus einer Zeichenkette zu extrahieren. Eine komplette Sammlung von Stringbehandlungsroutinen sind z.B. in den beliebten RX-Tools (erhältlich auf der Torry's Delphi Page) enthalten. Schaut euch dort die Unit StrUtils an!