Entwickler-Ecke

Kommerzielle Projekte - Modular Application Framework Components + Developers Blog


HelgeLange - Sa 10.03.07 00:58
Titel: Modular Application Framework Components + Developers Blog
UPDATE : Download link für die TechDemo am Ende des Beitrags hinzugefügt...
UPDATE 2 : Source der TechDemo hinzugefügt
UPDATE 3 : Title geändert

Wie es aussieht, bin ich wohl der erste, der sich hier mal etwas breit macht :) Ich werd mal versuchen, mich soweit an die Regeln zu halten, wie es im momentanen Stadium möglich ist. Ausserdem werde ich wohl das Ganze auf mehrere Beiträge verteilen müssen, da es doch recht unfangreich ist und es sich nicht in 3 Zeilen erklären lässt. Im Verlauf werden auch Screenshots und später ein Demo-Programm gepostet.

Hier erstmal der Link : http://www.maf-components.com

Die Website befindet sich noch im Design, deswegen hab ich erstmal im Blog angefangen, ein paar Artikel online zu stellen, die nächsten Tage folgen mehr davon, wo die Funktionsweisen soweit erklärt werden, dass die Vorzüge dieser Komponenten klar werden sollten. Ich werde versuchen, auf alle Fragen, die da kommen sollten, einzugehen, aber keine Anleitungen zum Selberbauen geben. :P

Für alle, die erstmal keine Lust haben, sich seitenlange Abhandlungen auf der Website durchzulesen hier mal eine mehr oder minder kurze Zusammenfassung. Es in 3 Sätzen zu beschreiben, wird natürlich nicht möglich sein, da es ein komplettes Komponenten-Pack ist und von daher einfach im Funktionsumfang zu gross.

1.) Wie kam ich eigentlich dazu, diese Komponenten zu schreiben und zu releasen ?

ERP (Enterprise Resource Planning, zu gut deutsch : Warenwirtschaft) - Systeme waren schon immer eine meiner Leidenschaften. Ich mag mit Datenbanken rumspielen und ich mag es logisch :) Irgendwann wollte ich mal neben dem Studium ein kleines ERP Programm basteln, welches allerdings so modular sein sollte, dass ich es jederzeit erweitern kann. Beim herkömmlichen Plugin-System kam ich recht schnell an die Grenzen, da Plugin starre interfaces haben und recht limitiert sind in deren Funktionen. Ein anderer Grund war natürlich die Austauschbarkeit von Funktionalität, denn durch Beruferfahrung wusste ich bereits, wie unterschiedlich Kundenwünsche sind. Auch das geht nicht mit einem herkömmlichen Plugin-System, ohne dass man neue Versionen der Plugins ausliefert und in denen auf Kundenwünsche eingeht. Besonders schlimm ist das natürlich, wenn es Wünsche sind, die nur auf einen Kunden zutreffen. Dann fängt man an, sich mit IFDEF oder If-Then-Else runzuschlagen.
Es war also aufgrund dieser Vorüberlegungen unumgänglich, ein System zu schreiben, in dem man nicht nur Module nachliefern/installieren kann, um neue Funktionalität ins Programm zu integrieren, sondern auch vorhandene Funktionalität zu verändern/auszutaschen. Und genau da setzt ein Teil der ERP Framework Components an.
Nun war die erste Komponente (THookClient) darauf ausgelegt, mir all das zur Verfügung zu stellen und es waren weder weitere Komponenten noch ein Release geplant. Aber im laufe der Jahre kamen immer mehr Komponenten dazu, die sich als sehr nützlich herausgestellt haben und ich fand es nachher doch recht schade, wenn sie bei mir auf der Festplatte verstauben.
Ein weiterer Punkt, der mich zum releasen veranlasst hat : Die Programme der anderen. Als Freelancer bekomme ich eine Menge Programme zu sehen und es tränt immer wieder in den Augen, wenn man 200 oder mehr Formulare in einer EXE sieht, dazu noch ne ganze Menge TTable und alles zum Programmstart erstellt. Jetzt kann ich natürlich meinen Clients in dem Stadium nicht meine Komponenten unterschwatzen, die wollen meist Probleme schnell gelöst bekommen, über alles andere später mal nachdenken. Zumindest mit einem Release könnte ich andere unterstützen, gute modulare Software zu schreiben.

2.) Was bietet ERP Framework Components meiner Software ?

wie unter Punkt 1.) schon erwähnt, ist der Ursprung eine Komponente für dynamische Funktionen, die es erlaubt, im Nachhinein neuen Code zu vorhandenem hinzuzufügen oder zu überschreiben bzw. zu löschen, ohne dass die vorhandenen Module neu übersetzt werden müssen. Beim Start des Programms wird vom HookManager (nicht zu verwechseln mit Windows-Hooks, hier wurde der Name gewählt, weil jeder Hook eigentlich ein Haken mit n-vielen Funktionen ist) eine DynamicFunctionTable erstellt, welche den Code so miteinander verknüpft, wie es sich der Programmier gewünscht hat. Dazu kommt ein Security-Layer, der bestimmte Funktionen (vom Programmierer festlegbar) vor unberechtigtem Zugriff schützt (zum Bsp. die Liste der Einkaufpreise eines Shops darf nicht jeder Mitarbeiter sehen). Das heisst, es wird für den Code, auf den der augenblicklich angemeldete Nutzer keinen Zugriff hat, gesperrt. bzw. erst garnicht geladen. Somit wird es schwerer, sich unberechtigt Zugang zu verschaffen.
Nur welchen Vorteil hat man von "dynamischen Funktionen" ? Ich will es mal am Beispiel eines Kunden erklären, weil der in fast jeder ERP Software gebraucht wird.
Nehmen wir an, hinter einem Button "Neuen Kunden erstellen" liegt folgende Procedure :

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
var CustomerID : Integer;
begin
  CustomerID := CreateCustomer;
  CreateCustomerAdressAndShipping(CustomerID);
  CreateCustomerAccount(CustomerID);
end;


Schreibt man auf Wunsch einer Kunden-Firma, die Ihre Software einsetzt, nun ein Modul, welches Einkaufsverhalten auswerten soll und entsprechend in Tabellen speichern etc., müsste der Code erweitert werden um eine Funktion, so dass Für neue Kunden die entsprechenden tabellen etc. auch angelegt werden.

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
var CustomerID : Integer;
begin
  CustomerID := CreateCustomer;
  CreateCustomerAdressAndShipping(CustomerID);
  CreateCustomerAccount(CustomerID);
  CreateCustomerAnalyzeTables(CustomerID);
end;


Mit den ERP Framework Components ist das nicht nötig, die Procedure hinter dem Button würde in beiden Fällen ungefähr so aussehen :

Delphi-Quelltext
1:
2:
3:
4:
5:
begin
  // HM_CreateCustomer ist einfach eine ID, die vom Programmierer festgelegt wird
  // und unter welcher er die Funktionen dieses Hooks speichert
  HookClient1.ExecuteHook(HM_CreateCustomer, 0);
end;


Die CustomerID selbst wird in einem Event der Komponente THookClient geliefert und kann dort entnommen werden, ExecuteHook liefert einen FehlerCode bzw. dass kein Fehler aufgetreten ist. Dem HookManager (der die Anforderung vom HookClient bekommt, etwas ausführen), ist es dabei egal, wieviele Funktionen eigentlich da sind und, ungleich einem Script zum Beispiel, ist es auch egal, ob eine Funktion da ist. Man bekommt mitgeteilt, wenn eine Funktion nicht vorhanden ist, aber das stört den Programmablauf nicht, da es kein Script ist. Der Programmierer selbst kann über Massnahmen in solchen Fällen entscheiden, er kriegt für jede Funktion innerhalb eines Hooks einen Bericht und Zwischenergebnis über entsprechende Events. Dabei kann entschieden werden, ob die Ausführung gestoppt wird, die nächste Funktion übersprungen oder einfach weitergemacht werden soll.
Soll nun der neue Code an den Hook Angefügt werden, wird bei der Installation des Moduls mittels einer Register-Funktion einfach dem HookManager mitgeteilt, dass es für den Hook HM_CreateCustomer eine neue Funktion gibt. Dabei kann auch Position des Codes festgelegt werden oder vorhandener überschrieben.

Der HookManager selbst befindet sich in einer DLL, welche ausser den Hooks noch ein ganzes Set von Funktionen zur Verfügung stellt.
- Datenbank-Zugang
- Globale Variablen (auch speicherbare)
- Install-API für Module und deren Funktionen
- Rechte-Verwaltung für Hooks
- Templates

Rechte-Verwaltung hatte ich ja weiter oben schon kurz erklärt, ich glaube, da muss ich nichts weiter dazu sagen. Auch bei der Install-API sollte klar sein, was sie macht.
Globale Variablen können über den HookClient gelesen und geschrieben werden, sie stehen für alle Module in der Anwendung zur Verfügung und der Programmierer kann bestimmen, welche ihre Gültigkeit nur für die Session haben und dann automatisch gelöscht werden und welche gespeichert werden sollen.
Templates sind eigentlich Streams, die nach ID (primär) oder Name+Kategorie (sekundär) gespeichert werden und darüber auch angesprochen werden können. Was drin gespeichert wird, bleibt dem Programmierer überlassen.
Datenbank Zugang habe deswegen dort eingebaut, da jeder Aufruf einer Funktion sowieso durch diese DLL geht und somit Datenbank und Transaktion mitgegeben werden können um im Modul benutzt zu werden durch ein TQuery oder TTable oder was auch immer. Dabei gibt es ein Basis-Object, welches virtuelle und abstracte methoden zur Verfügung stellt, welche durch das finale Datenbank-Objekt überschrieben werden um die Funktionalität unter verschiedenen Datenbank-Systemen zur Verfügung zu stellen. Im jetzigen Stadium gibt es ein Modul für Firebird und für die Registry (ein Mini-Treiber, der für datenbanklose Systeme gedacht ist). Um für ein anderes DB-System zu programmieren muss man eigentlich nur vom Basis-Object ableiten und ein paar recht einfache Befehle umsetzen / anpassen, wobei man allerdings am Bsp. des Firebird-Treibers sieht, welche das sind und was gemacht wird. Die meisten kann man wahrscheinlich vom Firebird-Treiber selbst nehmen und nur die Zugriffs-Komponenten austauschen.

Weiter geht es in Part 2 später...


Christian S. - Sa 10.03.07 02:44

Das klingt sehr interessant :-) Die mangelnde Flexibilität von Plugins via Interface hat mich auch schon gestört. Ich bin auf die weiteren Postings gespannt :zustimm:


HelgeLange - Sa 10.03.07 02:44
Titel: Part 2
Die Benutzung der Komponenten selbst gestaltet sich relativ einfach, da sie nur einen Loader brauchen, der auf die MainForm gelegt wird. In dessen Properties kann man festlegen, woher die einzelnen Manager geladen werden sollen etc. Alle Client-Komponenten suchen sich diesen Loader und holen sich entsprechend die Schnittstelle für ihren entsprechenden Manager. Dadurch kommen die Komponenten nicht nur ohne Einstellungen aus, sondern sind dazu auch sehr klein im Speicherverbrauch.

3.) Was gibt es für Manager neben dem HookManager mit seinem HookClient ?

Da wären ResManager, LinkManager und WindowManager im Moment.
Der ResManager kümmert sich um das Laden von Resourcen, Strings für Milti-Language-Support on-the-fly ohne Programm-Neustart und Bilder für Listen, die auch noch geshared werden, so dass jedes Bild faktisch immer nur einmal im Speicher vorhanden ist, aber in allen Programmteilen genutzt werden kann über dessen Handle. Ausserdem lädt er SQL-Strings, da diese nicht im Programm selbst bei mir sind, sondern als Resource gespeichert werden. Warum ? Weil ich Datenbank-unabhängig programmieren will, und so kann ich für das Programm den DB-Treiber und die SQL-Resource gegen die eines anderen DB-Systems austauschen und meine Module kriegen das nichtmal mit. Damit kann ich besser auf Kundenwünsche eingehen.

Der LinkManager kümmert sich um das Real-Time-Verknüpfen von Modulen/Fenster, die sich nicht kennen. Da ich ja davon ausgehe, dass immer wieder neue Module hinzukommen können, die ich im Moment der Auslieferung nicht kenne, habe ich mich entschieden, das das ganze ERP-System auf der Annahme beruht, dass keiner jemanden anderes kennt, aber sie trotzdem kommunizieren müssen. Der Linkmanager ist eines der Ergebnisse davon. Mit ihm kann man in real-time Daten zu einer unbekannten Menge von Empfängern schicken, um diese auf dem laufenden zu halten, so dass diese nicht pollen müssen. Zum Bsp. wird ein Auto vermietet und über den LinkManager kann die Übersicht der verfügbaren Autos sofort geupdated werden. Dazu meldet sich der Empfänger für Events an und falls dieses eintritt, wird beim Empfänger ein Event gefeuert, welches neben der Event-Information auch entsprechend Informationen enthält, die für das update nötig sein könnten. Welche Informationen das sind, bestimmt der Programmierer natürlich, es ist ja sein ERP System :)

Ein WindowManager kümmert sich darum, eine Fensterliste bei Bedarf anzuzeigen, Fenster zu finden, die von anderen Teilen der Anwendung benötigt werden und in Zukunft auch, diese zu schliessen, wenn nötig. Eines der grossen Vorteile des Systems ist dabei, dass es nicht mehr darauf ankommt, ob ich als Programmteil ein Fenster kenne bzw. den Object-Typ. Es reicht aus zu sagen, ich hätte gern einen Suchdialog für Kunden und das war es. Dabei entscheidet der FormFinder selbst, ob ein vorhandenes offenes Fenster genommen wird oder ein neues erstellt werden muss. Das Verhalten kann natürlich konfiguriert werden vom Anwender. Zusätzlich nutze ich zum Bsp. den LinkManger dort, um Suchergebnisse im aufrufenden Fenster anzuzeigen, wenn sinnvoll. Bsp.: Ich habe einen Dialog zum Kunden bearbeiten, drücke F3 für die Kundensuche, der Formfinder bringt mir solch ein Formular an, ich suche einen Kunden, doppelklick ihn und im KundenEditor werden schon die Daten geladen. Das kann sogar soweit gehen, dass man mit einem einfachen Klick auf den Eintrag in der Suche die Daten im Editor lädt und anzeigt, ohne, dass sich die beiden Fenster kennen. Sie können in unterschiedlichen Modulen befinden, auch könnte der Kunden-Editor erst 1 Jahr später nachgeliefert worden sein, die Kundensuche könnte über den WindowManager trotzdem gefunden werden und beide können über den LinkManager kommunizieren.

4.) Was gibt es sonst noch im Package ?

Biher hatten wir folgende Komponenten :
- TManagerBaseContainer (er lädt und verwaltet alle Manager DLLs)
- THookClient + Manager-DLL
- TResClient + Manager-DLL
- TLinkClient/TLinkServer + Manager-DLL
- TWindowComm + WindowManager.dll

Desweiteren im BasePack (das sind alle nicht-visuellen Komponenten) sind enthalten im Moment :
- TFormAccessManager
- TInstallManager

