Nachdem ich den Font-Free-Fehler aus FMX.TextLayout.pas beseitigt habe, konnte ich die TextLayout Ausgabe aus FMX.Canvas.D2D.pas entsprechend erweitern, sodass es endlich möglich ist Formatieren Text mit verschieden farbigen Paragraphen ausgeben zu können.
Hierfür waren einige Eingriffe in die Grundroutinen nötig.
Das Ergebnis sieht dann - so wie man es eigentlich erwartet - so aus:
Ich werde meine Änderungen mal an EMBT senden...
PS: Die Blocksatzroutine ist kein Feature per D2D mit DWRITE_TEXT_ALIGNMENT_JUSTIFIED das ist natürlich für Windows nur eine Zeile... "Meine" Blocksatz Routine funktioniert auf allen Plattformen.
Saturday, September 24, 2016
Friday, September 23, 2016
FMX & Blocksatz
Hallo!
Leider kann FMX - genau wie die alten RTF Routinen - kein Blocksatz. Da ich aber Texte am liebsten im Blocksatz lese, habe ich einen kleinen Wrapper für das Layout-Rendering programmiert.
Schriftumschaltungen wie Fett usw. funktionieren schon.. Farbige Texte noch nicht, da die Windows Routine das leider nicht kann. Es gibt auch leider zwischen den Plattformen noch einige unterschiede, aber das wird der Wrapper berücksichtigen.
Thursday, September 22, 2016
FMX - IFDEF oder gibt es etwas besseres.
Warum haben wir IFDEF's in unseren Sourcecode?
Weil wir:
Gibe es hier nicht bessere Lösungen?
Na Klar...
Nicht für alle 4 Punkte...
Um es einfach zu sagen: Die RTL macht es vor!
Über die Plattform-Dienste werden die eigentlichen Implementationen je nach Plattform registriert und der Rest linked gegen ein Interface...
Wenn es gut genug ist für dir RTL - sollten wir dieses Designpattern auch in unseren Applications anwenden.
Aber was ist, wenn wir kein IFDEF nehmen können, weil wir zur Laufzeit entscheiden müssen?
Klar nen IF auf eine Variable wird jeder sagen!
Ich mache es so (vereinfacht für das Beispiel! Im eigentlich Code passe ich das Ganze noch an den Text an):
type
TMyOSPlatform = (Windows, OSX, iOS, Android);
TOSPlatforms = Set of TMyOSPlatform;
Procedure InitFMX;
begin
TGetByID.Default.Register(Windows,
Function (Const Prop : String) : Single
begin
Case TFDKHelper.CaseSelector(Uppercase(Prop),[
{0} 'WIDTH',
{1} 'HEIGHT',
{2} 'MARGINLEFT' ]) of
0 : Result := 121;
1 : Result := 22;
2 : Result := 40;
end; // of case
end);
TGetByID.Default.Register(OSX,
Function (Const Prop : String) : Single
begin
Case TFDKHelper.CaseSelector(Uppercase(Prop),[
{0} 'WIDTH',
{1} 'HEIGHT',
{2} 'MARGINLEFT' ]) of
0 : Result := 128;
1 : Result := 24;
2 : Result := 40;
end; // of case
end);
TGetByID.Default.Register(iOS,
Function (Const Prop : String) : Single
begin
Case TFDKHelper.CaseSelector(Uppercase(Prop),[
{0} 'WIDTH',
{1} 'HEIGHT',
{2} 'MARGINLEFT' ]) of
0 : Result := 138;
1 : Result := 24;
2 : Result := 40;
end; // of case
end);
TGetByID.Default.Register(Android,
Function (Const Prop : String) : Single
begin
Case TFDKHelper.CaseSelector(Uppercase(Prop),[
{0} 'WIDTH',
{1} 'HEIGHT',
{2} 'MARGINLEFT' ]) of
0 : Result := 140;
1 : Result := 28;
2 : Result := 40;
end; // of case
end);
end;
ByPlatform :=
Function (Prop : String) : Single
begin
Result := TGetByID.Default.From(IDAktPlatform,Prop);
end;
Procedure Whatever;
begin
Button.Width := ByPlatform('Width');
Button.Height := ByPlatform('Height');
Button.Margins.Left := ByPlatform('MarginLeft');
end;
So ist der Zugriff im Code einfacher!
Weil wir:
- unseren Code mit verschiedenen Delphi Versionen übersetzen wollen und hierfür Änderungen nötig sind.
- Funktionalitäten an- und abschalten wollen.
- auf die Prozessor Struktur reagieren müssen. (32/64 Bit)
- auf unterschiedliche Betriebssystem reagieren müssen...
Gibe es hier nicht bessere Lösungen?
Na Klar...
Nicht für alle 4 Punkte...
Um es einfach zu sagen: Die RTL macht es vor!
Über die Plattform-Dienste werden die eigentlichen Implementationen je nach Plattform registriert und der Rest linked gegen ein Interface...
Wenn es gut genug ist für dir RTL - sollten wir dieses Designpattern auch in unseren Applications anwenden.
Aber was ist, wenn wir kein IFDEF nehmen können, weil wir zur Laufzeit entscheiden müssen?
Klar nen IF auf eine Variable wird jeder sagen!
Ich mache es so (vereinfacht für das Beispiel! Im eigentlich Code passe ich das Ganze noch an den Text an):
type
TMyOSPlatform = (Windows, OSX, iOS, Android);
TOSPlatforms = Set of TMyOSPlatform;
Procedure InitFMX;
begin
TGetByID
Function (Const Prop : String) : Single
begin
Case TFDKHelper.CaseSelector
{0} 'WIDTH',
{1} 'HEIGHT',
{2} 'MARGINLEFT' ]) of
0 : Result := 121;
1 : Result := 22;
2 : Result := 40;
end; // of case
end);
TGetByID
Function (Const Prop : String) : Single
begin
Case TFDKHelper.CaseSelector
{0} 'WIDTH',
{1} 'HEIGHT',
{2} 'MARGINLEFT' ]) of
0 : Result := 128;
1 : Result := 24;
2 : Result := 40;
end; // of case
end);
TGetByID
Function (Const Prop : String) : Single
begin
{0} 'WIDTH',
{1} 'HEIGHT',
{2} 'MARGINLEFT' ]) of
0 : Result := 138;
1 : Result := 24;
2 : Result := 40;
end; // of case
end);
TGetByID
Function (Const Prop : String) : Single
begin
Case TFDKHelper.CaseSelector
{0} 'WIDTH',
{1} 'HEIGHT',
{2} 'MARGINLEFT' ]) of
0 : Result := 140;
1 : Result := 28;
2 : Result := 40;
end; // of case
end);
ByPlatform :=
Function (Prop : String) : Single
begin
Result := TGetByID
end;
Procedure Whatever;
begin
Button.Width := ByPlatform('Width');
Button.Height := ByPlatform('Height');
Button.Margins.Left := ByPlatform('MarginLeft');
end;
So ist der Zugriff im Code einfacher!
Tuesday, August 23, 2016
Delphi-Tage 2016 Thema meiner Vorträge!
Das Thema meiner diesjährigen Vorträge auf den Delphi Tagen lautet:
Die Vorteile von dynamisch erzeugen Komponenten anhand von Firemonkey Beispielen!
Es wird sicherlich wieder eine interessante Veranstaltung.
1. Vortrag zusammen mit Olaf Monien
Effektives Multithreading – Die einfache Welt des TTask.Run und was kommt danach?2. Vortrag
Zusammenklicken oder Programmieren?Die Vorteile von dynamisch erzeugen Komponenten anhand von Firemonkey Beispielen!
Es wird sicherlich wieder eine interessante Veranstaltung.
Thursday, August 18, 2016
FDK - Feature Matrix
Vorab unsere Feature Matrix*.
Was sich genau dahinter "versteckt" folgt in Kürze... *) Diese Zusammenstellung ist auch noch nicht endgültig.Lite-Version
Delphiprofi.FDK.AnyFactory
Delphiprofi.FDK.Config
Delphiprofi.FDK.Console
Delphiprofi.FDK.Events
Delphiprofi.FDK.Exceptions
Delphiprofi.FDK.FireDAC
Delphiprofi.FDK.FluidCreator
Delphiprofi.FDK.FMXHelpers
Delphiprofi.FDK.Helpers
Delphiprofi.FDK.IdleWorker
Delphiprofi.FDK.IFDEF
Delphiprofi.FDK.IO
Delphiprofi.FDK.KeyValue
Delphiprofi.FDK.Logging.ConsoleLogger
Delphiprofi.FDK.Logging.DebugLogger
Delphiprofi.FDK.Logging.FileLogger
Delphiprofi.FDK.Logging.LogFilter
Delphiprofi.FDK.Logging
Delphiprofi.FDK.MainApplication
Delphiprofi.FDK.Messages
Delphiprofi.FDK.Observer
Delphiprofi.FDK.Pattern
Delphiprofi.FDK.Pattern.Internals
Delphiprofi.FDK.Platform.Utils
Delphiprofi.FDK.Resources
Delphiprofi.FDK.StringConsts
Delphiprofi.FDK.Types
Delphiprofi.FDK.Utils
Full-Version
(zusätzlich zur Lite-Version)
Delphiprofi.FDK.AnyConverterDelphiprofi.FDK.BackgroundWorker
Delphiprofi.FDK.CallByIDFactory
Delphiprofi.FDK.Compressing
Delphiprofi.FDK.Compressing.ZLib
Delphiprofi.FDK.Converters
Delphiprofi.FDK.Crypting
Delphiprofi.FDK.DataView
Delphiprofi.FDK.DTOWithVersion
Delphiprofi.FDK.Enumerables
Delphiprofi.FDK.EventBus
Delphiprofi.FDK.Fmx.Enumerables
Delphiprofi.FDK.Generics.BlockingCollections
Delphiprofi.FDK.Generics.Collections
Delphiprofi.FDK.HeartbeatWorker
Delphiprofi.FDK.Json
Delphiprofi.FDK.MulticastEvents
Delphiprofi.FDK.Push
Delphiprofi.FDK.Specifications.Dates
Delphiprofi.FDK.Specifications
Delphiprofi.FDK.Specifications.Strings
Delphiprofi.FDK.Stateless
Delphiprofi.FDK.Streams.Hashing
Delphiprofi.FDK.Streams
Delphiprofi.FDK.Tethering
Delphiprofi.FDK.Tethering.Queue
Delphiprofi.FDK.Tethering.TransferObjects
Delphiprofi.FDK.TextLayoutHelper
Delphiprofi.FDK.Threading.AsyncTasks
Delphiprofi.FDK.Threading
Delphiprofi.FDK.Threading.Pipeline
Delphiprofi.FDK.TimeOutWorker
Delphiprofi.FDK.TreeViewWalker
Delphiprofi.FDK.Vcl.Enumerables
Delphiprofi.FDK.Winapi.Windows
Dies Zusammenstellung entspricht der Version 1.0 weitere Units sind in der Queue!
Monday, August 15, 2016
Fortschritt im FDK
Zwischenstand des FDK's
Für alle die sehnsüchtig das Release des FDK's erwarten, hier ein kleiner Zwischenstand.
Die Inline-Docu ist fast fertig.
Die Beginners-Docu ist fast fertig.
Die Funktionalitäten der Lite-Version sind bis auf 2 Units fertig.
Die Funktionalitäten der Full-Version braucht noch ein bisschen refactoring.
Es fehlt noch:
- Erstellung der Installationspakete
- Einrichtung Bugtracker
Wir hoffen jedoch bis zu / auf den Delphi-Tagen / die Lite-Version rausgeben zu können.
Rest folgt dann schnellstmöglich...
* so ist der Plan....
Wednesday, August 10, 2016
Delphi-Tage 2016 in Köln
Selbstverständlich bin ich auf den Delphi Tage 2016 auch wieder als Speaker dabei.
Geändert hat sich meine Beteiligung.
Die Delphi-Tage werden jedoch nicht mehr von den drei Delphi-Foren organisiert. Auch Embarcadero hat sich nicht an der Organisation beteiligt.
Trotzdem kommt - so hat er es angekündigt - Marco Cantu.
Um es mit berühmten worten zu sagen: Klingt komisch, is´ aber so.
Was ändert sich? Eigentlich fast nix.
- Es wird wieder ein Workshop vor den Delphi Tagen geben. (Do. & Fr.)
- Es wird am Abend vor der Hauptveranstaltung einen Community-Abend geben. (Fr.)
- Es werden wieder zahlreiche Vorträge rund um Delphi gehalten. (Sa.)
Geändert hat sich meine Beteiligung.
- Ich unterstütze Olaf beim Workshop.
- Ich werde zwei Vorträge halten.
Eine Veranstaltung wie die Delphi-Tage, darf einfach nicht ausfallen. Welche Gründe vorlagen, dass sich die bisherigen Organisatoren zurückgezogen haben, entzieht sich meiner Kenntnis. Spielt aber eigentlich auch keine Rolle. Für mich war es jedoch sofort klar, dass ich meine Hilfe und Beteiligung, angeboten habe. Jeder der ein bisschen rechnen kann, wird erkennen, dass mit 35,- € pro Person, so eine Veranstaltung nicht zu finanzieren ist. In der Vergangenheit wurde ein großer Teil der Veranstaltung durch die Sponsoren bezahlt. Eine kleine Preiserhöhung auf (43,- €) wird aber jeder "verschmerzen" können.
Ein Bestandteil der Delphi-Tage - war schon immer - der Workshop vorher. Hier geht es weiter in die Tiefe, als es ein 60 Minuten Vortrag kann. Wie ich es hier schon in einem früheren Blogpost beschrieben habe: Fortbildung muss für jeden ernsthaften Developer ein fester Bestandteil im Terminkalender sein. Ob es sich hierbei um ein Selbststudium handelt oder die Teilnahme an einem Workshop ist erst mal zweitrangig. Den eigenen Schweinehund zu besiegen und - obwohl man schon seit Jahren programmiert - wieder die "Schulbank" zu drücken ist erst mal das Thema.
Seit vielen Jahren, treffen sich 6-12 Entwickler regelmäßig bei unserer Delphi-Frühstücks-Gruppe. Auch wenn sich das Kern-Team immer wieder trifft. Es gab noch kein Treffen bei dem ich und das sagen auch die anderen, nix neues gehört haben. Jedes Treffen hat ein Mosaik-Steinchen für mein Wissen gehabt...
Wednesday, August 3, 2016
Refactoring - Der "tägliche" Wahnsinn.
Wer kennt das nicht... Ein Projekt entwickelt sich immer weiter, natürlich kommt man an einen Punkt und stellt fest, XY benötige ich jetzt schon in 2 Units, 3 Units, 4 Units... Ab wann wird es Zeit daraus ein Pattern zu machen?
Frühzeitig? Nach Abschluss?
Aber was ist, wenn ich dieses Pattern mit nur kleinen Veränderungen auch in 3-5 anderen Units verwenden könnte? Soll ich lieber eine Kopie machen oder die Veränderungen mit einem Parameter steuern? Oder übergebe ich die Funktionalität lieber als interface an das Pattern? Was sieht nicht nur schick im Source-Code aus, sondern ist dann auch praktisch in der Benutzung? Fragen über Fragen.
Ich habe mittlerweile eine Klasse, die hat heute zum 2. Mal einen neuen Namen bekommen und die Unit habe ich zum 3. mal renamed. Natürlich nicht ohne die Documentation, das Handbuch und alle Anwendungen die daraufhin geändert werden müssen neu zu kompilieren. War das eine gute Idee?
Also vielleicht erstmal ein paar "Rule of Thumbs" generieren.
- Je mehr Code ich vernichten kann, weil ich eine "zentrale" Routine nutze. Desto weniger Codezeilen können einen Fehler haben.
- Wenn meine Anwendung in der Regel "nur" Basis-Routinen aufruft und diese fehlerfrei sind, um so weniger Fehler kann meine Anwendungen haben. Voraussetzung hierfür ist natürlich die Testbarkeit. Da jedoch "zentrale" Routinen einfacher zu testen sind, ist meine Anwendung einfacher zu testen.
- Ist die Basis-Routine Threadsave, ist es einfacher meine eigenen Routinen Threadsave zu gestalten (vereinfacht ausgedrückt). // Ach wäre doch nur die VCL/RTL Threadsave.
- Bei der Schaffung einen neuen Basis für XY erkaufe ich mir jedoch Zwangs-Verlinkungen ein!
Lohnt es sich also zu Refrakturieren?
Auf jeden Fall - am besten immer so schnell wie möglich, wenn ich ein Problem erkenne. Je früher ich es behebe, desto weniger Source-Code baut darauf auf.
"Nur das mit der Doku ist lästig, wenn ich eine habe..."
Friday, July 15, 2016
CodeRage 2016 Nachlese!
Vielen Danke für die zahlreichen Nachrichten zu meinem CodeRage Vortrag.
Sowie es die Zeit zulässt, werde ich weitere Video zu diesem Thema veröffentlichen.
Ich nehme auch noch gerne Themenvorschläge unter Info@delphiprofi.de für meinen Vortrag auf den Delphi-Tage in Köln entgegen...
Sowie es die Zeit zulässt, werde ich weitere Video zu diesem Thema veröffentlichen.
Ich nehme auch noch gerne Themenvorschläge unter Info@delphiprofi.de für meinen Vortrag auf den Delphi-Tage in Köln entgegen...
Saturday, July 2, 2016
So viele Begriffe...
Immer neue Begriffe erreichen uns…