Diese beiden benutzt man in den einzelnen Modulen, die InstallAPI habe ich ja schon erwähnt, sie kann über diese Komponente gesteuert werden oder direkt aufgerufen, was allerdings mit Komponente einfacher ist, da sie einen Property-Editor besitst, wo man alle Install-Einstellungen für das Modul visuell erledigen kann.
Der FormAccessManager verwaltet die Formulare eines Moduls und liefert an Enumeratoren und andere Funktionen alle Informationen, um das Formular zu präsentieren. Ausserdem erzeugt es die Formulare und gibt sie wieder frei, alles über eine einheitliche Schnittstelle.

Während man herkömmlich für jedes Form folgendes machen muss (es gibt mehrere Wege etc, das weiss ich, aber das sind die basics, auf die man es reduzieren kann) :

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
var Form1: TForm1;
begin
  Form1 := TForm1.Create(AOwner);
  Form1.Show;
  Form1.Free;
end;

Und dies muss eigentlich im Modul für jedes Form extra gemacht werden. Das erzeugt 'ne Menge Code und wird unübersichtlich. Der FormAccessManager reduziert das ganze auf eine Zeile im Programm und n-Zeilen (n=Anzahl Forms) im DLL-Init-Teil.

Zum Registrieren der Form braucht man pro Form 1 Zeile, damit wird der Code-Teil (der zu einem Hook gehört) mit der Form verknüpft. Das hört sich vielleicht kompliziert an, ist es aber nicht. Das ganze sieht so aus :


Delphi-Quelltext
1:
2:
3:
4:
5:
begin
  // HookSubID ist eine ID, welche die Unterfunktion eines Hooks identifiziert
  // sie muss eindeutig sein im Modul
  FormAccessManager1.RegisterFormClass(HookSubID, TForm1);
end;


und im Aufruf sieht das ganze dann so aus :

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
begin
  // Params sind ein record, welches zusätzliche Infos mitgeben an ein modul
  // auch enthalten ist die Info, ob man nur Informationen über die Form haben will,
  // sie erzeugen oder eben freigeben
  // dieser eine Aufruf reicht für ALLE Formulare im Modul, da das Formular
  // eindeutig über die SubHookID verknüpft ist und dadurch erkannt werden kann
  // man kann natürlich soviele Formulare registrieren, wie man will
  FormAccessManager1.RequestForm(HookSubID, Params);
end;

Der FormAccessManager kommt mit einem Property-Editor, über welchen man Informationen über ein Formular (Anzeige-Name, Icon etc), welche bei einem Aufrufer benötigt werden, mit der eindeutigen SubHookID verknüpft. Zur Laufzeit kommt dann ja noch die Verknüpfung der Form selbst hinzu. Normalerweise geht das auch zur Designzeit, aber ich habe dies extra so gemacht, weil damit sichergestellt wird, dass man kein Modul mit falschen Informationen übersetzen kann.
Da unterschiedliche Formular-Typen unterschiedliche Werte brauchen, um das Formular beim Aufrufer zu präsentieren, gibt es eine Basis-Klasse der Formular-Typen. Will man nun eigene definieren, kann man von der Basisklasse ableiten, sich eigene Typen definieren, registrieren und diese werden automatisch vom FormAccessManager gespeichert, da dieser eine Schnittstelle zu den Typen besitzt, der die Daten selbst egal sind, um sie zu speichern oder zu laden.


Mehr gibt es in einem 3. Teil über visuelle Komponenten...


HelgeLange - Sa 10.03.07 03:16
Titel: Part 3 - Visuelle Komponenten
Es gibt 2 Arten von visuellen Komponenten. Zum einen sind vorgefertigte Basis-Formulare, die schon Basis-Schnittstellen besitzen um mit den non-visuellen Komponenten optimal zusammearbeiten zu können. Zum Bsp. werden Settings mittels der Delphi-Dispatch-Methode gleich nach dem Erstellen des Formulars gemacht. Allerdings muss auf eine solche Nachricht ja reagiert werden, wodurch ein normales TForm das ganze nicht interessiert, aber von den ERP-Base-Formlaren abgeleitete fangen daraufhin an, zu rotieren (für alle, die nun denken, das Formular würde sich drehen... vielleicht doch erstmal richtig die ersten beiden Parts lesen, es geht hier nämlich nicht um Grafik-Effekte ;)) :)

Ausserdem haben die Fenster schon alle Einstellungen, um mit anderen visuellen ERP-Komponenten zusammenzuarbeiten. Zum Bsp. dem TabSheetServer oder der Wizard-Komponente. Diese beiden haben eine Property HookID, in welcher man den Hook angibt, an welchem sie ihre Formulare zusammensammeln. Da ja ein Hook aus n-vielen Funktionen besteht, die auch einfach Formulare sein können, kann zum Bsp. ein TabSheetServer (ist ein erweitertes TPageControl) sich über einen Hook seine Formulare zusammensammeln und diese auf den einzelnen TabSheets des PageControl darstellen. Dadurch ergibt sich natürlich die Möglichkeit, auch im Nachhinein neue TabSheets mit neuen Modulen anzufügen, ohne den Code des Formulars mit dem PageControl nochmal anfassen zu müssen. Neue Module bringen ja neue Informationen und Dialoge, die ins System eingefügt werden müssen, was somit natürlich zum Kinderspiel wird. Deswegen sage ich ja auch auf der WebSite, dass nun endlich ERP Programme leichter als ein Hello-World-Programm zu schreiben sind ;)
Oh.. und die Wizard-Komponente sammelt sich natürlich die einzelnen Steps aus den Modulen über einen Hook zusammen und zeigt sie in der Reihenfolge an, wie sie der Programmierer im Hook selbst vorgesehen hat. Methoden wie Next, Previous, First, Last und entsprechnde Events sind eine Selbstverständlichkeit und sollten der Erwähnung nicht benötigen. :)

Ausserdem mit hinzugelegt habe ich einige Komponenten als Beispiele, wie etwas in eigenen Controls bennutzt werden kann. Da gibt es zum Bsp. eine LinkedComboBox, LinkedListBox und LinkedCheckListBox, welche sich über einen Hook die darzustellenden Daten holen können und über den LinkManager mit einem Editor verbunden sind, um ihren Inhalt zu refreshen. Bsp.: In einer ListBox sind alle Genres für Filme dargestellt, der User muss diese nur entsprechend an/abwählen. Im Editor für die Genres wird ein neues Genre eingegeben, weil der User festegestellt hat, dass es dieses noch nicht gibt und normalerweise müsste er in herkömmlichen Systemen entweder das Fenster schliessen und neu öffnen, damit das neue Genre angezeigt wird.. oder aber eben drauf hoffen, dass der Programmierer clever genug war, dies vorauszusehen und über F5 zum Beispiel die Box refreshen kann. Oder es liegen die ERP Componenten dahinter und linken sich und können die Daten austauschen ohne User-Interaktion :P

Ausserdem dabei ist ein TResBitmap, welches an einer einfachen TPaintBox
zeigt, wie man eine Bitmap-resource lädt und mit Handle zeichnet. Denn ein gutes ERP System ist meiner Meinung nach unbedingt ein MDI-System und es kann von jedem Fenster n-viele Kopien offen geben. Dadurch werden aber TImage zum Bsp. n-mal geladen und Resourcen für das Bild verbraucht. Der ResManager lädt auf Anfrage Bilder, bei erneuter Anfrage wird nur ein ReferenzCounter erhöht bzw. gesenkt, wenn das Bild freigegeben wird und schlussendlich entladen, sowie der ReferenzCounter bei 0 ist. Dadurch wird nicht nur Resourcen-sparend gearbeitet sondern auch der Speicherverbrauch niedrig gehalten. In meiner ERP-Testanwendung daheim kam ich noch nie über 20 MB speicherverbrauch im TaskManager !


Ok, das erstmal zum Produkt selbst, im nächsten Part werde ich versuchen, auf Probleme der Programmierung, Marketing etc. einzugehen...


HelgeLange - Sa 10.03.07 04:39
Titel: Part 4
Als Entwicklungsumgebung wurde ja offensichtlich Delphi genommen, C++-Versionen sind im Moment nicht geplant, da ich a) erstmal genug mit dem Release zu tun habe und b) mit BDS das wohl kaum noch nötig sein wird.

Erstellt wurden die Komponenten selbst mit Delphi 7 und BDS2006. Sie sollten ohne Probleme ab Delphi6 lauffähig sein, die Property-Editoren müssten eventuell angepasst werden mit ihrer uses-Liste, da Borland ja die Units nach Delphi 5 umbenannt hat.

Fertiggestellt wurden/werden sie mit BDS2006, aber es werden Projektdateien für Delphi 6 und 7 beigelegt und die Komponenten auch nochmal unter diesen Versionen getestet. BDS2005 kann ich leider nicht anbieten, da mir dazu im moment die Entwicklungsumgebung selbst fehlt, aber ich denke, dass sie dort ohne Probleme einzusetzen sind, wenn sie unter Delphi 6/7 und BDS2006 laufen.
Zum Bugtracking wird zur Zeit ein Mantis-Server eingesetzt und zur Versionskontrolle ein SVN mit einem TortoiseSVN-Client unter Windows. Mit beiden habe ich sehr gute Erfahrungen gemacht und die Kostenlosigkeit beider Produkte machen sie nur umso attraktiver für den Anfang. Zusätzlich wurde MemProof unter Delphi 7 und AQtime unter BDS benutzt, um Memory-Leaks zu suchen.

Die Entwicklung selbst ging über einige Jahre, wobei zwischendurch Pausen waren, wo ich manchmal für 1 Jahr oder mehr nichts dran gemacht habe. Denn urspünglich waren sie nur für mein System gedacht und dadurch auch relativ eng mit ihm verbunden.
Mit der Überlegung, die Komponenten entsprechend zu vermarkten (da ja offensichtlich Interesse und Bedarf besteht), stellte sich natürlich auch die Frage nach der Offenheit für andere Programmierer. So entschied ich mich zum Bsp. den TManagerBaseContainer zu schreiben und auch die Basis-Komponente TERPComponent komplett neu zu designen. Das war nötig, da ich bisher einfach in den Client-Komponenten eine Property HandleShared hatte, welche darüber entschieden hat, ob die Komponente den Manager lädt oder nicht. Solche Daten kann man sich natürlich sparen, gerade weil THookClient von mir auf 90% aller Formulare benötigt wird. TResClient sogar auf 100%, da diese sich auch um Sprachumschaltung kümmert und wenn in der Konfiguration die Sprache umgeschaltet wird, feuert die Client-Komponente ein entsprechendes Event, um auf Eigenheiten des Komponenten eingehen zu lassen und ändert die Sprache bei den Standard-Komponenten von Delphi selbst. Die Container-Komponente kommt mit ca. 650 Zeilen Code daher, kann mit allen meinen Managern klarkommen, benötigt 0 Zeilen Code auf dem Hauptformular, wenn man will und hat mich ca. 1 Tag Arbeit gekostet. Und obwohl das garnichtmal so wenig ist, lohnte sich das trotzdem, da die Benutzbarkeit des Komponenten-Paketes ingesamt stark gestiegen ist. Und für den Anwender später ist der Aufwand extrem stark gesunken, meine Komponenten in ein vorhandenes System zu integrieren.
Insgesamt muss man sowieso immer mal wieder drüber nachdenken, wie es wäre, wenn man NICHTS über die eigenen Komponenten weiss und sie einsetzen muss. Am besten einfach mal ein leeres Projekt machen und versuchen, sie su implementieren. Dann fallen einem sehr schnell Schwachstellen auf.

Das gleiche gilt für den FormAccessManager. Diesen habe ich erst nach der Entscheidung zum Publish gebaut, um es für den Anwender einfacher zu machen, Formulare an Hooks anzubinden und diese anzuzeigen. In einem Modul mit 5 Formularen ist der Aufwand, diese anzubinden, von ca. 20 Zeilen pro Formular (also ca. 100 Zeilen insgesamt) auf 6 Zeilen geschrumpft, 5 davon im init-teil um die Formulare zu registrieren, 1 Zeile um auf sie zuzugreifen. Weiterhin stellte sich dabei das Problem der Daten für ein Formular, hier mal ein Screenshot als visuelles Beispiel :
user defined image

Um den Tree auf der linken Seite aufzubauen benötigt man folgende Daten :
- Name des Nodes
- Image des Nodes
- Parent name
- Parent Image

Letzeres eigentlich deswegen, da Parent-nodes kein Formular besizten und deswegen die Daten nicht über den Hook selbst kommen. Jedes Formular meldet sich dabei mit seinem Parent-Node an, welches erstellt wird, falls nicht vorhanden. Und zum Erstellen wird natürlich die entsprechende Information benötigt. Und da ich ja eher für generelle Sachen bin, lass ich die Formulare eben entscheiden, unter welchem Eintrag sie angemeldet sein wollen. Natürlich kommen Name und Image aus dem ResourceManager und werden bei Sprachumschaltung übersetzt. Auch die Bilder kann man in Update-Modulen ändern, ohne das ursprüngliche Modul zur Anzeige des Dialogs nochmal anzufassen.

Und gerade weil Daten auf die entsprechende Darstellung im System zugeschnitten sind oder sein sollten, musste ich mir zusätzlich einen Weg überlegen, wie ich das alles in einer Komponente unterbekomme, so dass sie später von Programmierern nicht nur benutzt, sondern auchg erweitert werden kann mit neuen Datentypen etc, ohne, dass diese sich fregen müssen, wie sie das ganze im DFM speichern. Ich selbst baue mir einen binären Stream für das DFM und mir ist es dabei egal, welche Daten das sind, die Daten-Typen so so geschrieben, dass ich sie wegschreiben und lesen kann, wenn sie bei mir registriert sind, was rein technisch auch zur Laufzeit geschehen kann. Das einzigste, was geändert werden muss für neue Typen : der Property-Editor. Aber jeder Datentyp hat eine Editor-Funktion, so dass auch das kein Problem ist.

Auch extra angefertigt wurde ein Registry-Mini-Treiber für die Hooks. Ursprünglich basierend auf einem Datenbank-System war natürlich die Benutzung auf Datenbank-Systeme beschränkt. Mit dem Registry-Treiber hat sich das geändert und nun ist es nun auch möglich, den Funktionsumfang in Projekten zu nutzen, die nichts mit Datenbanken zu haben (wollen). Es ist also rein technisch auch als ganz normales Plugin-System zu benutzen, mit dem Vorteil der dynamischen Funktionen etc. Dabei muss natürlich bedacht werden, dass manche Funktionen, die im DBTreiber drin waren, hier sinnlos geworden sind und deswegen nicht unterstützt werden. Zu nennen wären da Templates, die recht gross werden können und nichts in der registry zu suchen haben. Aber wenn doch benötigt, kann der Benutzer sich ja die Schnittstelle implementieren, den im Moment liest er ja nur keine Templates und schreibt sich nicht im Registry-Modul, aber die interfaces sind da.

Zum Marketing kann ich leider noch nicht soviel sagen, da ich gerade damit anfange. Zum einen ist es das Vorstellen in Foren wie hier, dann ein DevBlog (link oben im 1. Post) und dass man halt den Link zum DevBlob in seine Signatur der Foren, wo dies möglich ist, packt. Regelmässiges Posten in Foren zu Problemen hilft a) zu zeigen, dass man eine Ahnung von dem hat, was man tut und b) werden unterschiedliche Posts von unterschiedlichen Leuten gelesen. Das erhöht die Zahl derjenigen, die eventuell die eigene Seite besuchen und sich für das eigene Produkt entscheiden. Natürlich darf das nicht in Spam-Posts ausarten, das macht nicht nur einen schlechten Eindruck bei potentiellen Kunden, sondern man kann sicher auch schnell Ärger mit dem Admin bekommen :P
Weiterhin werde ich nächste Woche versuchen, mein DevBlog in Delphi-RSS-Feeds zu bekommen, so dass der Bekanntheitsgrad der Komponenten jetzt schon gesteigert werden kann, bevor sie überhaupt auf dem Markt sind. Damit weckt man das Interesse und kann sich Sorgen/Meinungen potentieller Kunden schon vorher anhören und evntuell drauf reagieren :)
Auch das Erstellen eines Demo-Programms und das zur Verfügung stellen einer Shareware-Version bei verschiedenen Komponenten-Seiten im Netz (Torry etc) hilft, die eigenen Komponenten zu vermarkten. Nichts desto trotz soll man so zeitig wie möglich damit anfangen, seine Komponenten im Netz bekannt zu machen, am besten schon mit der 1. Zeile Code, die man dazu schreibt.

Was allerdings recht schwer gerade bei nicht-visuellen Komponenten ist : Screenshots. Auch kann der User sich nicht viel unter einer ListBox vorstellen, wenn da 3 Einträge drin sind. Er weiss ja erstmal nicht, welche Technik dahinter steckt, diese Einträge zusammenzustellen.

Ich habe mich daher entschieden, dieser Tage eine Demo zu basteln, wo im oberen Teil der Anwendung die demo selbst auf TabSheets dargestellt wird und im unteren Teil in einem Memo der Code-Aufwand, um dies zu realisieren. Denn im Endeffekt geht es ja darum, dem potentiellem Kunden zu zeigen, wie einfach es ist, etwas mit diesem System zu tun :)

Ok, das war es erstmal für heute an Geschreibsel, dieser Tage folgt mehr mit Demo und vielleicht ein paar Schreenshots aus meiner ERP-Anwendung.
Hoffe natürlich, mit dieser ewig langen Vorstellung nicht zusehr gelangweilt zu haben, aber die erste Reaktion von Christian S. hat gezeigt, dass Interesse vom technisch versierten Programierern doch so gross sein könnte, wie ich es hoffe...

Und immer schön an einen meiner Leitsätze in der Programierung erinnern, das hilft bei der Entschedung, etwas zu machen : Andere Programmierer kochen auch nur mit Wasser !


matze - Sa 10.03.07 11:57

Hallo Helge.

Also ich möchte dir hier jetzt einfach mal ein großes Lob aussprechen. Dein Beitrag ist wirklich ein würdiger erster Beitrag für diese junge Sparte. :zustimm:
Alles gut, sauber und interessant beschrieben, sodass man sich was darunter vorstellen kann.

Ich bin schon auf die Demo-Programme und die Shareware Versionen der Komponenten gespannt :wink:


HelgeLange - Sa 10.03.07 15:02

Danke matze.. nach den Stunden an Arbeit, die man investiert hat, um den Beitrag zu schreiben, hört man das natürlich das natürlich doppelt gern.

Das Thema selbst ist für mich selbst schon immer interessant gewesen, weswegen ich wahrscheinlich auch die Energie reingesteckt habe, es zu programmieren. Nut fürchte ich auch ein wenig, dass der Text, der ja unbestritten über 3 Zeilen hinausgeht, vielleicht doch etwas zu lang geraten ist, damit er auch wirklich gelesen wird.

Was ich ausserdem total gern sehen würde hier, wären ein paar Tipps zu Marketing etc, da ich da etwas unbewandert bin, bin halt eigentlich nur ein Programmierschwein.
In einer Sache hatte ich Glück, zumindest für mein Land im Moment : Meine Freundin ist Journalistin hier für ein Business-Magazin, dadurch kennt sie natürlich alle möglichen Leute, auch in anderen Zeitungen/Magazinen und wird zum Release selbst eine Pressemitteilung machen und auch ein grossen beitrag für das grösste Technology-Magazin hier schreiben. Allerdings sind weder Venezuela noch Kolumbien (wo das Magazin erscheint) für ihre Software in der Welt bekannt ;) Aber ist besser als nichts.


JDKDelphi - Sa 10.03.07 15:49

Hallo Helge,

ich habe diesen Artikel mit äusserstem Interesse gelesen!

Such' schon lange nach einer ERP/CRM-Lösung, die ggf. in der Industrie eingesetzt werden kann. Ich programmiere so etwas in MAGIG oder IBOLT (Fa.(c)Magic)..

Sehr guter Artikel !!!


Gruss


Blawen - Sa 10.03.07 22:50

user profile iconHelgeLange hat folgendes geschrieben:
Danke matze.. nach den Stunden an Arbeit, die man investiert hat, um den Beitrag zu schreiben, hört man das natürlich das natürlich doppelt gern.

Das Thema selbst ist für mich selbst schon immer interessant gewesen, weswegen ich wahrscheinlich auch die Energie reingesteckt habe, es zu programmieren. Nut fürchte ich auch ein wenig, dass der Text, der ja unbestritten über 3 Zeilen hinausgeht, vielleicht doch etwas zu lang geraten ist, damit er auch wirklich gelesen wird.
Wenn Du den Text mit ein paar Bildern garnierst, lässt sich der Aufmerksamkeitseffekt problemlos steigern.
Du hast bisher ein Bild veröffentlicht und dies hat bei mir zumindest die Aufmerksamkeit geweckt! Gratulation auch von meiner Seite!


Christian S. - Sa 10.03.07 23:02

Hallo!

Auch von mir erst einmal großes Lob und Danke! Das ist genau so, wie wir uns Programmvorstellungen hier gedacht haben :-)

Ich finde den Text nicht zu lang, aber es würde vielleicht helfen, wenn Du ein paar Zwischenüberschriften in fett reinmachst, damit man eher den roten Faden erkennt.

Planst Du eigentlich auch etwas in Richtung .NET-Umsetzung?

Grüße
Christian


HelgeLange - Sa 10.03.07 23:10

Hi,

wie ich schon im Text oben erwähnt habe, ist es natürlich schwer, Screenshots für nicht-visuelle Komponenten zu machen, da ja die Komponenten nicht zu sehen sind. Bei denen kommt es drauf an, was sie unter der Haube haben. Der eine Screenshot war ein Beispiel aus meiner ERP Test Anwendung, bei welcher ich die Komponenten intensiv nutze.

Gerade in diesem Moment bin ich an der Umsetzung des Demos, natürlich modular, so dass ich immer mal neue Module nachschieben kann und der User sich nur diese laden muss und dazu installieren :)

Über die Möglichkeit der .NET Umseztung habe ich nachgedacht, muss aber erstmal evaluieren, ob das so überhaupt geht, den .NET hat viele Restriktionen. Ich arbeite zum Bsp. viel mit Pointern etc., Ich habe mehr "New"s und "GetMem"s im Code als alles andere.. (stimmt natürlich nicht, aber ich nutze das schon sehr häufig). Also muss ich erstmal rausfinden, wie ich das überhaupt in .NET ohne dies machen kann. Sowie das Release fertig ist, werd ich mir das mal anschauen, versprochen :)


Heiko - So 11.03.07 13:02

Hallo Helge,

ich hab mal eine kleine Frage bezüglich deines ersten Posts. Und zwar hast du ja geschrieben, dass man Methoden über deine Hook-Kapselung erweitern kann. Wie Variabel ist da deine Hookklasse? Also kann man da auf Parameter reagieren (also auf temporäre Variablen) und kann man seine Methode aufrufen lassen, bevor die "gehookte" an der Reihe ist?


MrSaint - So 11.03.07 13:43

user profile iconHeiko hat folgendes geschrieben:
und kann man seine Methode aufrufen lassen, bevor die "gehookte" an der Reihe ist?


Das würde mich auch interessieren ;) Wenn ich mir jetzt vorstell, dass ich so ein Programm mit deinen Kompos schreib und dann später dazu auch noch PlugIns. Angenommen, ich hab ein Plugin, dass bei irgendeiner Aktion, die das Programm macht, einen Dialog anzeigt und da dann irgendwas machen läßt. Und jetzt das zweite PlugIn, das das gleiche macht (man kann da halt irgendwas anderes mit einstellen), dessen Dialog muss aber zwingend vor dem Dialog des ersten PlugIns kommen (aus irgendwelchen Abhängigkeitsgründen). Geht sowas? Ich denke nämlich, dass das ein komplexeres Problem ist, da man ja nicht einfach jedem PlugIn einen Integer mit eineer Priorität mitgeben kann...

Allgemein find ich aber auch: Gute Arbeit! Sind hübsche Ideen mit dabei :)


MrSaint


HelgeLange - So 11.03.07 16:06

Wenn man in Hooks neuen Code einfügt, hat man eine Option :

Delphi-Quelltext
1:
     THookInsertDirection = (hidWhoCares, hidBefore, hidAfter, hidFirst, hidLast);                    


wobei hidWhoCares bedeuted, es wird eingefügt, wo Platz ist, hidBefore und hidAfter brauchen einen Bezugs-Punkt, also man sagt, dass man diesen Code vor oder nach einem bestimmten vorhandene Code-Teil haben will. Also ist es kein Problem, vor einem Code später noch einen Config-Dialog einzubauen etc.


HelgeLange - So 11.03.07 16:48

oh, glatt die Frage von Heiko vergessen. Ja, man kann Variablen, Objekte, was auch immer mitgeben und in den HookFunktionen manipulieren lassen. Das sah zwar erstmal nicht so aus, aber es gibt da 4 Events bei der Ausführung eines Hooks. Der 1. tritt auf, wenn der HookClient zum HookManager geht. In der Zwischenzeit wurde nämlich ein QueryInfoBlock erstellt und gefüllt und Speicher für eine var-Variable erzeugt. Im Event selbst kann man dann Felder des QueryInfoBlock nutzen oder auch einfach die var-Variable (ist vom Typ Pointer) und irgendwas dran hängen, was man halt so brauch.
Das nächste Event wird gefeuert, wenn der HookManager eine angemeldete Funktion ausführen will. Man erhält die gleichen Möglichkeiten wie vorher auch, allerdings ist dabei zu bedenken, dass sie vor jeder einzelnen Funktion innerhalb eines Hooks gefeuert wird, während die erste genannte nur einmal aufgerufen wird.
Nachdem eine Funktion innerhalb eines Hooks ausgeführt wurde, wird wieder ein Event gefeuert und der Aufrufer kann nun die ersten Ergebnisse lesen, die Daten für die nächste HookFunktion manipulieren oder zurücksetzen und auch FehlerCode auswerten und entscheiden, wie bei der Ausführung des Hooks weiterverfahren soll, kann die nächste Funktion überspringen, wenn er will oder den Hook gänzlich stoppen.
Sind alle Funktionen des Hooks ausgeführt, wird wieder ein einmaliges Event gefeuert, so dass man die Ergebnisse des Hooks auswerten kann, speicher freigeben, den man für die Funktionen des Hooks eventuell angefordert hatte etc.
Danach gibt der HookClient seinen angeforderten Speicher frei und landet wieder bei der Aufrufer-Funktion.

Um das ganze Variablen-Zeug etwas zu erleichtern, da es ja über Events geregelt wird (das muss so sein, da der HookClient sich um seinen Speicher kümmert, nicht der Anwender!), habe ich einen Stack dazu gebastelt. Da kann man Variablen drauflegen (String/Integer/Objekte/Pointer) und im Event wieder runternehmen und in den vom HookClient zur Verfügung gestellten Speicher legen. Dadurch hat man den grossen Vorteil, dass man Daten, die einem nicht selbst gehören, aber die an die Funktion, welche den dann Hook aufrufen, übergeben wurden, nicht zwischenspeichern muss in Variablen, die man extra dafür anlegt, sondern man pusht sie auf den Stack, ruft den Hook auf, der trottelt im 1. Event an (BeforeCallRouter) und dort poppt man sie vom Stack und arbeitet mit ihnen.

So, hoffe, die Frage nach Variablen ist ausreichend erklärt worden :)


MrSaint - So 11.03.07 16:58

user profile iconHelgeLange hat folgendes geschrieben:
Wenn man in Hooks neuen Code einfügt, hat man eine Option :

Delphi-Quelltext
1:
     THookInsertDirection = (hidWhoCares, hidBefore, hidAfter, hidFirst, hidLast);                    


wobei hidWhoCares bedeuted, es wird eingefügt, wo Platz ist, hidBefore und hidAfter brauchen einen Bezugs-Punkt, also man sagt, dass man diesen Code vor oder nach einem bestimmten vorhandene Code-Teil haben will. Also ist es kein Problem, vor einem Code später noch einen Config-Dialog einzubauen etc.



Hmm... das würde doch aber vorraussetzen, dass jedes PlugIn jedes andere kennt, oder? Weil sonst machen einfach beide PlugIns ein hidAfter (in Bezug auf den Original-Code im Programm) und dann ist wieder ein Konflikt da. Und da muss man dann ja auch Glück haben, dass die beiden dann gerade richtig rum angeordnet werden.
Ich mein, das ist schonmal ein guter Ansatz mit den HookInsertionDirections, aber es reicht wohl leider noch nicht aus. Eine Idee wie man das besser machen könnte, hab ich aber leider momentan auch net...
Ich stell mir das halt so vor, wenn ich mal 100 PlugIns oder so für ein Programm hab, dann weiß ein Programmierer, der jetz noch eins dazu programmiert nicht unbedingt die genauen Einstellungen von allen anderen und vergißt dann eben solche Seiteneffekte. Ganz zu schweigen, wenn man PlugIns für sein Programm von anderen Firmen oder sogar öffentlich (also dass jeder Mensch einfach ein Plugin schreiben kann, wies ihm so passt) programmieren läßt. Und durchtesten mit allen vorhandenen PlugIns kann ja auch net die Lösung sein...


MrSaint


EDIT: vllt wäre es eine Möglichkeit die Sortierung solcher PlugIns zentral auf einem Server zu managen und das Programm lädt sich diese Reihenfolge bei einer PlugIn-Installation einmal runter und passt das dann richtig an... Das würd mir jetzt dazu einfallen...


HelgeLange - So 11.03.07 17:28

Naja, diese Komponenten sind ja keine FreeWare/OpenSource-Komponenten, von daher, wird es nicht passieren, dass man etwas schreibt wie Miranda und die Welt schreibt Plugins.
Von daher reicht mein Ansatz, nämlich dem, der eine Software schreibt und später erweitern will, die Möglichkeit zu geben, die Position des neuen Codes innerhalb eines Hooks zu bestimmen. Und der sollte schon wissen, was bei ihm im System passiert, gerade wenn es um sensitive Stllen des Programms geht, bei denen die richtige Reihenfolge des Codes eine Rolle spielt.

Ich selbst benutzte das bisher 2 mal in meinem Programm, für alle anderen Hooks ist mir die Reihenfolge egal. Oft hat ein Hooks auch nur eine Funktion bei mir. Warum ? Weil ich den Code austauschbar machen wollte. Ich weiss oftmals schon im voraus, dass man da vllt mal was anderes dahinter stellen könnte.

Nehmen wir mal das Beispiel eines ERP-Systems. Was sind die Mängel aktueller Lösungen auf dem Markt ? Sie sind Monolith-Anwendungen, die alles schon können und daher im Preis extrem hoch. Das schreckt viele Anfänger mit einem Geschäft ab, weil die Software a) zu teuer ist und b) zu kompliziert, da man von Funktionen, die man erstmal nicht braucht, erschlagen wird.