Welche dieser Begriffe kennen wir den?
Welche Techniken nutzen wir?
Und die eigentliche Frage: Wofür das ganze überhaupt?
Diese Techniken gilt es zu erlernen und – im besten Fall – fehlerfrei an zu wenden.
Oder haben wir uns vielleicht mit unserer komfortablen IDE und der einfachen Möglichkeit:
Butten aufs Formular – Doppelclick und code rein. Vielleicht zu lange auf die faule Haut gelegt?
Ist das eigentlich Fremdwort : Weiterbildung?

Welche dieser Begriffe kennen wir den?
Welche Techniken nutzen wir?
Und die eigentliche Frage: Wofür das ganze überhaupt?
Bestanden früher Programme aus linearablaufendem Code bei dem die Reihenfolge eindeutig war, sind durch Windows und die eventgesteuerte Programmierung viele neue Techniken zum täglichen Programmieralltag hinzu gekommen.
Diese Techniken gilt es zu erlernen und – im besten Fall – fehlerfrei an zu wenden.
Dieses sich immer schneller drehende Hamsterrad in dem wir täglich unsere Software entwickeln, hat durch Firemonkey und die Cross-Plattform Programmierung wieder einmal einen neuen Schub bekommen.
Oder haben wir uns vielleicht mit unserer komfortablen IDE und der einfachen Möglichkeit:
Butten aufs Formular – Doppelclick und code rein. Vielleicht zu lange auf die faule Haut gelegt?
Ist das eigentlich Fremdwort : Weiterbildung?
Für alle die, die sich auf der eigenen Application ausgeruht haben, biete ich selbstverständlich Schulungsmöglichkeiten an.
Tuesday, June 21, 2016
Updating NAS RAID Controller...
Updating NAS RAID Controller Nightmare...
Wer kennt das nicht... Das NAS steht im Keller im 19" Schrank und macht das was ein NAS so machen soll - hält und speichert Daten... Gelegentlich gibt es die Daten auch zurück...
Natürlich hat das NAS auch eine Benachrichtigung Funktion... Per E-Mail.... Diese wurde aber NIE eingerichtet...
Die Jahre vergehen und es gab NIE Problem... Auch nach einem Umzug - alles prima.
Eines Tages (vor ca. 4 Wochen) komme ich in den Keller und schaue auf das NAS... Ein Festplatten LED blinkt...
OK - ist ein Plattenzugriff... Oder? in einem RAID 5 auf nur einer Platte obwohl keine im Büro ist?
An den Rechner - Webbrowser und die Console aufrufen... Zertifikatswarnung ignorieren... Hmm alles in Ordnung...
Also wieder in den Keller und die Festplatte raus ziehen. Sollte ja in einem RAID 5 kein Problem sein. hmm... Platte eiskalt und dreht sich nicht... Normalerweise hat man noch den Kreiseleffekt beim rausziehen...
OK Platte tot... Schnell eine neue Bestellt... 1TB... geliefert wird eine 2TB zum 1TB Preis...
Und nun... Der 2. Menü von der Managment Console bringt immer einen Fehler... Ob ich nach so vielen Jahren noch den Lieferanten kontaktieren kann und Support erhalte?
Geliefert hat das alles die Firma xtivate aus Ilmenau...
Ich stelle meine Frage warum ich nicht in die Console komme und werde mit einem Mitarbeiter verbunden...
Lange Rede kurzer Sinn... HUT AB!!! Das nenne ich Service - Nicht nur das mir jede Frage beantwortet wurde... Auch in einer einstündigen TeamViewer Sitzung wurde mit einem alten Firefox, putty mir der Zugang zu meinem NAS ans laufen gebracht... Vielen Dank noch mal hierfür.
die Platte wurde als 2GB brutto erkannt und das RAID war schon auf dem Weg sich zu rebuilden...
Ich habe dann auch mal den E-MAIL zugang für die Benachrichtigungen eingestellt... War eine Empfehlung des Servicemitarbeiters...
Meine Frage: Kann ich alle Platten gegen 4 TB Platten austauschen - Antwort Nein... Kann der Contoller nicht... (2TB Konnte er noch)
Und ein neuer Contoller...? Geht nicht in diesem Board...
Und ein neues Bord und ein Controller...
Dann ist es in der Regel günstiger ein neues NAS Fertigkonfiguriert mit Platten zu kaufen...
Na toll...
Jetzt nervt mich das NAS andauert mit E-Mails...
- bla dies - bla das -Verify - OK - Verify - OK...
WARNING - Remapping - OK...
hmm defekter Sektor... auf der nächsten Platte... (Jeden Tag einer)
Ich muss wohl etwas unternehmen.
Externe Docking Station mit USB3+ und Controller gekauft... 2x4TB sollte für ein Backup reichen...
Jetzt liegen auf dem NAS aber hunderttausende kleine Dateien... der 1. XCOPY sagt 3 Tage...
Also mal RAR bemühen und nach 2-3 Anläufen sind alles Shares auf der externen Festplatte...
Und jetzt? Neue Platten bestellen ... 12 Stück.... NAS Platten vielleicht zahlt sich der Stromverbrauch ja aus... hmm Aber welche....2TB gingen 4TB sollen nicht gehen...
Bestellen wir 12 x 3TB NAS Platten. Und schlagen alle Warnungen in den Wind...
Als Erstes mal die defekte Platte tauschen... Und siehe da.. Die neue 3TB Platte wird als 768GB erkannt und kann nicht in das RAID eingefügt werden... Das kommt davon wenn man nicht auf den Servicemitarbeiter hört....
Aber ich bin heute mutig... Controller Update gefunden... Das Update lässt sich nicht installieren... Geht nur als Admin... Umloggen und neuer Versucht...
Die Maus schwebt über den Update Button... (Sind wirklich alle Daten sicher gebackuped?)
Lieber doch nicht und Platten zurück schicken...?
Ach was soll's... Und Go... (Nix passiert)
Plötzlich ein Fenster : Update ist compatible... Haben Sie alle Daten gesichert? Weiter?
Also "Weiter"... Die längsten 30 Sekunden die ich kenne...
Update erfolgreich - System muss neu gestartet werden... Reboot? "JA"
Die Weboberfläche kommt nicht wieder... Reload bring auch nix... 1 Minute ist schon rum...
1:30 - Mist jetzt ist das NAS tot... Oder?
Start -> Ausführen -> CMD
Ping senden... <1ms
OK, Dass geht... und der Browser? Antwort nach 2 Min... Alles wieder da...
Und die neue Platte?
Erkannt mit 3TB und das RAID hat schon begonnen zu rebuilden...
Jetzt muss ich nur mal alle tauschen und das RAID neu aufsetzen... Aber nicht mehr heute....
Und ich kann wieder ruhig schlafen...
Wednesday, June 1, 2016
Erste Deutsche CodeRage am 13.Juli.2016
Selbstverständlich darf auf der deuschen Coderage kein FMX Vortrag von mir/uns fehlen.
Key-Thema ist selbstverständlich das FDK und die Entwicklung von mobilen- und Desktopwendungen mit FMX.
Gerne nehmen wir im Vorfeld Themen auf, die wir in unserem Vortrag näher beleuchten sollen.
Anregungen bitte per e-Mail an Info@delphiprofi.de
Key-Thema ist selbstverständlich das FDK und die Entwicklung von mobilen- und Desktopwendungen mit FMX.
Gerne nehmen wir im Vorfeld Themen auf, die wir in unserem Vortrag näher beleuchten sollen.
Anregungen bitte per e-Mail an Info@delphiprofi.de
Subscribe to:
Posts (Atom)