Die Lösung dafür liegt auf der Hand : Man baut eine modulare ERP-Lösung, die wie ein Baukasten funktioniert. Das gibt dem Einsteiger die Möglichkeit, eine "kleine"Version für den Anfang zu kaufen, die genau das macht, was er erstmal braucht und nur einen Bruchteil kostet. Und wenn er später mehr braucht, kauft er sich die Module dazu, die ihm die Funktionen liefern, die im jeweiligen Moment benötigt werden.
Ok, das hört sich vllt. kompliziert an, aber es bringt Vorteile, denn für den Kunden fällt es am Anfang natürlich leichter, sich für eine 100-200 Euro Lösung zu entscheiden und die dann langsam zu erweitern, wie halt Geld reinfliesst (gerade am Anfang will man sein Geld so optimal wie möglich anlegen), zum anderen sieht der Kunde schon im Vorfeld, dass er sich "sein" Programm modellieren kann wie eine Statuette und kriegt nicht einen Klotz vors Gesicht gestellt. Das gibt ihm das Gefühl von Freiheit zu entscheiden, wieviel er bezahlt und ob er für etwas bezahlt, was er nicht braucht.

Die Lizenz für mein eigenes ERP-Programm wird zum Bsp. beinhalten, dass es frei kopiert und unbeschränkt evaluiert werden kann, aber wenn es komerziell eingesetzt wird (also in einem Shop etc.), muss es lizensiert werden. Das mache ich deswegen so, weil ich ja möchte, dass die Leute mein Programm weitergeben. Und heutzutage kann man es sich nicht wirklich erlauben, Raubkopien/unlizensierte Software in seinem Laden zu haben, wenn es nur um 200 euro geht. Plugins werden bei mir für 50 Euro wahrscheinlich angeboten, Festpreis. Das macht es dem Kunden einfach, zu kalkulieren.


Bex - Mo 12.03.07 10:45
Titel: Re: ERP Framework Components + Developers Blog
user profile iconHelgeLange hat folgendes geschrieben:
ERP (Enterprise Resource Planning, zu gut deutsch : Warenwirtschaft) - Systeme waren schon immer eine meiner Leidenschaften.


Sorry, wenn ich die allgemeine Begeisterung hier mal unterbrechen muss, aber: ERP mit WaWi zu übersetzen - darauf muss man auch erst einmal kommen (etwa so wie "Truck, zu deutsch Fahrrad").
Bei ERP geht es um weit mehr als bloß die Waren, beispielsweise Personal- und Finanzplanung, Material, Arbeitspläne, Kapazitäten, Produktionsprozesse etc.


Robert.Wachtel - Mo 12.03.07 11:02
Titel: Re: ERP Framework Components + Developers Blog
user profile iconBex hat folgendes geschrieben:
Sorry, wenn ich die allgemeine Begeisterung hier mal unterbrechen muss, aber: ERP mit WaWi zu übersetzen - darauf muss man auch erst einmal kommen (etwa so wie "Truck, zu deutsch Fahrrad").

Danke, dass es mal jemand erwähnt hat...


HelgeLange - Mo 12.03.07 13:51

doh.. und warum schreib ich dann extra hin "zu gut deutsch" ? Ich habe versucht, alles so einfach wie möglich zu halten, damit einfach jeder weiss, worum es geht. Leider ist es so, dass in Deutschland ERP für WaWi benutzt wird. Wie man "Enterprise Resource Planning" Wort für Wort übersetzt, weiss ich selbst. Und ich habe gerade nachgeschaut, auch Leo übersetzt Warenwirtschaft mit ERP :P
Also komm mal wieder runter.


Bex - Mo 12.03.07 14:31

Auch wenn LEO einem das einredet: ERP ist funktional etwas anderes als WWS, und die Übersetzung ist mindestens schädlich. ERP ist was für Industriebetriebe, WWS für Händler. Letzteres ist erheblich weniger komplex.
Just my 2 Cents.


HelgeLange - Mo 12.03.07 14:56

Das Problem liegt nicht bei mir, sondern bei dem allgemeinen denglisch in Deutschland.
Ich habe versucht, die Software-Vorstellung so allgemein wie möglich zu halten, so dass die verschiedenen Gruppen hier verstehen können, was gemeint ist. Nicht jeder versteht ERP oder kann sich unter "Enterprise Resource Planning" etwas vorstellen, aber unter Warenwirtschaft.

Und genau deswegen habe ich auch am Anfang darauf hingewiesen, dass man ERP zu gut deutsch als Warenwirtschaft-System bezeichnet, denn genau das machen die denglisch-Spezialisten in den Firmen, wenn sie ihre Reden halten :P

Dass meine Komponenten für beides gehen, dürfte auch Dir aufgefallen sein. Und von daher ist die Aussage "die allgemeine Begeisterung etwas dämpfen" etwas fehlerhaft, da Deine Kritik sich weder auf Funktionalität, Idee, Nutzen noch Originalität bezieht, sondern eben nur auf den "Fehler" im ersten Satz in einem Artikel, welcher versucht, jedem von der ersten bis zur letzten Zeile verständlich machen zu wollen, um was es geht.


Bex - Mo 12.03.07 15:05

Dann bitte ich um Nachsicht dafür, dass ich Deine Aussage "zu gut Deutsch" mit "gutem Deutsch" verwechselt habe. Ich halte es weiterhin für schädlich, die beiden Begriffe zu verwechseln (ist aber mein Privatvergnügen). ;-)

Edit: das mit der Begeisterung war in der Hinsicht gemeint, dass manche vielleicht ERP-Funktionalität in Deinen Komponenten erwarten ...


HelgeLange - Mo 12.03.07 15:21

ERP-Funktionalität ? von einem Framework ? Das wäre ja so, als würde man von einem TForm erwarten, schon 3D-animierte Charaktere darzustellen in wahlweise OpenGL oder DirectX...
Denn wie der Name "Framework" ja schon sagt, biete ich mit den Komponenten Rahmenbedingungen für ein modulares System (ob nun ERP oder WaWi), welches weit über herkömmliche modulare Plugin-Systeme hinausgeht, da diese Komponenten nicht nur irgendwo 'nen neuen Button hinsetzen oder ein Menü erweitern, sondern den Code von Funktionen eines solchen Systems auf einer frei vom Programmierer gewählten Ebene manipulieren können, ihn erweitern, verringern, ersetzen. Und dies, ohne ausgelieferte Module neu übersetzen und beim Käufer austauschen zu müssen.
Desweiteren bieten die Komponenten Nachrichten-Systeme für Fenster, welche auf Module verteilt liegen, sich nicht kennen und vllt. einfach nur auf einer gemeinsamen Basis arbeiten, und lässt diese miteinander kommunizieren. Denn oftmals ist dies auch das grosse Problem der Programmierer von solchen Systemen, worauf man sich entscheidet, alles in eine Anwendung zu packen und dies als 8MB-EXE auszuliefern.
Dazu werden Fensterklassen als Beispiel dazugelegt für verschiedene Anwendungsbereiche und in ihnen gezeigt, auf was meine Komponenten wert legen etc.

Alles in allem ist es ein Framework und keine ERP-Anwendung, die Komponenten sind dazu da, dem Programmierer später die Arbeit zu vereinfachen, da er sich nicht mehr mit der Basis-Programmierung rumschlagen muss, sondern seine Logik des Systems auf meinem Framework aufbaut.

Aber wahrscheinlich wirst Du jetzt etwas am Wort Framework auszusetzen haben und dass man es nicht in diesem oder jenem Kontext benutzen kann.. *grummel*


alzaimar - Mo 12.03.07 15:53

Einfache Frage: Du hast aber jetzt Warenwirtschaftskomponenten, und keine ERP-Komponenten, oder? Oder kann man mit deinen Komponenten auch Resourcen planen? Minimum Workflow und den ganzen Schmunz?


Sei mal nich so grummelig, ob das nun WaWi- oder ERP-Kompos sind... Ist doch wurscht, wie sie heißen. Wichtig ist, das die was taugen, oder? Dann kannst Du sie auch Horstel nennen. Und so wie das aussieht, sieht das doch nach was aus, oder?


Bex - Mo 12.03.07 15:59

Nicht grummeln, anscheinend war ich etwas zu pedantisch, was die Begriffe angeht - muss ich mir in diesem Forum wohl abgewöhnen. Aber: haben die Komponenten keine Funktionalität, verstehe ich das richtig?


HelgeLange - Mo 12.03.07 16:24

Also wir der Name schon sagt : Es sind ERP-Framework Components !

Ich frage mich, was an dem Wort Framework so schwer zu verstehen ist, besonders nach dem Lesen des Textes...

Was können meinen Komponenten nicht : Kaffee kochen, obwohl unerlässlich in jeder Firma, die ERP oder WaWi einsetzt und wo diese Programme durch Kollegen/Kolleginnen (nicht das jetzt noch ein Grüner kommt und meckert, ich würde die weibliche Belegschaft in Firmen nicht ausreichned würdigen... ;)) bedienen lässt...

Habt ihr denn den Text überhaupt gelesen ? Die Frage geht im Besonderen an Bex, der offensichtlich sehr penibel ist, aber anstatt lieber zu lesen, was die Komponenten können, erstmal die Frage stellt, ob die Komponenten "denn Funktionalität haben"...

ok, ich gebs auf, du hast mich erwischt, ich habe nur einfach von TComponent abgeleitet, der Klasse somit einen neuen Namen verpasst und versuch nun, diese zu verkaufen.. mist, das klappt jetzt wohl nicht. Du kannst jetzt mit dem Lesen hier aufhören, es geht wieder um Funktionalität...

@alle anderen, die es geschafft haben, den Text zu lesen : sorry, das musste jetzt raus.
Also ich biete nicht ERP-Funktionalität selbst an, sondern die Rahmenbedingungen, um ein modulares ERP-System mit viel weniger Aufwand als normal zu schreiben. Ich kann keinem Programmierer die Arbeit abnehmen, seine Logik zu schreiben und es ist auch nicht der Sinn dieser Komponenten. Ich habe versucht, einen Misstand zu beheben, den viele ERP-Systeme gemein haben. Dazu gehört die fehlende Modularität und Austauschbarkeit von Code, die Möglichkeit, Systeme durch "plugins" flexible zu erweitern ohne auf die Schwächen vorhandener Plugin-Systeme Rücksicht nehmen zu müssen. Zudem versuchte ich, eine Basis zwischen all den Programmen zu finden und etwas cleveres zu einzelnen Bereichen beizutragen. Da man selbst selbst bei vorhandener Kenntnis der Technik meines Systems (wie gesagt, auch ich koche nur mit Wasser) Monate braucht, um Vergleichbares nachzubilden, bietet sich hier einfach ein Markt, der bisher nicht erschlossen ist (zumindest scheint es mir so, ich habe nichts Vergleichbares gefunden).

Natürlich kann man die Komponenten auch für andere Systeme nutzen, wie WinAmp , ICQ oder Spiele, und ich hätte sie demzufolge auch Super-Hyper-Plugin-System nennen können, aber erstens ist es nicht nur das, es bietet viel mehr (näheres in den Eingangs-Posts von mir) und zweitens schreibe ich modulare ERP-Systeme seit Jahren und würde allein deswegen einfach mal in den Raum stellen, dass ich da nicht unbedarft bin und weiss ungefähr, was benötigt wird und habe meine Komponenten aus der Not des Nicht-Vorhandenseins solchiger geschrieben.

Ich habe nie behauptet, ERP-Funktionalität selbst anzubieten (jeder, der den Post wirklich gelesen hat, weiss das), und den Anspruch will ich mit den Komponenten auch nicht stellen, weder jetzt noch in Zukunft. Um was es mir geht und immer ging, sind die Funktionen, wie man ein modulares und einfach zu erweiterndes System aufbaut, wie man Kommunikation in einem System regelt, wo niemand niemanden kennt etc.


Bex - Mo 12.03.07 17:33

Tut mir wirklich leid, dass ich Dir "zu penibel" bin - aber wenn ich im Thread-Titel ERP lese und das noch weiter dauernd im Text vorkommt, dann fühle ich mich schon veräppelt, wenn es nichts mit ERP zu tun hat, was da angeboten wird. Du verkaufst ja auch keine Bleistifte unter dem Namen, nur weil man damit auch planen kann. Ist für mich Etikettenschwindel.


Christian S. - Mo 12.03.07 17:34

Könntet Ihr das bitte per PN klären? Ich denke, aller spätestens nach Helges letztem Posting ist klar, worum es geht, damit hat das hier nix mehr zu suchen.


Heiko - Mo 12.03.07 18:44

user profile iconHelgeLange hat folgendes geschrieben:
Wenn man in Hooks neuen Code einfügt, hat man eine Option :

Delphi-Quelltext
1:
     THookInsertDirection = (hidWhoCares, hidBefore, hidAfter, hidFirst, hidLast);                    

Hast du irgendwo auch eine Replace-Funktion? Also dass man eine Prozedur einfach so ersetzten kann? z.B. kann ja sein, dass einem eine Stelle überhaupt nicht gefällt, von der Funktionsweise her

z.B. gefällt einem das hier nicht:

Delphi-Quelltext
1:
2:
3:
4:
function CheckPW(PW: String): Boolean;
begin
  Result:= PW = 'Test';
end;

und will statt dessen

Delphi-Quelltext
1:
2:
3:
4:
function CheckPW(PW: String): Boolean;
begin
  Result:= md5(PW) = ...;
end;


Kann man also vorgefertigte auch erstezten, oder sind diese dann fest drin?

Aso, noch als Hinweis. Wikipedia hat ERP so übersetzt: "Planung [des Einsatzes/der Verwendung] der Unternehmensressourcen"


HelgeLange - Mo 12.03.07 20:04

@Heiko :

Wie ich erwähnt hatte, ist das ganze System skalierbar, d.h. der Programmierer entscheidet, an welchen Stellen er statt eines Aufrufs an eine ihm derzeit bekannte Funktion eine virtuelle Funktion setzt.

Virtuell deswegen, weil es die Funktion erstmal nicht gibt im System. Das ist eines der Grundprinzipien eines Keiner-kennt-keinen-Systems. Oder zumindest ist es meiner Definition nach so. Als Programmierer des Systems mit den "ERP Framework Components" weisst Du nur, dass es eine Funktion gibt, die macht, was du an dieser Stelle im Programm brauchst, aber Du weisst nicht, wo diese sich befindet oder wie sie es macht. Beides ist Dir auch egal, weil Du in diesem Moment eine Anforderung hast, diese mit dem Aufruf des Hooks artikulierst und der HookManager sich darum kümmert, dass die in diesem Augenblick gültige Funktion diese Aufforderung zugetragen bekommt.

Willst Du nun das Passwort, wie in Deinem Beispiel, überprüfen, kannst Du sogar viel weiter gehen, als nur die Funktion zu ersetzen. Du kannst sie universell machen. Du schreibst Dir für alle im System benutzten Programme mit Passwort (eine ERP-Landschaft kann ja aus n-verschiedenen Programmen verschiedener Hersteller bestehen, wobei Schnittstellen diese mehr oder minder kommunizieren lassen) eine entsprechende Funktion, die das Passwort prüfen kann. Soweit ist das ja auch im Programm ohne meine Komponenten gleich.
Hast Du nun sagen wir 5 verschiedene Programme, die Dir über ihre Schnittstelle Login/Passwort zur Verfügung stellen, allerdings die Passwörter auf verschiedene Art und Weise geprüft werden müssen, schreibst Du einfach die 5 Funktionen für die verschiedenen Systeme, hängst alle an einen Hook und wertest das Ergebnis aus, denn war das Passwort richtig, wird Dir das eine der Funktionen im Event melden und Du kannst weitergehen in Deinem Programm. Meldet keine der Routinen Erfolg, war das Passwort falsch oder mit einer 6. Methode encrypted.
Wo wir bei dem zweiten grossen Vorteil sind. Taucht nämlich die 6. Methode auf, müsstest Du an Deinen Code wieder ran, diese Methode integrieren und dein Programm mit allen 6 System-Schnittstellen und ihren Passwörtern testen und dann wieder ausliefern. Unter Umständen kann es Probleme bei denen Deiner Kunden geben, die die 6. Methode garnicht brauchen etc...
Mit den "ERP Framework Components" schreibst Du nur die Methode in ein gesondertes Modul für die Kunden, die das brauchen, meldest dort die Funktion unter dem gleichen Hook wie die anderen an und fertig. Du brauchst weder dem Kunden ein komplettes Set neuer Module unterschieben noch ihm die EXE neu übersetzen, weil sich der Code geändert hat. Und wie gesagt, Du kannst es an denjenigen ausliefern, der es wirklich braucht. Das verringert zusätzlich die Gefahr sogenannter Side-Effects bei Systemen, für die das update nicht gedacht war (weil ihnen das 6. Programm fehlt).

Und natürlich kann man einzelne Funktionen eines Hooks löschen oder umleiten. Gefällt einem Kunden ein Dialog nicht mehr und dein Designer (oder eben Du) hat sich rangesetzt, einen neuen zu erstellen nach den Wúnschen des Kunden, musst Du danach nicht ihm das komplette Modul austauschen mit seinen 50 Funktionen, sondern ein neues Modul machen mit dem neuen Dialog und leitest die Funktion um, so dass statt die Funktion in Modul A aufzurufen, diese jetzt in Modul F zu finden ist.


HelgeLange - Mo 12.03.07 21:06

@Bex: Leider machst Du immer noch den Fehler, "ERP Components" und "ERP Framework Components" zu verwechseln. Entweder willst Du das Wort Framework nicht sehen, oder aber du kannst den Unterschied zwischen einem fertigen System und einem Framework für ein System nicht verstehen.

Was ist ein Framework ?

Das dt. Wikipedia sagt dazu :
Zitat:

Framework (engl. für Rahmenstruktur, Fachwerk) ist ein Begriff aus der Softwaretechnik und wird insbesondere im Rahmen der objektorientierten Softwareentwicklung sowie bei komponentenbasierten Entwicklungsansätzen verwendet.
Wörtlich übersetzt bedeutet Framework (Programm-)Gerüst, Rahmen oder Skelett. Darin wird ausgedrückt, dass ein Framework in der Regel eine Anwendungsarchitektur vorgibt. Dabei findet eine Umkehrung der Kontrolle statt: Der Programmierer registriert konkrete Implementierungen, die dann durch das Framework gesteuert und benutzt werden, statt – wie bei einer Klassenbibliothek – lediglich Klassen und Funktionen zu benutzen.
...


"ERP Framework Components" in einem modularen System

Mein Komponentenpack stellt somit Komponenten für ein Framework zur Verfügung und übernehmen innerhalb des Frameworks spezifische Aufgaben. Aber ausserdem geben sie auch den Rahmen vor : es muss eine modulare Anwendung sein. Warum ist das so wichtig ? Weil es keinen Sinn macht, meine Komponenten in einer 8MB-EXE unterzubringen, da diese sowieso neu kompiliert werden muss, wenn etwas geändert wird.
Sehr wohl kann die EXE allerdings die Basis eines modularen Systems sein, aber selbst keine Module zu besitzen im Ursprungs-Zustand und erst zusätzliche Funktionalität aufweisen kann, wenn Module hinzugefügt werden. Wie das modulare System kommuniziert gebe ich vor, wenn meine Komponenten eingesetzt werden (sofern der Programmierer alle benutzt, das hängt von ihm ab, allerdings manche Komponenten benötigen andere im System, um lauffähig zu sein, das bedingt die Architektur).
Dabei sind die Komponenten selbst mehr oder minder konfigurierbar in ihrer Arbeitsweise, einmal zur Designtime und auch zur Runtime. Das heisst, es gibt zwar Vorgaben, wie manche Prozesse laufen müssen (Deklaration von Funktionen für den HookManager, um als solche benutzt werden können zum Bsp.), aber das ist offen genug, um akzeptiert zu werden und vergleichbares wird ja innerhalb von ziemlich jeder Hochsprache benutzt.

Warum beinhaltet der Name die 3 Wörter "ERP", "Framework" und "Components" in dieser Reihenfolge ?

ERP, weil ich denke, in ERP (und ERP-ähnlichen) Systemen sind sie am besten aufgehoben, da genau dort diese modulare Funktionalität benötigt wird und ich dort das Kunden-Potential sehe. Ich hätte sie auch Hundefutter nennen können, doch eine Suche eines potentiellen Kunden würde meine Komponenten dann nicht als Ergebnis bringen. Dafür würde ich viele Anfragen von Hundebeitzern bekommen, wie ich das mit den Modulen bei Hunden meine und ob Hunde auch mit allen Modulen gleichzeitig spielen können. ;)

Framework, weil sie nicht die ERP-Funktionalität selbst abbilden, sondern für das Grundgerüst eines Programms gedacht sind, welches ERP-Funktionalität implementiert. Das hat den Vorteil, dass ich dem potentiellen Kunden nicht in die Lage bringe, sich meinem Denkschema in seinem ERP-System anzupassen. Dass ich ihn in mein modulares Denkschema presse ist aber ein eher gewollter Effekt, der uns beiden zugute kommt. Und der auch vom Käufer so gewollt ist. Niemand kauft sich Hundefutter und fragt sich danach, warum der Fernsehempfang auf der Hundefutter-Tüte schlecht ist.

Components heisst es aus 2 Gründen.
1.) Ich biete kein komplettes Framework an, da es eventuell wiederum den Anwender der Komponenten einschränken würde. Es muss meiner Meinung nach genug Platz für eigene Ideen da sein. Und so wie ich das sehe für meine "Babies", mache ich dem Programmierer sogar mehr Platz, als er mit den jetzt erhältlichen Plugin-Systemen hätte.
2.) Es ist Mehrzahl, denn in dem Pack gibt es mehr als eine Komponente, die mehr als einen Bereich abdecken. Dazu gehört das Hook-System der dynamischen Funktionen selbst, sowie Kommunikations-Komponenten, Daten-Zugriffs-Komponenten und und und (Siehe Beschreibung in den Eingangs-Posts).

Insgesamt könnte man es ins Deutsche mit folgenden Worten übertragen : Komponenten für ein Basis-System von ERP-Software. Ok, da sind immer noch viele englische Wörter drin, nur benutzen wir die ja eh im Deutschen genau so.

Abschliessende Betrachtung

Aus den oben angeführten Argumenten erkennt man, dass es kein Etiketten-Schwindel ist, meine Komponenten als "ERP Framework Components" zu bezeichen, da es Komponenten sind, welche für ein Framework eines ERP-Systems gedacht waren (immer noch sind !) und der Name nur als komplette Einheit zu betrachten ist. Sie erheben weder durch Namen noch durch Inhalt den Anspruch, ERP-spezifische Aufgaben zu erfüllen, sondern sie können innerhalb eines Frameworks für ein ERP-System Aufgaben übernehmen und somit dem Programmierer eines solchen Systems die Arbeit ungemein erleichtern.
Jeder Hersteller von ERP-Systemen entwirft mehr oder minder sein eigenes Framework dazu. Wie ausgeklügelt dies ist, sei in den Raum gestellt, aber ich kann mit meiner Berufserfahrung im Allgemeinen und mit meiner spezifischen Erfahrung in der Programmierung modularer Systeme mit Bestimmtheit sagen, dass meine Komponenten die Arbeit definitiv leichter und universeller machen, dazu dem Hersteller von ERP-Lösungen eine Menge Geld sparen, denn es dauert Monate, Vergleichbares zu meinen Komponenten zu programmieren, selbst wenn man die Idee selbst hat. Gerade auch weil so ein System wächst. Die Komponenten meines ERP Framework-Packs sind auch nicht mit einem mal entstanden und seitdem in dieser Fassung, sondern sie unterliefen einem Entwicklungsprozess.


Bex - Di 13.03.07 11:59

Ich denke, die Diskussion über Deine Namensgebung führt nicht wirklich weiter; jeder Kunde muss selbst entscheiden, ob er sich bei Dir wiederfindet oder nicht. Für mich sieht Dein Ansatz nach einem generischen Framework aus (Schade um die Einschränkung auf ERP) ...

Was das Framework betrifft: die Idee finde ich nach wie vor gut; mir hat sie schon in den 90-ern gefallen, als IBM dasselbe vorhatte, was bei Dir die Grundidee hinter dem ganzen zu sein scheint (Stichwort SanFrancisco). Die haben das ganze leider nicht mehr weiterentwickelt. Ich drücke Dir die Daumen, dass Du die nötige Entwicklerpower zusammenbekommst, um es besser zu machen ;-)


HelgeLange - Di 13.03.07 20:30

Leider kenne ich die Idee von IBM nicht, von daher kann ich nicht sagen, was die vorhatten oder so.
Meine Idee funktioniert seit einigen Jahren sehr gut, ich brauche da keine weiteren Entwickler, um dies fertig zu stellen, denn alles, was ich im Moment mache, ist polieren und einige Routinen, die ich drin haben will vor dem Release, um es den Leuten einfacher zu machen, mit meinem System zu arbeiten.

Dass das System sehr generisch sein kann, ist mir auch klar und habe ich ja auch im Beitrag so gesagt. Nur sehe ich das Kunden-Potential hauptsächlich in der ERP-Entwickler-Ecke, aus verschiedenen Gründen, denn diese Leute bauen Anwendungen, welche

1.) Modularität und Austauschbarkeit haben sollten
2.) gross genug sind, um das potential wirklich zu nutzen
3.) einen Datenaustausch und eine Erweiterung der Datenverarbeitung benötigen

Nichts desto trotz habe ich ja einen Mini-Treiber gebaut für den HookManager, der mit der Registry arbeitet und dadurch auch für viel kleinere Programme, die ohne Datenbank auskommen (müssen), genutzt werden kann.

Aber durch die Namensgebung mache ich ja hauptsächlich die Gruppe auf mich aufmerksam, welche ich mit dem Produkt vorrangig ansprechen will. Wenn mich noch andere finden und zuschlagen... ich kann damit leben ;) Vielleicht wird es die Komponenten für die dynamischen Funktionen auch in Zukunft als Mini-Package geben, nur mit den Registry-Treiber daherkommen und ohne die Lizenz, diesen mit mehr zu nutzen als diesem Treiber, wobei das "grosse" Paket andere Treiber (für andere Datenbanken), die auch vom Käufer entwickelt werden können, nutzen können. Das Framework dafür ist geschaffen durch eine Objekt-Orientierte Programmierung, so dass nur die Datenbank-spezifischen Funktionen, welche in einem DB-Objekt gekapselt sind, auf eine andere DB umgeschrieben werden müssten.

Alles in allem kann es ein Paket sein, was viel mehr Leute anspricht, als nur ERP-Software-Entwickler, nur besteht dort eben das Problem, dass man den Namen hätte allgemein halten müssen und dann wird das Interesse von den Leuten, für die ich es gebaut habe, nicht geweckt :(

Grüsse aus Caracas,


Bex - Mi 14.03.07 15:27

War ein Java-Framework. Ganz guter Überblick: http://www.sts.tu-harburg.de/slides/1999/11-99-Schm-OS-SanFrancisco.pdf

Auf dem Framework basierend sollte beispielsweise im Fiscus-Projekt die einheitliche Software für alle deutschen Finanzämter implementiert werden. Zum Thema SF sind zwischen 1997 und 2001 diverse Diplom- und Doktorarbeiten geschrieben worden - ich kann Dir gerne ein paar Titel heraussuchen, wenn Interesse bestehen sollte.

Wie schon gesagt, SanFrancisco wurde von IBM beerdigt (ich glaube endgültig 2002). Das Hauptproblem war, wenn ich mich recht erinnere, dass nicht genügend andere Softwareentwickler auf den Zug aufgesprungen sind.


HelgeLange - Mi 14.03.07 16:25

Das spielt ja für mich dann eher keine Rolle, da mein System sich damit beschäftigt, dies innerhalb eines Programmes zu bewerkstelligen. Ich will nicht den Anspruch erheben, ein Framework zu erschaffen, welches von sich aus n-verschiedene Programme unter einen Hut bringt oder eine gemeinsame Entwicklungs-Basis für verschiedene Programme zu schaffen, die dann über diese Basis kommunizieren sollen.

Wie ich im Beitrag die ganze Zeit klar gemacht habe, besteht das Framework aus mehreren Komponenten, wobei eine davon lapidar (und abwertend) als Plugin-System bezeichnet werden kann. Denn was heutzutage als Plugin-System bezeichnet wird und Anwendung findet, wird meine Meinung nach dem namen gerecht, aber von der Funktionalität und den Möglichkeiten meines Systems weit übertroffen. Alles weitere dazu eben in den vorherigen Posts...

Btw.. die Demo verzögert sich etwas, denn hier gab es im Kabel-System vorm Haus eine Explosion und scheinbar hat es meinen Arbeits-Computer mitgerissen. Ich bin gerade dabei, ihn zu fixen.


HelgeLange - Mi 21.03.07 02:06

Hi, mal wieder ein kleines update... weiss ja nicht, ob die interessierten Leser auch mein DevBlog lesen :)

Zur Zeit baue ich grad den Router um, der kriegt 4 neue Komponenten spendiert und verliert dabei 'ne Menge Code. Warum das ganze ? Es wird der komfort erheblich erhöht, es kommen ein paar neue Funktionen dazu und es wird die chance auf ein kleineres, billigeres non-source-Paket erhöhen.

Wer den Thread bisher gelesen hat, wird wissen, dass der Router aus mehreren Teilen besteht. Da diese alle im ganzen Programm nur 1x benötigt wurden/werden, sah ich bisher noch keine Veranlassung, diese als Komponenten zu schreiben, sie waren Teils im DatenModul, teils in Objekten vergraben.
Nun habe ich mir einige Teile rausgesucht und schreibe diese grad als non-visual-Komponents um.

- HookManager
- DB Zugriff
- SecurityLayer

HookManager & SecurityLayer werden dabei mit der DB Komponente verknüpft und können ihre Daten von dieser beziehen. Die DB-Zugriffs-Komponente ist wieder als Custom-Variante mit vielen abstracten und virtuellen Methoden als Basis vorhanden, diese ist keine Komponente in der Komponenten-Palette, dafür gibt es eine integrierte Registry-Access-Komponente sowie in jeweils extra Packages für verschiedene Datenbanken Ableitungen dieser Basis-Komponente.

Den SecurityLayer kann/muss man mit der HookManager-Komponente verknüpfen. Ist sie nicht verknüpft, werden keine Sicherheits-Profile geladen und gut. Ist sie da, hat man 2 Möglichkeiten :

1.) Vorgegebene Tabellen zum Laden der Rechte benutzen, wobei die Tabellen-Beschreibungen für jede Datenbankart als sql-Script mitgegeben werden
2.) Benutzerdefiniert laden, wobei eigentlich ein Event gefeuert wird, der Nutzer drauf reagieren kann, die Daten laden, wo er möchte und dann per API hinzufügen.

Was meint ihr : Ist es generell problematisch, Tabellen vorzugeben für ein Produkt, was zum Teil auf Datenbank basiert ? Irgendwo muss ich meinen Kram ja auch speichern, oder ? gerade wenn es um dynamische Sachen geht, die mit jedem installierten Modul sich ändern. Die andere Möglichkeit wäre eben, es vollkommen Laufzeit-abhängig machen, das heisst, alle Daten werden von den Modulen beim Start angefordert, einsortiert, verworfen etc., also alles, was ich sonst beim Install einmal mache und gut...

Würde mich über Antworten freuen


HelgeLange - Sa 24.03.07 02:01

hm.. es gab zwar in den letzten 2-3 Tagen ca. 400 Zugriffe, aber keine Antwort.

Also, der augenblickliche Stand ist folgender :

THookManager : 90% done
die fehlenden 10% bin ich mir nicht sicher, ob ich sie vor dem Release einbaue, denn sie sind eine reine Neuerung. Beim Umbauen habe ich halt festgestellt, dass wenn ich eh schon am Code so derb rumbaue, dann kann ich es auch gleich richtig machen. Habe dazu die Speicherverwaltung für die DFT (DynamicFunctionTable) umgeschrieben und kann rein technisch das Erstellen der DFT beim Programmstart machen, muss nur den entsprechenden Code für re-init etc implementieren. Dazu gibt es eine Boolean-property SaveDFT, welche zur Designzeit bestimmt, ob ein angeschlossenes DBObject zum speichern in eine DB genutzt werden soll. Steht diese auf False, wird beim Start die DFT aus den registrierten Modulen frisch gebaut (langsamer, logischerweise... allerings nur beim Start, danach ist alles gleich).

user defined image

die Properties :
AutoLoad : die Komponente lädt Module und DFT automatisch, da gibt es noch einen kleinen Timing-Bug, wenn die Komponente eher geladen wurde als die Datenbank und ich will mich nicht an deren OnConnect hängen... überlege mir noch was dazu
BaseDB : die verbundene BaseDB Komponente (siehe weiter unten)
FunctionCount : zeigt an, wieviele Dynamische Funktionen geladen sind
ModuleCount : zeigt an, wieviele Module geladen sind
ModuleLoadMethod : mlmDataBase = es wird von Datenbank die Liste der Module genommen, das ist gut, wenn ein Netzwerk-LW alle module beinhaltet, aber je nach Workstation nur eine Selektion geladen wird. Im Gegensatz dazu die Einstellung mlmDirectory, wo alle Module aus einer Directory geladen werden, geprüft, ob es ein Modul für das ERP-System ist und dieses dann entsprechend geladen. Funktioniert gut, wenn man eine IT-Umgebung hat, wo jeder Rechner sein eigenes Module-Verzeichnis hat oder wo alle Clients alle Module laden müssen.
ModulePath : wird für 2 Sachen genommen. Einmal für die Einstellung ModuleLoadMethod und auch für das Laden der Module selbst, da diese ohne Pfad in die DB geschrieben werden.
Name : Kopmponentenname natürlich
SaveDFT : gibt an, ob die BaseDB-Komponente zum speichern benutzt werden soll
SecurityLayer : gibt die SecurityLayer-Komponente an. Ist sie nicht angegeben, werden alle Dynamischen Funktionen geladen.

TERPCustomBaseDB & TFIBBaseDB :

Während TERPCustomBaseDB eigentlich nur vorgibt, was da sein muss und dadurch eine gemeinsame Basis für alle BaseDB-Ableitungen bildet, ist TFIBBaseDB die eigentlich Implementierung. Einige Funktionen kann man natürlich schon in der Base-Komponente machen. Aber das sieht man ja dann im source. Auch hier das OI-Bild dazu :

user defined image

Gehen wir auch hier mal durch die Properties:
ComputerName : Name der Workstation
Connected : True setzt (oder versucht es eben) die DB-Verbindung auf Active/Connected.. je nach dahinterliegender DB
ConnectionData : Zeigt Conenction-Data an, ID des Users (aus DB), die SessionID und wann die Session gestartet wurde.
Database : hier setzt man die zu benutzende Datenbank-Komponente, in diesem Fall gehen nur die von FIBPlus, es wird aber noch weitere anleitungen geben, welche andere DB-Komponenten einbinden
DataBaseName : Connections-String für die Datenbank, jeder Interbase/Firebird-Nutzer kennt den ;)
HookLoadOptions : Je nachdem, was in StoreTableName eingestellt ist, wird entweder der Name der Workstation (aus CompuerName), der Name des Users oder eben nichts als Prefix genommen. Dadurch ist es möglich, das Laden von Modulen und Funktionen abhängig von Workstation oder Nutzer zu machen bzw. es für alle gleich. Das bringt den Vorteil, dass Funktionen bei der Einstellung stnWorkStation immer die gleichen Module geladen haben, egal, wer den Rechner benutzt (dazu kommt aber noch der SecurityLayer, welcher Benutzerabhängig ist). Bei der Einstellung stnUser wird der Username benutzt, so dass ein User auf allen Rechner mit "seinen" Modulen und Funktionen arbeiten kann.
HookTableSuffix : gibt den Suffix der Hook-Tabelle an, wo die vorgebauten dynamischen Funktionen gespeichert werden. Je nach Einstellung in StoreTableName wird der Name der Tabelle dann <UserName>_<HookTableSuffix> oder <ComputerName>_<HookTableSuffix> oder eben nur <HookTableSuffix> bei der Einstellung stnUserDefined.
PluginTableSuffix : siehe HookTableSuffix, nur eben für Module
für beide wird in der read-only-property HookTable und PluginTable der so zusammengesetzte Name angezeigt zur Designzeit.
Name : wieder mal der Name der Komponente
Password, Role und User : sind für die Datenbank-Komponente
Transaction : die Transaktions-Komponente, in dem Fall von FIBPlus

Es fehlen noch Funktionen zum erzeugen der DataSets für DB-unabhängige Programmierung, der Code ist schon da, muss aber eben noch übertragen werden aus dem ehemaligen Objekt in die neue Komponente. Ausserdem schreibe ich noch am Funktionszeiger-Mapping für TQuery-Objekte, weiss aber noch nicht, ob es funktioniert, ista uch nicht so wichtig, wird es wohl eh nicht in das aktuelle Release schaffen.

Ausserdem gibt es jetzt eine non-visual-component TERPGlobalVars, welche global Variablen speichert und lädt und deren Inhalt über den HookClient von überall abfragbar bzw. setzbar ist. Diese habe ich zur richtigen Komponente umgebaut, um den Code zu reduzieren im Router.

Nichts desto trotz würde mich mal noch einiges an Meinungen interessieren. Man schreibt es ja nicht nur wegen Verkauf, sondern wünscht sich auch Feedback :)

Grüsse aus Caracas


Zauberfalke - Sa 24.03.07 05:31

Hört sich alles sehr interessant an, und für mich ist auch die Namensgebung verständlich. Erst ein Praxisttest allerdings wird zeigen, ob es für meine Zwecke verwendbar ist. Wird das Framework auch mit Sourcen zukünftig angeboten ?

Leider kann ist die Website nicht erreichbar, wird da gerade umgebaut ?


HelgeLange - Sa 24.03.07 06:44

natürlich wird es auch mit Source angeboten. Manche Erweiterungen/Anpassungen gehen ja eigentlich auch nur mit Source. Gerade, weil es ein Framework ist und ich nicht ALLES voraussehen kann ;) Aus diesem Grund wird viel mit Custom-Komponenten gemacht (wo es Sinn macht), so dass später die entsprechenden Anpassungen gemacht werden können.

Bsp.: TERPCustomBaseDB implementiert nicht viel. Mehr stellt es nur die notwendigen Schnittstellen zur Verfügung. Es werden natürlich ensprechende Komponenten mit der finalen Implementierung zur Verwendung als auch als Beispiel zur Verfügung gestellt. Man steht also nicht im Dunkeln, sondern kann sich bei den abgeleiteten Datenbank-Komponenten anschauen, wie es implementiert wurde und es für "seine" Datenbank (falls noch keine Komponente verfügbar ist von mir) anpassen (meist ist es SQL austauschen und mit einer anderen Database/Transaction-Komponente verbinden, sowie Login anpassen). Das sollte aber in ein paar Stunden zu schaffen sein.

Btw... die neue Domain ist da, die Website ist jetzt unter http://www.erp-components.com zu finden :D


HelgeLange - Do 05.04.07 17:53

so, fast 2 Wochen schwerster Entwicklungsarbeit und einige gute Ergebnisse vorzuweisen...
Zum einen sind ein paar neue (und wie ich meine, gute) Komponenten entstanden, ausserderm hat sich logischerweise die Benutzbarkeit erheblich verbessert.
Ich gehe mal etwas kürzer drauf ein als zuvor, da der Thread zwar offensichtlich viel gelesen wird, aber kaum jemand irgendeine Meinung hat zu den Änderungen und Fortschritten, die ich hin und wieder poste.

Zum einen ist eine neue Komponente "TERPHookAccessContainer" entstanden, welche eigentlich nur 2 Sachen machen sollte, aber jetzt noch ein bissl mehr kann.
Ursprünglich sollte sie als ModulEditor dienen, wo man komfortabel mit Komponenten-Editor den Code für die dynamischen Funktionen verwalten kann (anlegen, löschen etc).Das geht auch soweit ganz gut, die Idee dabei war ja auch, dass dieser hier verwaltete Code sich automatisch beim Start des Programms anmelden "kann", so dass die dynamische Funktions-Tabelle beim Start on-the-fly erzeugt werden kann. Natürlich ist das Laden einer fertigen Tabelle schneller.
Hinzugefügt habe ich dann noch einen EventManager, so dass man für für einzelne Funktionen spezielle Events feuern kann, anstatt (oder zusätzlich, das ist einstellbar in der Komponente) das Standard-Event zu feuern. (Zur Erklärung : im Event wird der Code des SubHooks ausgeführt). Ausserdem kann man zur Laufzeit Events hinzufügen, kann mehrere ausführen lassen oder vorhandene ersetzen, das hängt von den Einstellungen ab, die man in den properties der Komponente macht.
Das gab mir die Möglichkeit (ist mir so beim rumspielen mit der Komponente - man würde in Fachkreisen "Test" dazu sagen), die API der Manager innerhalb der Komponente zu "verstecken". Weisst man also jetzt einer der Manager-Komponenten den ERPHookAccessContainer (kurz: HAC) zu, meldet sich die Komponente automatisch mit ihren Funktionen bei dieser an und wenn eine Client-Komponente einen API-Aufruf macht, wird, solange man die Funktion nicht ausserhalb überschreibt, über den HAC die Komponente angesteuert. Dadurch konnte ich nun endlich den Router.dll-Code auf 20 Zeilen reduzieren (ich brauch ja noch einen Einsprungpunkt und Init-Teil des Moduls ;) ). Aber in der Basis ist nun das Bauen des Router eigentlich nur Drag'n'Drop und das Verknüpfen der Komponenten. Piece of cake!

Ausserdem hat der TERPHookManager (kurz : HM - das Herz der dynamischen Funktionen) einen Editor spendiert bekommen. über diesen kann man Module an/abmelden, Hooks editieren (sofern man ein Datenbank-Objekt benutzt und die DFT nicht automatisch beim Start bauen lässt) und sogar über die TERPTemplate-Komponente Beschreibungen zu Hooks und SubHooks speichern (diese werden allerdings nicht mit den Hooks gespeichert, sondern in einer Template-Tabelle, so dass es leicht ist, diese NICHT zum Kunden mit auszuliefern). Ausserdem kann man, sofern der HM eine SecurityLayer-Komponente angeschlossen hat, Funktionen im SecurityLayer kapseln, diese werden dann, wie schonmal beschrieben, geschützt.

Desweiteren habe ich die Datenbank-Komponente für FIBPlus erweitert, sie kann nun auch Update-Transaktionen benutzen, sofern diese angegeben wurde. Das heisst, immer wenn HM, SecurityLayer etc. etwas in der Datenbank zu speichern haben und es gibt eine Update-Transaktion, dann wird diese benutzt, ansonsten die normale (FIBPlus-User wissen, was ich meine ;))

Zur Zeit arbeite ich an der Umsetzung der Pseudo-DB-Komponente der Registry, dazu wird der DFT gepackt und als Bin-Stream (anstatt frei editierbar für Programmierer in der richtigen DB-Variante) in der Registry untergebracht. Die Streams sollten nicht allzu gross sein, schliesslich ist es ja vor allem für kleinere Projekte gedacht.

Ausserdem wurden der ResourceManager und LinkManager als Komponente umgeschrieben, sie können nun auch auf ein Datenmodul oder Formular geworfen werden, melden sich über den HAC mit ihrer API an und gut. 0 Zeilen Code zur Verwaltung. Das gibt auch die Möglichkeit, alle Manager in einem SuperManager unterzubringen, ohne dieübersicht zu verlieren (was ein Grund für die Trennung der verschiedenen Manager war neben der Modularität). Die Entscheidung wird nachher beim Kunden liegen, wie er seine Verwaltung bauen will, ich werde einfach die Trennung im Paket beibehalten und zusätzlich ein Projekt beilegen, welches alles in einem vereint. Natürlich steht es durch das neue Komponenten-System jedem frei, sich "seinen" Supermanager selbst zu basteln. Ausserdem ist die API so gehalten, dass es einfach sein wird, eigene Ideen in Managern umzusetzen und diese ins vorhandene System zu integrieren (dazu gibt es ja einen Manager-Loader TManagerBaseContainer, sie ein paar Posts weiter oben).

Ausserdem hat sich schon ein bissl was auf der Website getan, heute ist (bedingt durch die Karwoche, "Semana Santa" hier, wo es bei der Familie meiner Freundin Tradition ist, zusammen zu Abend zu essen und ich nun auf's "Dorf" fahren musste) Doku-Schreibe-Tag, so dass ich einige neue Artikel auf der Website schreiben werde.

Alles in allem hoffe ich, im Laufe der nächsten Woche mit allem fertig zu sein und Euch damit auch endlich die Demo anbieten kann, die zwar in Arbeit ist, aber aufgrund der Änderungen erstmal zurückstehen musste.

Ok, soviel für heute, würde mich immernoch über ein paar reaktionen freuen...
Helge


HelgeLange - Mi 11.04.07 19:35

Hallo mal wieder.
Heute ist endlich die Demo fertig geworden, habe nochmal ein paar der älteren Komponenten auf neueste Entwicklungen angepasst und getestet. Soweit ich das bisher gesehen habe, läuft die Demo stabil, konnte erstmal keine Fehler produzieren.. Später am Tag werde ich dann noch den Source posten, so dass jeder mal gucken kann, was der Lange da eigentlich so treibt, um das in der Demo so hinzukriegen :)

Viel Spass damit...

PS.: Setze den Download-Link in den ersten Beitrag


Zauberfalke - Do 12.04.07 07:39

Jetzt wird es interessant !
Theorie ist schön und gut, aber erst "Hands-on" und eigene Experimente werden die Möglichkeit(en) der Verwendung des Framworks in eigenen Projekten zeigen.

Für mich ist noch interessant:
Welche Test-Verfahren bzw. Tools werden eingesetzt um die Qualität bzw. Fehler des Codes zu überprüfen ?
Ist ein einwandfreies Resourcen-Management gewährleistet (keine Objekt Leichen etc) ?
Wird unter WindowsXP/64 entwickelt (wg. Angaben im Profil) ?
Wie sieht es mit Delphi2007 und Vista aus ?

Michael Jung
mijn-design


HelgeLange - Do 12.04.07 15:43

hmm.. also es ist ja nicht so, dass das gaaaanz neue Sachen sind von mir, sondern es war eine Eigenentwicklung die ich mal vor Jahren gemacht habe, damals noch unter Win98/Win2000. Jetzt hab ich das ganze mehr oder weniger aufgebohrt, um es anderen Leuten zugänglich zu machen, heisst :

+ einige Sachen in Komponenten verwandelt (waren TObjects vorher, weil man sie nur 1 x benutzte im ganzen System und sich eine Komponente nicht lohnte)
+ habe properties für Sachen hinzugefügt, die ich als feste Grösse in meinem System hatte und deswegen nicht an Komponenten brauchte
+ habe Objecte zerstückelt und getrennt, so dass der Anwender nachher entscheiden kann, welche benutzt werden
+ habe ein paar Neu-Entwicklungen gemacht, die sich für mich nicht lohnten, aber wenn die Komponenten auch von anderen benutzt werden sollen, es sehr wohl Sinn macht

All das ist jetzt unter WindowsXP 64 passiert, wurde aber auch unter WindowsXP getestet (auf Laptop und Zweitrechner).

Vista ist auf dem Weg zu mir, mit Delphi 2007 muss ich mal sehen, hier gibt es das noch nicht. Aber ich denke, es wird eine der ersten Anschaffungen sein, die von dem verdienten Geld gemacht werden :)
Die Komponenten selbst sollten ab Delphi 5 funktionieren, muss mal in der Kiste kramen und Delphi 5 irgendwo installieren zum testen, aber sie wurden zum grossen Teil unter Delphi 7 entwickelt und erst vor 2-3 Monaten bin ich komplett auf BDS2006 umgestiegen. Da ist zwar einiges an Sprachfeatures hinzugekommen, das hab ich aber in den Komponenten nicht genutzt (ausser {$REGION}, aber das fliegt wieder, ist nicht abwärtskompatibel).

Memory leaks hab ich schon seit Jahren mit MemProof gesucht, jetzt dessen Nachfolger QATime, welches auch für BDS geht. Und gegen nicht-freigegebene Objekte/Pointer steht auch meine sehr lange Erfahrung mit solchen Sachen, da ich sehr viel an Speicher dynamisch anfordere und freigebe, dabei aber in den Tests immer gute Ergebnisse erziel (also keine Leaks etc), was wohl daran liegt, dass ich nach der Zeile, wo das Object/der Speicher erstellt wird ich schon die Freigabe schreibe und dann erst dazwischen, was passieren soll. Bzw. bei Listen schreibe ich nach der record-Deklaration als erstes die Freigabe-Routine und setz sie ins TObject.Destroy, auch wenn eigentlich noch keine Items in der Liste sein können. Ich habe allerdings für mich festegestellt, dass nach dieser Methode ich keine leaks produziere.


Was mich interessieren würde sind ein paar Meinungen zur Demo selbst. Ich weiss, sieht ein bissl nach nichts aus bzw. unspektakulär von aussen. Aber es sind ja zum grossen Teil non-visual-components und da geht es ja dadrum, was unter der Haube ist. Dazu muss man sich allerdings auch den source mal etwas betrachten, der in oft fast nichts beinhaltet, weil die Komponente alles selbst macht und nur Steuerungs code beinhaltet oder das memo-update.


HelgeLange - Fr 13.04.07 05:44

Hab gestern noch ein wenig mit Christian gequatscht und habe für alle, die am Demo Source interessiert sind (haben sich ja hier erst 2 Leute gesaugt bisher :( ), es gibt jetzt Designtime packages für Delphi 6/7 und BDS2005/2006, man kann die Komponenten nun also in seiner IDE installieren, schauen, was im Demo so an Einstellungen gemacht wurden und auch die Property-Editoren ausprobieren.
Die einzige Einschränkung : man kann keine Programme mit ihnen übersetzen, da halt die DCU's fehlen. Aber zum schnuppern im Demo reicht es ja.

Viel Spass damit...


HelgeLange - Fr 13.04.07 05:45

und noch die BPLs für BDS2006 sowie die neue Demo und der neue Source (beide machen das gleiche, wie vorher, nutzen eben nur ERP_Base2006.bpl und ERP_Visual2006.bpl


alias5000 - Do 19.04.07 22:18

Hm, ich hab ein Problem beim Debuggen der Demo.
Wenn ich die BPLs in mein 2006er installieren will, kann ich 3 von denen installieren, aber bei der ERP_BaseDesign.bpl kommt die Fehlermeldung, dass er die ERP_Base.bpl nicht finden kann (die ja auch nicht existiert, sondern nur eine ERP_Base2006.bpl)

Gruß
alias5000


HelgeLange - Do 19.04.07 22:21

Nimm Dir einafch mal die shareware von meiner website, da sind alle korrekt drin. Falls Du BDS 2005/2006 benutzt, dann ist da auch ein neueres Demo, mit projekt-files direkt für die jeweilige Version


HelgeLange - Sa 21.04.07 19:24

Ich habe die techDemo und auch die trial version auf der der Webseite [url]http://www.erp-components.com[/url] geupdated. Beide tragen nun die Versionsnummer 1.1

Neu hinzegekommen sind 2 Komponenten, einfach anschauen und überrascht sein :)


HelgeLange - Mo 23.04.07 14:11

ok, endlich wurde bei ShareIt.com (fast) alles freigeschaltet und nun können die Komponenten dort bezogen werden. Direkte Links gibt es unter http://www.erp-components.com/index.php?option=com_content&task=view&id=13&Itemid=30.

Für DF user (auch wenn sie nicht an der Diskussion teilgenommen haben, so schade es ist), biete ich folgende Rabatte an :

single developer license : 25 Euro
3 developer license : 75 Euro
unlimited developer license : 150 Euro

Das ganze gilt für DF-User, welche bis zum heutigen Tag angemeldet sind und mir eine PM schicken (das ganze geht über Coupons, deswegen personalisiert). Pro User kann für einen der Lizenz-Typen ein Coupon ausgegeben werden, für jeden Typ ist es auf maximal 10 coupons limitiert und die Aktion geht bis zum 23.5.2007.
Die Preisrabatte addieren sich mit der Early-Bird-Aktion, so dass die single user license mit vollem source code dem DF user für 174 Euro zur Verfügung gestellt wird.

Ich hoffe, Euch gefällt diese spezielle DF Angebot zum Start des Verkaufs der ERP Framework Components.

LG aus Caracas,
Helge Lange


alias5000 - Mo 23.04.07 15:15

Hi!
Folgende zwei Sachen sind mir noch aufgefallen:
Der Link zu ShareIt auf deiner Seite (die Grafik) ist defekt.

Und wenn ich auf ShareIt nach ERP suche, kommen deine Komponenten nicht.

Gruß
alias5000


HelgeLange - Mo 23.04.07 15:19

Grafik ist gefixed, danke für den Tipp.
Das andere ist eine ShareIt-Sache, denke mal, ihre DB ist noch nicht aktualisiert, so dass die Komponenten in einer Suche nicht gefunden werden können. Aber die einzelnen Lizenztypen haben ja direkte links zum jeweiligen Produkt und diese funktionieren.

Grüsse :)


HelgeLange - Sa 12.05.07 00:46

Habe heute endlich ein Tutorial zur TechDemo geschrieben, wo neuer Code und ein neues Form eingefügt wird und dabei Schritt für Schritt erklärt, was dafür getan werden muss. Ich hoffe, es hilft Euch, besser zu verstehen, wie man die Komponenten einsetzen kann. Alles, was man dazu braucht ist die trial version und die TechDemo, beides von der homepage http://www.erp-components.com zu beziehen :)

Viel Spass

PS.: Denkt dran, dass die Coupon-Aktion für DF-User nur noch bis zum 23.5.2007 läuft, also nicht ganz 2 Wochen...


alias5000 - Sa 12.05.07 19:57

Also, wie du weißt, brüte ich jetzt schon länger (dafür aber sehr gelegentlich ;) )daran, ein eigenes Testprojekt zum Laufen zu bekommen.
Ich krieg es partout aber nicht hin, einen simplen Hook "ausführen" zu lassen.
Im Anhang ist das noch wirklich kleine Projekt. Die Router-Library hab ich aus der TechDemo kopiert. Mein Problem bei der ganzen Sache ist im Moment, dass ich es nicht hinbekomme, dem Router den SubHook 10002 aus dem Module1.dll bekannt zu machen (zumindest führt der HookClient in der Hauptanwendung nichts aus).
Wenn ich im Router (HookManager) versuche, das Modul im DFT- Experten einzutragen, klappt das auch solange, wie das Fenster offen ist (nur die ganzen Informationen, alla ModuleID, Autor,... werden nicht angezeigt!). Schließe ich das ganze und öffne es dann wieder, wird aus dem Module1.dll ein 1Module1.dll und alle eingetragenen Hooks, subhooks sind weg.
Öffne ich dann das Projekt neu, dann bringt er mir beim Öffnen des DFT Editors ne Meldung, dass er einen ungültigen SubHook aus der Liste gelöscht hat (iss ja auch klar, 1Module1.dll gibts ja nicht).
Wie bekomme ich jetzt das so hin, dass der SubHook 10002 auf den Hook 1001 ausgeführt wird, wenn ich in der Anwendung den Hook 1001 ausführen lasse?

Und zweite Sache: Welche Mthoden gibt es, um im Framework bekannt zu machen, welche Hooks ein Modul "benutzt" oder zur Verfügung stellt? Muss ich das im HAC-Editor einstellen?

Gruß
alias5000

P.S.: Irgendwie stürtzt mir ständig die Delphi IDE ab, nachdem der Router sich mit der 1Module1.dll überschlagen hat. Bin mir aber nicht sicher, ob das nur dann war :gruebel:

@Team: Wie ist das in der Sparte hier eigentlich? Kann ich in den Beiträgen sowas fragen, oder wie würde sowas gehandhabt werden?


HelgeLange - So 13.05.07 16:03

Ok, folgende Fehler :

1. Projekte sollten mit der Option "dynamische Laufzeit-Bibliotheken verwenden" erstellt werden, dabei RTL, VCL, ERP_Base und ERP_Visuals angeben. Das erspart den ärger mit SpeicherManagern, dem Problem mit eigenen TApplication-Objekten in jedem Modul und macht die Module um einige hundert KB kleiner.

2. Wenn in der HookManager-Komponente der Pfad zu den Modulen angegeben wird, dann immer mit backslash hinten. Da dies eine Komponente ist, die man im ganzen Projekt nur einmal benutzt, muss sie nicht unbedingt sowas checken und selbst anfügen.

3. SaveDFT war auf False, deswegen war auch kein DFT zu laden. (InstallAPI-Komponente, die das dynamisch macht, gibt es ja nicht in der Trial). Und wenn Kein DFT da ist, kann auch nichts ausgeführt werden ;)

4. Das Form im Modul1.dll (Form2), welches als Holder Für den HAC genommen wurde, wurde nur geschlossen, aber nicht freigegeben. Ein Close reicht da nicht aus, gibt Schutzverletzung beim Schliessen des Programms.

5. In der ManagerBase-Komponente im Hauptprogramm muss ein ModuleSubDirectory angegeben werden (in dem Fall "Modules").

6. Da der HookManager den ManagerBaseContainer nicht kennt und zur Designzeit eh nicht drauf zugreifen kann, sollten alle Module in dem Pfad liegen, der im HookManager angegeben ist.


Als Anhang hast du den geänderten Code zum Vergleich. Viel Spass damit :)


HelgeLange - Di 22.05.07 22:52

Dank BenBE hier und einem sehr netten Gespräch (unter vielen) im TS, hier nun ein nettes Ergebnis für die Community (Alias5000 : weisst ja schon, was ich meine :D)

ERP Framework Components will be available as Freeware für nicht-kommerzielle Nutzung.
Das heisst, wenn ihr ein Freeware-Programm schreibt, dürft ihr die Komponenten frei benutzen und weitergeben, keine NagScreens, nichts. Code bekommt ihr von den meisten Komponenten auch dazu, nur einige Core-Komponenten bleiben als dcu, ich will ja nicht die ganze Magie verraten :D
Einzige Auflage für Freeware-Programme : Es sollte schon meine Webseite und die Komponenten genannt werden. Aber das ist ja normal....

Für kommerzielle Nutzung muss weiterhion bezahlt werden, aber wer so mit seinem Programm schneller Geld machen kann (bzw. überhaupt machen kann), sollte auch an die was abgeben, die daran beteiligt waren :)

Ein Paket mit den Komponenten wird dieser Tage auf der bekannten Webseite (siehe mein Profil) zum Download angeboten werden...

Ausserdem wird dann wohl ein neuer Thread in der Sparte Freeware eröffnet für Fragen und updates...


alias5000 - Di 22.05.07 23:00

user profile iconHelgeLange hat folgendes geschrieben:
(Alias5000 : weisst ja schon, was ich meine :D)

Jap :D
Finds cool, danke ;)


Robert.Wachtel - So 01.07.07 00:12

Existiert das Projekt noch? Auf der Website sind keine Informationen abrufbar...


alias5000 - So 01.07.07 22:30

Das kann mit den Problemen in Venezuela zusammenhängen, ich weiß es nicht. Hab schon länger nicht mehr mit ihm geredet...


HelgeLange - Mo 02.07.07 14:18

jojo, gibt es noch, gan nur Probleme mit ISP und Datenbanken, soillte morgen spätestens wieder gehen...


HelgeLange - Sa 13.06.09 19:49

Das Projekt lebt immer noch, auch wennd er Webserver mal wieder nicht geht :) Der steht in Berlin in der Wohung der Ex-Freundin meines besten Freundes und ist abgeraucht. Der Freund wohnt aber mittlerweile in München und muss nun erstmal wieder nach Berlin tuckern und dort die Daten holen und einen neuen Server in München aufsetzen. Wie das Leben halt manchmal so spielt. :D

Mittlerweile auch ein gutes Stück gewachsen, viele neue leckere Möglichkeiten. Wenn ich mit den aktuellen Änderungen fertig bin und auch mein Datenbank-Demo gebaut habe, dann setz ich hier wieder was neues rein :)


HelgeLange - Mo 20.07.09 22:23

Der Server ist wieder online seid 1-2 Wochen und ich möchte doch gleichmal die Chance nutzen, ein kleines Update zu schreiben (obwohl ich doch ab und an in das Blog dort schreibe :)).

Neben den üblichen Wartungsarbeiten und Verbesserungen am Gesamtpaket bin ich gerade an einer grösseren Änderung, welche 2 Komponenten ersetzen wird und als Kontroll-Komponente eines Moduls dienen wird.

Problembeschreibung :

In den beiden vorhergehenden Komponenten dazu hatte ich eine offene Datenstruktur, die man erweitern konnte innerhalb der Komponente oder auch innerhalb des Moduls und dann dynamisch bei Laden des Moduls hinzufügen. Allerdings stand ich vor nciht allzulanger Zeit vor dem Problem, einen neuen Daten-Typen hinzufügen zu müssen. Hab ca. 30 Minuten gebraucht, nicht zulang, aber ich fand es im Nachhinein doch zu umständlich.

Lösungsansatz :

Mir kam nach etwas nachdenken dann die Idee, eine komplett dynamische Struktur zu basteln, die man in einem Komponenten-Editor selbst zusammenbasteln kann und die man dann als Delphi-Record geliefert bekommt. Klar, nicht alle Datentypen machen dort Sinn oder sind gar möglich (zum Bsp. Objekte, die der Komponenten-Editor nicht kennen kann). Allerdings für die Aufgaben, die ich für die Komponente zur Zeit sehe, reichten die vorhandenen Datentypen vollkommen aus.

Hier die Definition von Records im Editor...
user defined image

Und hier die Benutzung im Editor :
user defined image

Was dabei rauskommt ist ein Record, welches auf der Empfänger-Seite als Delphi-Record angesprochen werden kann, im markierten Fall würde die Client-Seite (der Aufrufer) ein Record bekommen, welches man in Delphi so defniert :


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
RMyRecord = packed record
  NameID   : Integer;
  ImageID  : Integer;
  ParentID : Integer;
end;
PMyRecord = ^RMyRecord;


Damit man weiss, was ich mir mit den Daten gedacht habe... Ich benutze als eines der GUI Elemente eine Outlook style bar, welche in Gruppen zusammengefasst Icons (mit Beschriftung) für verschiedene Funktionen besitzt. Klickt man auf ein Icon, wird die entsprechende Funktion aufgerufen (im Normalfall wäre das ein Fenster aus einem der Module anzeigen). Im Record benutze ich also NameID für die Beschriftung des Icons (ist eine Nummer, weil die den String identifiziert, der geladen werden muss aus der aktuellen Sprach-Datei), ImageID is die ID des Icons (wird über diese beim Resourcen-Manager angefordert, der ein Bild zurückliefert) und ParentID ist wieder die ID eines Strings, welcher die Gruppe angibt. Besteht die Gruppe noch nicht, wird sie erstellt, ansonsten nur das Icon in die Gruppe eingefügt.

Das heisst im Endeffekt, dass diese Funktion nur ein Teil einer Enumerations-Funktion ist, die aus allen Modulen die Daten zusammensammelt, um die Outlookbar zu füllen. Ein Teil eines Automatisierungsprozesses, sozusagen. Man schreibt ein Modul, welches sich gern irgendwo reinhängen will und muss nicht im Modul per Hand Code schreiben, um solche Sachen zu machen wie diese oder ein Fenster zu erstellen etc. Und man weiss, dass es sorum richtig ankommt, solange man die Daten selbst richtig eingibt ;)

Will ich das ganze nun nicht in einer Outlookbar, sondern im MainMenu unterbringen, kann ich mir ein anderes Datenrecord basteln, welches mir alle Daten zur Verfügung stellt, um ein MainMenu zu füllen, also auch mit SubMenus in SubMenus in SubMenus.

Das interessante dabei war für mich die dynamische Erstellung von Delphi Records (eine nette Speicher-Spielerei !!!), so dass ich keine varianten Datentypen nehmen muss und auch die Daten im DFM einer Form oder eines DataModules gespeichert werden konnten.

Ich hoffe der Beitrag war mal wieder interessant für einige...

Helge


HelgeLange - Mi 04.11.09 20:34

ERP Framework Components ist tot... :(

Es lebe Modular Application Framework Components :)

Nach anfänglicher Kritik am Namen hier und auch anderswo habe ich mich entschieden, das Gesamtpaket umzubenennen.
Was dahinter steht, kann sich jeder denken :

1.) Refactoring aller Klassen, weg vom TERPXXXX name style zum TmafXXXX. das gleiche gilt für units, die jetzt alle uMAF_XXXX.pas heissen
2.) anpassen bestehender Projekte durch Änderung der DFM files per Hand, um binäre Datenstreams nicht zu verlieren
3.) Neue domain, weg von [url]http://www.erp-components.com[/url] zu http://www.maf-components.com (Danke an user profile iconBenBE für seine Hilfe und Ausdauer, um von Strato auf seinen Server umzuziehen .... schönes Angebot von ihm btw... falls jemand eine Webseite hosten will, user profile iconBenBE ist Euer Mann!
4.) Einträge bei ShareIt.com updaten, Texte umschreiben dort und auf der eigenen Webseite.

Und da waren sicherlich noch hier und da andere kleine Arbeiten zu machen. Also eine Menge Arbeit, kein Wunder, dass ich es bisher gescheut hatte.
Aber für die neue version 2.0, die endlich (!!!) fertig ist, wollte ich es richtig machen. Die Komponenten sind erwachsener, warum auch nicht Name, Webseite ud Angebot. :)

Was ist neu :



Es gibt sicherlich noch eine Million anderer Verbesseungen, die mir grad nicht einfallen, aber naja..
Auf der Webseite gibt es mittlerweile 6 Tutorials, die Schritt für Schritt erklären, wie bestimmte Aufgaben gelöst werden können.

Wie schon vorher mal gesagt, MAF Components sind für den privaten und nicht-kommerziellen Einsatz kostenlos ohne Beschränkungen innerhalb der Komponenten, dazu kann man bei mir eine private Lizenz anfordern.

Für den kommerziellen Einsatz gibt es Standard und Professional Pakete, erstere als DCU/BPL files, letztere kommt natürlich wie immer mit vollem Source code.


Heiko - So 08.11.09 02:27

Nur einmal eine kurze Frage: wie erfolgreich ist das Projekt? Also wie gut wird es angenommen? Denn inzwischen sind ja schon mehr als 2 1/2 Jahre vergangen seit dem du es hier zum ersten Mal meldeste ;)


HelgeLange - So 08.11.09 02:59

Ein paar Lizenzen habe ich verkauft, auch jetzt mit der neuen Version schon 2, aber es könnte ruhig mehr sein.
Wenn ich jetzt selbst zurückblicke auf die 1.0 version, dann könnte ich mich natürlich schon fast schämen, das als kommmerzielles Produkt angeboten zu haben, aber wie es immer ist beim Programmieren : Man entwickelt sich persönlich ständig weiter und lernt neue Sachen und neue Wege, bestimmte Sachen zu programmieren. Und eine Version 1.0 ist weder vertrauenserweckend (noch zuviele potentielle Fehlerquellen) noch annähernd ausgereift (man hat grösstenteils seine eigenen Vorstellungen drin, nicht wie der Nutzer später es wirklich braucht und will).

In den 2 1/2 Jahren habe ich ein wenig mehr Gehirnschmalz investiert, auf Kritik zur Version 1 gehört und das ganze Paket etwas abgerundeter und logischer gemacht, sowie stark vereinfacht in der Benutzung. Allerdings eben nichts gross an die Glocke gehängt mit Veröffentlichungen, da ich mich im Leben auf andere Sachen konzentrieren wollte (Heirat, Kind geboren etc) und viel freelance Aufträge hier im Land gemacht, um meine Kontakte auszubauen.

Ich denke, mit der neuen Version kann sich etwas mehr Erfolg einstellen, da es eben viel besser ist, eine bessere und umfangreichere Demo hat und die Webseite stark aufpoliert wurde. Nur am Marketing muss ich noch arbeiten :)

Insgesamt habe ich allerdings das Gefühl im netz, als wäre Delphi ein wenig im Rückzug, ohne Turbos etc ist es schwer, neue Programmierer dafür zu begeistern.


Heiko - So 08.11.09 03:22

user profile iconHelgeLange hat folgendes geschrieben Zum zitierten Posting springen:
Ein paar Lizenzen habe ich verkauft, auch jetzt mit der neuen Version schon 2, aber es könnte ruhig mehr sein.

Unter der Annahme das dein letzter Post hier am Erscheinungstag von v2 erschien, geht das ergebnis doch schon für ein nebenläufiges Projekt ;).


user profile iconHelgeLange hat folgendes geschrieben Zum zitierten Posting springen:
Wenn ich jetzt selbst zurückblicke auf die 1.0 version, dann könnte ich mich natürlich schon fast schämen, das als kommmerzielles Produkt angeboten zu haben, aber wie es immer ist beim Programmieren : Man entwickelt sich persönlich ständig weiter und lernt neue Sachen und neue Wege, bestimmte Sachen zu programmieren.

Ich duck mich da lieber :lol: Ich habe vor 3 Jahren mit einem PHP-Templatesystem angefangen - und irgendwie werde ich damit nicht fertig (inzwischen läuft es aber mal wieder und größere Änderungen sind nimmer geplant). Ist aber schon lustig wenn man etwas Hobbymäßig macht. Man programmiert bissl dran rum, irgendwann merkt man: ey, so würde es besser gehen :arrow: man fängt neu an. Die Anzahl der Generationen habe ich bei mir jetzt nicht gezählt (2 stellig dürfte die inzwischen sein :mrgreen: ). Auf jeden Fall wird es dir mit v2 bei v3 bzw v4 auch so gehen ;).

user profile iconHelgeLange hat folgendes geschrieben Zum zitierten Posting springen:
Insgesamt habe ich allerdings das Gefühl im netz, als wäre Delphi ein wenig im Rückzug, ohne Turbos etc ist es schwer, neue Programmierer dafür zu begeistern.

Ja zum einem wegen dem fehlen neuerer kostenloser Versionen (das Erscheinen einer neuen kostenlosen IDE, die sonst kommerziell ist, geht doch oftmals über diverse Newsseiten, und somit ist es Werbung) und zum anderem hat Borland eine Menge vermasselt. Zum einem der extrem späte Start von nativer Unicodeunterstützung und zum anderem wegen kleineren Sprachfeatures die in nahezu allen anderen Sprachen üblich sind, nur Delphi halt nicht (+= & Co). Gibt es eigentlich inzwischen Namespaces? Ich glaube nicht, oder? Insgesamt müssten die einiges wieder aufholen. Was mir aber an Delphi gefällt, wes wegen ich mich auch nicht ganz von Delphi abwenden will: der sehr schöne Support von Propertys. Unter Java, PHP & Co habe ich soetwas noch nicht gefunden :(
Aufgrund der langsamen Entwicklung dieser Sprache verliert Delphi auch in Schulen immer mehr Bedeutung. In Schulen wird halt Java Standard *graus*


HelgeLange - So 08.11.09 03:35

Naja, ich müsste mehr posten in verscheidenen Foren :) Werd mich wohl die tage mal im DP Forum verewigen, will aber da erstmal mit dem Moderator reden, der für die Freeware-Sparte zuständig ist, denn es ist ja auch ein kommerzielles Produkt. Allerdings gibt es eine unbeschränkte Freeware version für nicht-kommerzielle Projekte. Von daher könnte es ja passen. :) Aber lieber fragen, dann posten...

Es gibt wie bei jedem "Hobby-"Projekt Hoch und Tiefs. Mal hat man einfach keine Zeit, die ganze Zeit dran zu sitzen und neue Features einzubauen, schliesslich verdioent man damit ja nicht seinen Lebensunterhalt. Ich glaube auch nicht, dass man es kann, da muss man schon 5-10 solcher Projekte am Laufen haben. Klar, eine Lizenz verkaufen ist hier in Vzla ein halber Monatslohn (nach Schwarzmarkt-Kurs).

Rechnet man es mal hoch bei 1.7 Millionen angeblicher Delphi-Programmierer (laut Embarcadero).. wenn nur 100 davon eine Single-User-Lizenz kaufen würden, wäre das ein sehr guter Start (1 user = 200 euro in source-version, macht 20.000 euro). Für 20.000 Euro würd ich es fast schon ganz verkaufen, so dass ich ncihts mehr mit zu tun habe und eine professionelle Software-Schmiede wie TMS die weitere Vermarktung übernimmt. Aber soviel Glück hab ich bestimmt nicht, dass sich eine grosse Firma für interessiert. :(

Wegen der Versionen.. ich habe mal in meinem Blog über die Code-Evolution bei mir geschrieben, kannst aj mal gucken, wenn der Server wieder da ist...

Ich hatte letztens auch einen Link zu einer Umfrage von Embarcadero gepostet, da fragte man auch nach Preismodellen etc., vielleicht führen sie ja sowas wie die Turbos wieder ein :)


HelgeLange - Mo 09.11.09 22:54

Ich habe gerade ein neues Build in der Version 2.0.0.645 in den Download Bereich gelegt, auch Demo und Demo Source sind neu.

Die neue Version benutzt standard-mässig keine PNGComponents mehr, da es erstaunlicherweise zu Problemen kam, wenn man die Demo selbst übersetzen wollte. Offensichtlich ist für Delphi PNGComponents nicht gleich PNGComponents. Will sagen, dass meine unveränderte Version von der Embarcadero Seite ein anderes Kompilat erzeugt als das gleiche Projekt auf einem anderen Rechner. Ob es mit Zeitstempel zu tun hat, weiss ich nicht, aber es kam immer die Fehlermeldung, dass MAF_Base neu übersetzt werden müsse. Sowie ich mein Original-Kompilat der PNGComponents hinkopiert habe (DCU/BPL und DCP), funktionierte es tadellos.


Um weiteren Problemen aus dem Wege zu gehen, habe ich mich entschlossen, die PNG support rauszunehmen für Delphi-Versionen unter Delphi 2009 (ab da gibt es das von Haus aus). Allerdings kann er per Compiler-Switch wieder eingeschaltet werden (Hint für Professional - Lizenz Besitzer) für alle Delphi Versionen.

Neu ist auch der TFrame support beim Auto-Erstellen von Fenstern, bisher hatte ich dem keien Bedeutung zugemessen, aber ein potentieller Kunde fragte direkt danach und ich habe es eingebaut :)

Alle, die die letzte Version sich runtergeladen haben und fluchten, weil sie nichts selbst mit den Komponenten übersetzen konnten : Sorry ? Das war leider auch neu für mich. Nun sollte es gehen und ich hoffe, dass man es einfach nochmal versucht mit der aktuellen Version.

Helge


HelgeLange - Di 17.11.09 21:01

Grad bei einem Gespräch mit FinnO festgestellt, dass zumindest er der Meinung war, dass die Komponenten zu teuer sind, als dass man wirklich Interesse zeigt (für Schüler etc.)

Ich bin mir nicht sicher und will grad auch nicht nachschauen, aber es gibt eine Personal Edition, die keine Einschränkungen hat (also kein Nag, kein Limit für geladene Module etc.) und für nicht-kommerzielle Projekte kostenlos ist. Man kann sie direkt bei mir mir ordern : HelgeLange@maf-components.com
Wenn eine neue Version der Komponenten erscheint, können PE Nutzer natürlich auch davon profitieren, da es eine Rundmail gibt mit der neuen Version.

Eine Einschränkung gibt es generell bei den MAF komponenten : Man kann sie nicht komfortabel bei den Turbos einsetzen, da ich ziemlich oft das dfm file nutze, um Sachen abzuspeichern. Aber ich denke, das spielt bei den Turbos eh nicht so die Rolle, da ist man ja ans Selbst-Erzeugen gewöhnt :)