Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Die Delphi-IDE (https://www.delphipraxis.net/62-die-delphi-ide/)
-   -   MMX für Delphi ist ab sofort kostenlos! (https://www.delphipraxis.net/196416-mmx-fuer-delphi-ist-ab-sofort-kostenlos.html)

Der schöne Günther 19. Mai 2018 07:38

MMX für Delphi ist ab sofort kostenlos!
 
Uwe Raabe:
Zitat:

I am very pleased to announce that as of today I am going to take over the award winning ModelMaker Code Explorer™ from ModeMaker Tools BV.
Quelle: UweRaabe.de/Blog


Für mich die bislang beste Nachricht in Sachen Delphi für 2018. Und sicher auch 2017 und darüber hinaus 8-)

Nicht nur dass dieses großartige Werkzeug endlich in fähigen und fleißigen Händen liegt, es ist ab sofort auch noch kostenlos.


Was MMX genau macht ist schwer in einem Satz zu beschreiben. Ich habe es für die exzellente Klassen-Ansicht lieb gewonnen die um Welten besser ist als das Chaos das die IDE "out of the box" anbietet.
Der Slogan von MMX scheint "speed up your Delphi development" zu sein - Und wie es das tut. Es kann einem grade bei Aufgaben wie "Fügen wir dem Konstruktor schnell noch einen Parameter hinzu" so stark unter die Arme greifen dass man am Ende der Woche viele Minuten, wenn nicht gar eine halbe Stunde oder mehr und mehr gespart haben kann.


Anfangs wird man vielleicht etwas erschlagen von all den Möglichkeiten die man hat. Aber es ist rundum so vielfältig, zuverlässig und nun sogar kostenlos - Jeder sollte sich damit einmal auseinandersetzen. Ich habe es gerade in meine Starter-Edition geschraubt.


https://www.mmx-delphi.de/

EWeiss 19. Mai 2018 08:25

AW: MMX für Delphi ist ab sofort kostenlos!
 
Ich weis nicht was da so toll ist nur weil umsonst muss es nicht gut sein.
Mein erster Test schlug zumindest fehl und ging voll in die Hose.

Habe mein Interface sortieren lassen das Resultat war das meine DLL nicht mehr funktioniert.

Was beim ersten mal schon nicht funktioniert und mir nur wegen dem sortieren einer Unit (Interface) meinen Code
unbrauchbar macht hat bei mir schon verloren.

Zitat:

zuverlässig und nun sogar kostenlos
Dem muss ich widersprechen.

Eins sollte klar sein.
Wenn ich ein Interface sortieren lasse dann sollten alle anderen Interface vom gleichen Typ (Namen\Abhängigkeiten) auch sortiert werden.
Ansonsten welchen sinn macht das ganze.
Anschließend 40 Units durchzublättern und zu prüfen ob diese dann auch die richtige Sortorder enthalten macht nicht wirklich sinn.

gruss

Mavarik 19. Mai 2018 09:37

AW: MMX für Delphi ist ab sofort kostenlos!
 
Zitat:

Zitat von EWeiss (Beitrag 1402498)
Mein erster Test schlug zumindest fehl und ging voll in die Hose.

Bei mir lief es auch nicht rund... in 10.2.3 warten die Guidelines dann an falscher Stelle
und die IDE hat rumgesponnen...

Hab aber nicht lange getestet und wieder deinstalliert.

Ich werde es nochmal versuchen wenn ich mehr Zeit habe und Uwe dann genauer berichten...

Uwe Raabe 19. Mai 2018 10:05

AW: MMX für Delphi ist ab sofort kostenlos!
 
Zitat:

Zitat von Mavarik (Beitrag 1402506)
Ich werde es nochmal versuchen wenn ich mehr Zeit habe und Uwe dann genauer berichten...

Bugreports und Feature Requests bitte an support@mmx-delphi.de mailen.

bytecook 19. Mai 2018 11:41

AW: MMX für Delphi ist ab sofort kostenlos!
 
Hallo Uwe,

das sind tolle Neuigkeiten. Eine schöne Sache eurerseits. Vielen Dank dafür!

BeBored 19. Mai 2018 12:38

AW: MMX für Delphi ist ab sofort kostenlos!
 
Auch von mir vielen Dank dafür. Ich habe es zwar gekauft, aber ich freue mich wenn mehr dieses tolle Tool nutzen.

Harry Stahl 19. Mai 2018 12:45

AW: MMX für Delphi ist ab sofort kostenlos!
 
Hallo Uwe,

erst mal vielen Dank, dass Du hier so ein Projekt in die eigene Verantwortung übernimmst und dann das sogar kostenlos zur Verfügung stellst.:thumb::thumb:

In Deinem Blog-Eintrag dazu hast Du in einer ToDo-Liste dargestellt, was Du da noch ergänzen und verbessern willst.

Zu dem Punkt

"updating the documentation and examples (videos)"

habe ich eine Anregung.

Ich hatte mir das Tool vor längerer Zeit mal kurz angesehen, bin aber letztlich nicht weit gekommen, da die textlichen Erläuterungen und erst recht die Videos nach meinem Dafürhalten nicht sehr hilfreich waren. Ohne Ton und nur mit Sprechblasen, die zu kurz sichtbar waren. Mir ist letztlich nicht wirklich klar geworden, was man von dem Tool erwarten kann und ich glaube, entweder habe ich es gar nicht oder nur kurz installiert.

Hier würde ich mir Videos mit gesprochenem Text wünschen (durchaus auch in englischer Sprache), die den echten Nutzen (Grundfunktionalität) und Mehrwert herausstellen.

freimatz 19. Mai 2018 13:35

AW: MMX für Delphi ist ab sofort kostenlos!
 
Zitat:

MMX für Delphi ist ab sofort kostenlos!
Als ich das las war mein erster Gedanke: Ach du Sch ...

MMX verwende ich seit vielen Jahren und ist für mich unverzichtbar. Insbesonderen die Klassenansicht und die Möglichkeiten Member zu bearbeiten und zu kopieren. Gerne habe ich dafür das wenige Geld gezahlt, es war es wert.

Mich weckt das unangenehme Erinnerungen an Turbopower. Gute nicht ganz billige Bibliotheken für Delphi. Nicht ganz billig aber mit hoher Qualität und gutem Support. Dann auch kostenlos - Weiterentwicklung und Support war dahin.

Es ist schön dass Uwe das weiter macht. Danke!!! :thumb: Aber auch er hat nur 24 Stunden am Tag. Ich hoffe das Beste.

Uwe Raabe 19. Mai 2018 14:07

AW: MMX für Delphi ist ab sofort kostenlos!
 
Zitat:

Zitat von freimatz (Beitrag 1402520)
Aber auch er hat nur 24 Stunden am Tag. Ich hoffe das Beste.

Ehrlich gesagt, bin ich weder bereit, noch in der Lage diese 24 Stunden am Tag in MMX zu investieren. Es wird weiterentwickelt werden und das auch in einem Umfang, der die letzten Jahre übersteigt.

Natürlich war auch eine kommerzielle Weiterentwicklung im Gespräch, aber ich habe ehrlich gesagt keine Lust mich um Vertrieb, Lizenzen und Kopierschutz zu kümmern. Ob die zu erzielenden Einnahmen dann den Aufwand decken würden, muss angesichts der letzten Umsatzzahlen schon bezweifelt werden. Das ist halt das Problem bei Software, die nicht auf einem Subscription-Modell vertrieben wird. Der Markt ist begrenzt und irgendwann gesättigt und von den Updates allein kann man nicht leben. Dann lieber gleich ein freies Produkt und ich weiß im Vorfeld, daß ich da nur meine Freizeit einbringen kann.

Jemand hatte einen Donate-Button vorgeschlagen. Das würde ich sogar in Erwägung ziehen, allerdings würde ich die Donations dann auch direkt einem guten Zweck zukommen lassen. Da wird man sicher schnell was finden. Ich möchte nicht in Versuchung kommen, irgendwann dann doch die Rentabilität zu hinterfragen. Da bin ich für von Anfang an klare Verhältnisse.

Bernhard Geyer 19. Mai 2018 14:47

AW: MMX für Delphi ist ab sofort kostenlos!
 
Ich habe gelesen das es Closed Source bleiben soll.
Ist das deine Entscheidung oder liegt es an Code den Modelmaker verbaut hat und selbst nicht der Urheber ist?
Eine OpenSource-Projekte würde die Möglichkeit bieten das andere dir helfen könnten MMX weiter zu entwickeln.

Der schöne Günther 19. Mai 2018 14:55

AW: MMX für Delphi ist ab sofort kostenlos!
 
Zitat:

Zitat von Nick Hodges
[…]What is the reason that this just didn't become an open source project? "It's none of your business" is a perfectly acceptable answer.

Zitat:

Zitat von Uwe Raabe
All three products from ModelMaker Tools BV share a good portion of common code. Gerrit doesn't want parts of this code to go public. This is just part of the deal.

Quelle: https://plus.google.com/+UweRaabe/posts/1eB1T5WSCi1

MichaelT 19. Mai 2018 16:13

AW: MMX für Delphi ist ab sofort kostenlos!
 
Uwe. Danke dass du dich darum annimmst.

Zitat:

Zitat von Uwe Raabe (Beitrag 1402511)
Zitat:

Zitat von Mavarik (Beitrag 1402506)
Ich werde es nochmal versuchen wenn ich mehr Zeit habe und Uwe dann genauer berichten...

Bugreports und Feature Requests bitte an support@mmx-delphi.de mailen.


Ghostwalker 19. Mai 2018 16:22

AW: MMX für Delphi ist ab sofort kostenlos!
 
Auch von mir Dank an Uwe.

Ich werd mir das bei Gelegenheit mal installieren, da es einiges an Funktionalität bietet (und "nachrüstet") die
bei der Starter fehlen.

Uwe Raabe 19. Mai 2018 22:53

AW: MMX für Delphi ist ab sofort kostenlos!
 
Ich möchte nochmal eindringlich darum bitten, daß ihr wirklich alle Bugs oder sonstigen Probleme (z.B. bei der Installation) an support@mmx-delphi.de sendet. Ich muss mich ja auch noch in weiten Teilen in den Code und das Drumherum einarbeiten und möchte wenn irgend möglich erst alle vorhandenen Bugs beheben, bevor ich groß mit neuen Features einsteige.

Es hilft ja nichts, wenn potentiell neue Nutzer durch dämliche Installationsprobleme abgeschreckt werden, die in der Regel relativ einfach in den Griff zu bekommen sind, wenn man denn nur davon weiß.

stifflersmom 20. Mai 2018 17:52

AW: MMX für Delphi ist ab sofort kostenlos!
 
Moin,

mal 'ne ganz unverschämte Frage: wäre/ist es möglich, diese Tools auch für Delphi 2006 zur Verfügung zu stellen?

Gruß

jaenicke 21. Mai 2018 08:53

AW: MMX für Delphi ist ab sofort kostenlos!
 
Das ist eine echt schöne Sache. Danke Uwe!

Bezüglich Bugs versuche ich mal etwas noch einmal zu reproduzieren... Extract Method hatte bei uns bei Tests verrückt gespielt. Das Refactoring schlug fehl und danach war die Unit komplett kaputt.

Ich hätte auch ein paar kleine Featurewünsche, die das Tool ohne Riesenaufwand noch genialer machen würden.
Da sich in dem Projekt nicht viel getan hatte, hatte ich aber nicht viel Hoffnung diesbezüglich.

Aber erstmal abwarten. Ich nehme an, dass Uwes Ideen in ähnliche Richtungen gehen dürften.

Eine wichtige Frage hätte ich:
Wie sieht es mit dem Structured Difference Viewer aus? Den fand ich auch extrem hilfreich, aber den scheint es nun gar nicht mehr zu geben.

Zitat:

Zitat von EWeiss (Beitrag 1402498)
Habe mein Interface sortieren lassen das Resultat war das meine DLL nicht mehr funktioniert.

Solange das Interface sich in einer gemeinsamen Unit für Hostanwendung und DLL befindet, beide neu kompiliert wurden und man keine harten Casts oder ähnlichen Schmu einsetzt, kann die Sortierung keinen Einfluss auf die Funktionalität haben. Das habe ich sicher schon dutzendfach gemacht.

Zitat:

Zitat von stifflersmom (Beitrag 1402587)
mal 'ne ganz unverschämte Frage: wäre/ist es möglich, diese Tools auch für Delphi 2006 zur Verfügung zu stellen?

Das hat Uwe im Grunde schon in der Ankündigung beantwortet:
Zitat:

I am not going to conceal that this will most likely lead to drop support for older Delphi versions in favor of making maintenance easier.
Und ich finde das auch sinnvoll. Gerade bei einem Projekt, das in der eigenen Freizeit entwickelt wird, wäre es schade, wenn zu viel dieser begrenzten Zeit in die Pflege älterer Versionen fließt.

KodeZwerg 21. Mai 2018 10:16

AW: MMX für Delphi ist ab sofort kostenlos!
 
Der Download bricht bei mir immer so bei 4 mb ab, gibt es dafür eventuell einen Mirror mit Resume funktionalität?

Uwe Raabe 21. Mai 2018 10:37

AW: MMX für Delphi ist ab sofort kostenlos!
 
Zitat:

Zitat von KodeZwerg (Beitrag 1402603)
Der Download bricht bei mir immer so bei 4 mb ab, gibt es dafür eventuell einen Mirror mit Resume funktionalität?

Im Moment jedenfalls nicht.

Uwe Raabe 21. Mai 2018 10:53

AW: MMX für Delphi ist ab sofort kostenlos!
 
Zitat:

Zitat von jaenicke (Beitrag 1402602)
Ich hätte auch ein paar kleine Featurewünsche, die das Tool ohne Riesenaufwand noch genialer machen würden.
Da sich in dem Projekt nicht viel getan hatte, hatte ich aber nicht viel Hoffnung diesbezüglich.

Aber erstmal abwarten. Ich nehme an, dass Uwes Ideen in ähnliche Richtungen gehen dürften.

Ich würde dich dennoch bitten, deine Featurewünsche an support@mmx-delphi.de zu schicken. Dann kann ich besser planen.

Zitat:

Zitat von jaenicke (Beitrag 1402602)
Wie sieht es mit dem Structured Difference Viewer aus? Den fand ich auch extrem hilfreich, aber den scheint es nun gar nicht mehr zu geben.

Sagen wir mal so: Er ist aktuell im Hibernation-Mode. Wenn es meine Zeit erlaubt, werde ich ihn vielleicht reaktivieren und eventuell auch erweitern. Die Zielgruppe ist allerdings im Moment arg begrenzt.

MichaelT 21. Mai 2018 12:13

AW: MMX für Delphi ist ab sofort kostenlos!
 
Ich verwende den SD auch noch, aber nurmehr fallweise. Die File Difference tut es am Ende auch und die ist zumeist im Source Code repository eingebaut. Du brauchst auf jeden Fall eine Zugriff auf die Source Code Repositories. Ohne dem geht seit 15 Jahre sicher nichts mehr, eigentlich gut 20.

---

TextDiff von Agnus Johnson ist auch ganz gut und mit Code.

---

Gerade auch bei kommerziellen Projekten ist die Pflege älterer Versionen nicht sonderlich hilfreich.

Die Delphi Community ist kein Sonderfall. Lasse Jahre ins Land ziehen und du bekommst auf keinen Eck mehr nur irgendeine Hinwendung zu neuen Sachen.

Bei der Investition in die Vergangenheit entsteht nichts was morgen spannend ist. Dem gegenüber steht eine andere Kraft. Nämlich dass du in der Vergangenheit nicht falsch gelegen sein kannst.

---

Zu den den Entwicklungen an sich. Die 'Büros' haben so lange die Infrastrukturkosten beweint bis sie eine Lösung bekamen. Android und Tablet. Die IT war bis zum Athlon 800 relativ ergebnisoffen. Dann war schon relativ klar, dass Großinvestoren angreifen. Ein Problem haben die behoben. Laufende Software heißt heute App.

Du brauchst mit der Cloud die IT Organisation nicht mehr kennen. Außerdem werden Ressourcen in ein Technologieeck gezogen. Die meisten da wuchsen in der Welt des Client Server und CAT 5 Kabeln auf. Consumer. Die Frage ob Engineering Kapazitäten in das Eck laufen auf Dauer ist mehr als fraglich, das passiert heute schon nicht mehr. Du hattest ja schon immer die geile Hardware im Serverraum.

Was heute auf einem PC läuft hat mit CMM 0 bis 1 der 80er oder frühen 90er nichts mehr zu tun. ISO 9001 ist so ca. 3 und dahinter 15504. (auf mitteleuropäische Industrie übersetzt). Das Modell hat sich nicht durchgesetzt aber die Entwicklung schreitet voran in Richtung Optimizing. Die Verantwortung für den Betrieb geht schon lange in Richtung Hersteller. Woher glaubst kommt der 'ganze Schwachsinn' zu Delphi hinzuinstalliert hat.

Die Delphi IDE selbst war schon in der Lage dich gegen 3 zu hieven. .net und Java sind schon die Basis für 4 (Beseitigung der Qualitätsschwankungen (im Prozess)). Das geht auf Basis von CS nicht, resp. ist der Glaube daran nicht recht ausgeprägt und das schon seit den 90ern. Y2k war im großen Bild nur ein Wake Up Call.

Embarcadero in 10 Jahren wird ein Rechenzentrum in der Wüsten von Texas sein und wir hängen dann herum wie im Terminator. The 64-Bit Desert Monkeys (Mobile Division).

---

Was der Uwe macht ist vorbildlich. Der unterzieht dem MMX einem Reinigungsprozess mit folgender Politur. Die Leute wollten einfach die letzten 20 Jahre Putzmittel (starke Putzmittel). Aus meiner Sicht splitten sich Delphi Komponenten in Reiniger und Putzmittel auf. Devexpress vs. TMS.

In dem Sinne ist Delphi in Summe eher der starker Allzweckreiniger.

Zitat:

Zitat von jaenicke (Beitrag 1402602)

Eine wichtige Frage hätte ich:
Wie sieht es mit dem Structured Difference Viewer aus? Den fand ich auch extrem hilfreich, aber den scheint es nun gar nicht mehr zu geben.

Und ich finde das auch sinnvoll. Gerade bei einem Projekt, das in der eigenen Freizeit entwickelt wird, wäre es schade, wenn zu viel dieser begrenzten Zeit in die Pflege älterer Versionen fließt.


jaenicke 21. Mai 2018 16:24

AW: MMX für Delphi ist ab sofort kostenlos!
 
Zitat:

Zitat von Uwe Raabe (Beitrag 1402609)
Ich würde dich dennoch bitten, deine Featurewünsche an support@mmx-delphi.de zu schicken. Dann kann ich besser planen.

Das mache ich. Ich schreibe mal alles zusammen.

Eine der Ideen, die allerdings umfangreicher ist, war die Integration der Differenzansicht in die Ansicht im MMX. Aber das schreibe ich dann genauer.

Zitat:

Zitat von Uwe Raabe (Beitrag 1402609)
Sagen wir mal so: Er ist aktuell im Hibernation-Mode. Wenn es meine Zeit erlaubt, werde ich ihn vielleicht reaktivieren und eventuell auch erweitern. Die Zielgruppe ist allerdings im Moment arg begrenzt.

Schön wäre aber, wenn er in der aktuellen Fassung weiter zur Verfügung stünde. Und die Zielgruppe wäre nicht so klein, wenn ein paar Änderungen kämen denke ich.

EWeiss 21. Mai 2018 21:42

AW: MMX für Delphi ist ab sofort kostenlos!
 
Zitat:

Solange das Interface sich in einer gemeinsamen Unit für Hostanwendung und DLL befindet, beide neu kompiliert wurden und man keine harten Casts oder ähnlichen Schmu einsetzt, kann die Sortierung keinen Einfluss auf die Funktionalität haben. Das habe ich sicher schon dutzendfach gemacht.
Klar kann sie das.
Ich habe jetzt extra für dich nochmal einen Test gemacht.

Mein öffentliches Interface sortiert.. (unit SKAeroAPI;) in der Anwendung
Delphi-Quellcode:
ISkinPopUpMenu = interface
  ['{712A92E4-6D43-45DC-9A85-77DDF5EB19B5}']
    function AppendMenu(WinHandle: HWND; uFlags, DlgItemID: UINT; Text: PWideChar): BOOL;
    function CreatePopupMenu(ParentHandle: HWND): HWND;
    procedure CreatePrivateFont(PrivateFontPath: PWideChar; var FontName: string);
    procedure DestroyWindow;
    function GetFontSize: Integer;
    function GetGlassOpacity: Integer;
    function GetHandle: hWnd;
    function GetHeight: Integer;
    function GetIconArrowPath: WideString;
    function GetImageStateMax: Integer;
    function GetItemEnabled: BOOL;
    function GetItemHeight: Integer;
    function GetItemHiliteColor: COLORREF;
    function GetItemIconPath: WideString;
    function GetItemLeft: Integer;
    function GetItemShadow: Integer;
    function GetItemTextAlligment: TTextAlligment;
    function GetItemTextLeft: Integer;
    function GetItemToolTip: PWideChar;
    function GetItemTop: Integer;
    function GetItemWidth: Integer;
    function GetLeft: Integer;
    function GetSelectedImgPath: WideString;
    function GetSeperatorImgPath: WideString;
    function GetSideBarCaption: WideString;
    function GetSideBarCaptionLeft: Integer;
    function GetSideBarCaptionTop: Integer;
    function GetSideBarImgPath: WideString;
    function GetSkinConfigFile: PWideChar;
    function GetSubMenuHandle: HWND;
    function GetSubMenuItemCount: Integer;
    procedure GetTextWidth(Text: WideString; var bW, bH: integer);
    function GetTop: Integer;
    function GetUseSideBar: BOOL;
    function GetUseVistaBlur: BOOL;
    function GetUseVistaCrystal: BOOL;
    function GetWidth: Integer;
    procedure SetFontSize(const Value: Integer);
    procedure SetGlassOpacity(const Value: Integer);
    procedure SetHeight(const Height: Integer);
    procedure SetIconArrowPath(const Value: WideString);
    procedure SetImageStateMax(const Value: Integer);
    procedure SetItemEnabled(const Value: BOOL);
    procedure SetItemHeight(const Value: Integer);
    procedure SetItemHiliteColor(const Value: COLORREF);
    procedure SetItemIconPath(const Value: WideString);
    procedure SetItemLeft(const Value: Integer);
    procedure SetItemShadow(const Value: Integer);
    procedure SetItemTextAlligment(const Value: TTextAlligment);
    procedure SetItemTextLeft(const Value: Integer);
    procedure SetItemToolTip(const Value: PWideChar);
    procedure SetItemTop(const Value: Integer);
    procedure SetItemWidth(const Value: Integer);
    procedure SetLeft(const Value: Integer);
    procedure SetSelectedImgPath(const Value: WideString);
    procedure SetSeperatorImgPath(const Value: WideString);
    procedure SetSideBarCaption(const Value: WideString);
    procedure SetSideBarCaptionLeft(const Value: Integer);
    procedure SetSideBarCaptionTop(const Value: Integer);
    procedure SetSideBarImgPath(const Value: WideString);
    procedure SetSkinConfigFile(const Value: PWideChar);
    procedure SetSubMenuItemCount(const Value: Integer);
    procedure SetTop(const Value: Integer);
    procedure SetUseSideBar(const Value: BOOL);
    procedure SetUseVistaBlur(const Value: BOOL);
    procedure SetUseVistaCrystal(const Value: BOOL);
    procedure SetWidth(const Width: Integer);
    function TrackPopupMenu(WinHandle: HWND; Left, Top, Width, Height: Integer): BOOL; stdcall;
    property FontSize: Integer Read GetFontSize write SetFontSize;
    property GlassOpacity: Integer read GetGlassOpacity write SetGlassOpacity;
    property Handle: hWnd read GetHandle;
    property Height: Integer read GetHeight write SetHeight;
    property IconArrowPath: WideString read GetIconArrowPath write SetIconArrowPath;
    property ImageStateMax: Integer read GetImageStateMax write SetImageStateMax;
    property ItemEnabled: BOOL read GetItemEnabled write SetItemEnabled;
    property ItemHeight: Integer read GetItemHeight write SetItemHeight;
    property ItemHiliteColor: COLORREF read GetItemHiliteColor write SetItemHiliteColor;
    property ItemIconPath: WideString read GetItemIconPath write SetItemIconPath;
    property ItemLeft: Integer read GetItemLeft write SetItemLeft;
    property ItemShadow: Integer read GetItemShadow write SetItemShadow;
    property ItemTextAlligment: TTextAlligment read GetItemTextAlligment write SetItemTextAlligment;
    property ItemTextLeft: Integer read GetItemTextLeft write SetItemTextLeft;
    property ItemToolTip: PWideChar read GetItemToolTip write SetItemToolTip;
    property ItemTop: Integer read GetItemTop write SetItemTop;
    property ItemWidth: Integer read GetItemWidth write SetItemWidth;
    property Left: Integer read GetLeft write SetLeft;
    property SelectedImgPath: WideString read GetSelectedImgPath write SetSelectedImgPath;
    property SeperatorImgPath: WideString read GetSeperatorImgPath write SetSeperatorImgPath;
    property SideBarCaption: WideString Read GetSideBarCaption write SetSideBarCaption;
    property SideBarCaptionLeft: Integer Read GetSideBarCaptionLeft write SetSideBarCaptionLeft;
    property SideBarCaptionTop: Integer Read GetSideBarCaptionTop write SetSideBarCaptionTop;
    property SideBarImgPath: WideString Read GetSideBarImgPath write SetSideBarImgPath;
    property SkinConfigFile: PWideChar Read GetSkinConfigFile write SetSkinConfigFile;
    property SubMenuItemCount: Integer read GetSubMenuItemCount write SetSubMenuItemCount;
    property Top: Integer read GetTop write SetTop;
    property UseSideBar: BOOL read GetUseSideBar write SetUseSideBar;
    property UseVistaBlur: BOOL read GetUseVistaBlur write SetUseVistaBlur;
    property UseVistaCrystal: BOOL read GetUseVistaCrystal write SetUseVistaCrystal;
    property Width: Integer read GetWidth write SetWidth;
end;
Meine Master Interface Unit.. (unit uInterface;) in der DLL unsortiert
Delphi-Quellcode:
ISkinPopUpMenu = interface
  ['{712A92E4-6D43-45DC-9A85-77DDF5EB19B5}']
    function GetHeight: Integer;
    function GetWidth: Integer;
    procedure SetHeight(const Height: Integer);
    procedure SetWidth(const Width: Integer);
    function GetHandle: hWnd;
    function GetSkinConfigFile: PWideChar;
    procedure SetSkinConfigFile(const Value: PWideChar);
    function GetUseVistaBlur: BOOL;
    function GetUseVistaCrystal: BOOL;
    procedure SetUseVistaBlur(const Value: BOOL);
    procedure SetUseVistaCrystal(const Value: BOOL);
    function GetGlassOpacity: Integer;
    procedure SetGlassOpacity(const Value: Integer);
    function GetLeft: Integer;
    function GetTop: Integer;
    procedure SetLeft(const Value: Integer);
    procedure SetTop(const Value: Integer);
    function GetSideBarCaption: WideString;
    function GetSideBarCaptionLeft: Integer;
    function GetSideBarCaptionTop: Integer;
    procedure SetSideBarCaption(const Value: WideString);
    procedure SetSideBarCaptionLeft(const Value: Integer);
    procedure SetSideBarCaptionTop(const Value: Integer);
    function GetFontSize: Integer;
    procedure SetFontSize(const Value: Integer);
    function GetSideBarImgPath: WideString;
    procedure SetSideBarImgPath(const Value: WideString);
    function GetUseSideBar: BOOL;
    procedure SetUseSideBar(const Value: BOOL);
    function GetSelectedImgPath: WideString;
    procedure SetSelectedImgPath(const Value: WideString);
    function GetItemIconPath: WideString;
    procedure SetItemIconPath(const Value: WideString);
    function GetItemHiliteColor: COLORREF;
    procedure SetItemHiliteColor(const Value: COLORREF);
    function GetItemToolTip: PWideChar;
    procedure SetItemToolTip(const Value: PWideChar);
    function GetItemTextAlligment: TTextAlligment;
    procedure SetItemTextAlligment(const Value: TTextAlligment);
    function GetImageStateMax: Integer;
    procedure SetImageStateMax(const Value: Integer);
    function GetItemHeight: Integer;
    procedure SetItemHeight(const Value: Integer);
    function GetItemLeft: Integer;
    function GetItemTop: Integer;
    function GetItemWidth: Integer;
    procedure SetItemLeft(const Value: Integer);
    procedure SetItemTop(const Value: Integer);
    procedure SetItemWidth(const Value: Integer);
    function GetItemShadow: Integer;
    procedure SetItemShadow(const Value: Integer);
    function GetItemTextLeft: Integer;
    procedure SetItemTextLeft(const Value: Integer);
    function GetItemEnabled: BOOL;
    procedure SetItemEnabled(const Value: BOOL);
    function GetIconArrowPath: WideString;
    procedure SetIconArrowPath(const Value: WideString);
    function GetSeperatorImgPath: WideString;
    procedure SetSeperatorImgPath(const Value: WideString);
    function GetSubMenuItemCount: Integer;
    procedure SetSubMenuItemCount(const Value: Integer);
    procedure CreatePrivateFont(PrivateFontPath: PWideChar; var FontName: string);
    procedure GetTextWidth(Text: WideString; var bW, bH: integer);
    function AppendMenu(WinHandle: HWND; uFlags, DlgItemID: UINT; Text: PWideChar): BOOL;
    function GetSubMenuHandle: HWND;
    function TrackPopupMenu(WinHandle: HWND; Left, Top, Width, Height: Integer): BOOL; stdcall;
    property Left: Integer read GetLeft write SetLeft;
    property Top: Integer read GetTop write SetTop;
    property Width: Integer read GetWidth write SetWidth;
    property Height: Integer read GetHeight write SetHeight;
    property Handle: hWnd read GetHandle;
    property GlassOpacity: Integer read GetGlassOpacity write SetGlassOpacity;
    property UseVistaBlur: BOOL read GetUseVistaBlur write SetUseVistaBlur;
    property UseVistaCrystal: BOOL read GetUseVistaCrystal write SetUseVistaCrystal;
    property SkinConfigFile: PWideChar Read GetSkinConfigFile write SetSkinConfigFile;
    property FontSize: Integer Read GetFontSize write SetFontSize;
    property SelectedImgPath: WideString read GetSelectedImgPath write SetSelectedImgPath;
    property SeperatorImgPath: WideString read GetSeperatorImgPath write SetSeperatorImgPath;
    property IconArrowPath: WideString read GetIconArrowPath write SetIconArrowPath;
    property ItemHiliteColor: COLORREF read GetItemHiliteColor write SetItemHiliteColor;
    property ItemToolTip: PWideChar read GetItemToolTip write SetItemToolTip;
    property ItemIconPath: WideString read GetItemIconPath write SetItemIconPath;
    property ItemTextAlligment: TTextAlligment read GetItemTextAlligment write SetItemTextAlligment;
    property ItemHeight: Integer read GetItemHeight write SetItemHeight;
    property ItemWidth: Integer read GetItemWidth write SetItemWidth;
    property ItemLeft: Integer read GetItemLeft write SetItemLeft;
    property ItemTop: Integer read GetItemTop write SetItemTop;
    property ItemShadow: Integer read GetItemShadow write SetItemShadow;
    property ImageStateMax: Integer read GetImageStateMax write SetImageStateMax;
    property ItemTextLeft: Integer read GetItemTextLeft write SetItemTextLeft;
    property ItemEnabled: BOOL read GetItemEnabled write SetItemEnabled;
    property SubMenuItemCount: Integer read GetSubMenuItemCount write SetSubMenuItemCount;
    property UseSideBar: BOOL read GetUseSideBar write SetUseSideBar;
    property SideBarImgPath: WideString Read GetSideBarImgPath write SetSideBarImgPath;
    property SideBarCaption: WideString Read GetSideBarCaption write SetSideBarCaption;
    property SideBarCaptionLeft: Integer Read GetSideBarCaptionLeft write SetSideBarCaptionLeft;
    property SideBarCaptionTop: Integer Read GetSideBarCaptionTop write SetSideBarCaptionTop;
    function CreatePopUpMenu(ParentHandle: HWND): HWND;
    procedure DestroyWindow;
end;
Und die Class des Interface..
Delphi-Quellcode:
  TSkinPopUpMenu = class(TInterfacedObject, ISkinPopUpMenu, ISkinPopUpMenuEx)
  private
    dwTitle: PWideChar;
    dwExStyle: DWORD;
    dwStyle: DWORD;
    wc: TWndClassEx;
    IsInitialized: BOOL;
    FHeight: Integer;
    FWidth: Integer;
    FHPopupWindow: HWND;
    FSkinConfigFile: PWideChar;
    FUseVistaBlur: BOOL;
    FUseVistaCrystal: BOOL;
    FGlassOpacity: Integer;
    FLeft: Integer;
    FTop: Integer;
    FPrivateFont: Pointer;
    FPrivateFontPath: PWideChar;
    FFontName: WideString;
    FSideBarCaption: WideString;
    FSideBarCaptionLeft: Integer;
    FSideBarCaptionTop: Integer;
    FSelectedImgPath: WideString;
    FFontSize: Integer;
    FIcon: array of TIconType;
    FSideBarImgPath: WideString;
    FUseSideBar: BOOL;
    FItemIconPath: WideString;
    FItemHiliteColor: COLORREF;
    FItemToolTip: PWideChar;
    FItemTextAlligment: TTextAlligment;
    FImageStateMax: Integer;
    FItemHeight: Integer;
    FItemWidth: Integer;
    FItemLeft: Integer;
    FItemTop: Integer;
    FItemShadow: Integer;
    FItemTextLeft: Integer;
    FItemEnabled: BOOL;
    FIconArrowPath: WideString;
    FSeperatorImgPath: WideString;
    FSubMenuItemCount: Integer;
    FClientInstance, FPrevClientProc: TFNWndProc;
    FIsSubMenu: BOOL;
    imgW, ImgH: Cardinal;
    ImgSideBar: Cardinal;
    FTrackUser32: Boolean;
    FMouseTracking: BOOL;
    SideBarWidth: Integer;
    ButtonCount: Integer;
    SideBarCount: Integer;
    SubMenuHandleCount: Integer;
    function GetHeight: Integer;
    function GetWidth: Integer;
    procedure SetHeight(const Height: Integer);
    procedure SetWidth(const Width: Integer);
    function GetHandle: HWND;
    function GetSkinConfigFile: PWideChar;
    procedure SetSkinConfigFile(const Value: PWideChar);
    function GetUseVistaBlur: BOOL;
    function GetUseVistaCrystal: BOOL;
    procedure SetUseVistaBlur(const Value: BOOL);
    procedure SetUseVistaCrystal(const Value: BOOL);
    function GetGlassOpacity: Integer;
    procedure SetGlassOpacity(const Value: Integer);
    function GetLeft: Integer;
    function GetTop: Integer;
    procedure SetLeft(const Value: Integer);
    procedure SetTop(const Value: Integer);
    function GetFontName: WideString;
    procedure SetFontName(const Value: WideString);
    function GetSideBarCaption: WideString;
    function GetSideBarCaptionLeft: Integer;
    function GetSideBarCaptionTop: Integer;
    procedure SetSideBarCaption(const Value: WideString);
    procedure SetSideBarCaptionLeft(const Value: Integer);
    procedure SetSideBarCaptionTop(const Value: Integer);
    function GetFontSize: Integer;
    procedure SetFontSize(const Value: Integer);
    procedure ChangeButtonPicture(ButtonCount: Integer; ImageIcon: WideString; HButton: HWND;
      X, Y, W, H: Integer; ArrowIcon: WideString = '');
    function GetHIconFromFile(AFileName: WideString; ASmall: Boolean = false; AIndex: Integer = 0)
      : HIcon;
    function GetSideBarImgPath: WideString;
    procedure SetSideBarImgPath(const Value: WideString);
    function GetUseSideBar: BOOL;
    procedure SetUseSideBar(const Value: BOOL);
    function GetSelectedImgPath: WideString;
    procedure SetSelectedImgPath(const Value: WideString);
    function GetItemIconPath: WideString;
    procedure SetItemIconPath(const Value: WideString);
    function GetItemHiliteColor: COLORREF;
    procedure SetItemHiliteColor(const Value: COLORREF);
    function GetItemToolTip: PWideChar;
    procedure SetItemToolTip(const Value: PWideChar);
    function GetItemTextAlligment: TTextAlligment;
    procedure SetItemTextAlligment(const Value: TTextAlligment);
    function GetImageStateMax: Integer;
    procedure SetImageStateMax(const Value: Integer);
    function GetItemHeight: Integer;
    procedure SetItemHeight(const Value: Integer);
    function GetItemLeft: Integer;
    function GetItemTop: Integer;
    function GetItemWidth: Integer;
    procedure SetItemLeft(const Value: Integer);
    procedure SetItemTop(const Value: Integer);
    procedure SetItemWidth(const Value: Integer);
    function GetItemShadow: Integer;
    procedure SetItemShadow(const Value: Integer);
    function GetItemTextLeft: Integer;
    procedure SetItemTextLeft(const Value: Integer);
    function GetItemEnabled: BOOL;
    procedure SetItemEnabled(const Value: BOOL);
    function GetIconArrowPath: WideString;
    procedure SetIconArrowPath(const Value: WideString);
    function GetSeperatorImgPath: WideString;
    procedure SetSeperatorImgPath(const Value: WideString);
    function FuncExported(stFunc, stModul: PWideChar): Boolean;
    function GetSubMenuItemCount: Integer;
    procedure SetSubMenuItemCount(const Value: Integer);
    function GetIsSubMenu: BOOL;
    procedure SetIsSubMenu(const Value: BOOL);
    procedure ClientWndProc(var Message: TMessage);
    procedure SubClass(WinHandle: HWND);
    procedure UnSubClass(WinHandle: hWnd);
    function GetMouseTracking: BOOL;
    procedure SetMouseTracking(const Value: BOOL);
    function GetPrivateFont: Pointer;
    procedure SetPrivateFont(const Value: Pointer);
    function GetTrackUser32: BOOL;
    procedure SetTrackUser32(const Value: BOOL);
  public
    procedure TrackMouse(WinHandle: HWND);
    procedure CreatePrivateFont(PrivateFontPath: PWideChar; var FontName: string);
    function TrackPopupMenu(WinHandle: HWND; Left, Top, Width, Height: Integer): BOOL; stdcall;
    function AddButton(WinHandle: HWND; DlgItemID: Integer; ImagePath: WideString;
      ItemIconPath: WideString; Text: PWideChar; Left, Top, Width, Height: Integer;
      TextCol: COLORREF; Label3D, ImageStateMax: Integer; TextAlligment: TTextAlligment;
      TextLeft: Integer; ItemToolTip: PWideChar; uFlags: UINT; Enabled: BOOL = True;
      IconArrowPath: WideString = ''): HWND;
    procedure AddSideBar(WinHandle: HWND; DlgItemID: Integer; ImagePath: WideString;
      Left, Top, Width, Height, ImageStateMax: Integer; Enabled, Visible: BOOL);
    procedure GetTextWidth(Text: WideString; var bW: Integer; var bH: Integer);
    function AppendMenu(WinHandle: HWND; uFlags, DlgItemID: UINT; Text: PWideChar): BOOL;
    function GetSubMenuHandle: HWND;
    property Left: Integer read GetLeft write SetLeft;
    property Top: Integer read GetTop write SetTop;
    property Width: Integer read GetWidth write SetWidth;
    property Height: Integer read GetHeight write SetHeight;
    property Handle: HWND read GetHandle;
    property GlassOpacity: Integer read GetGlassOpacity write SetGlassOpacity;
    property UseVistaBlur: BOOL read GetUseVistaBlur write SetUseVistaBlur;
    property UseVistaCrystal: BOOL read GetUseVistaCrystal write SetUseVistaCrystal;
    property SkinConfigFile: PWideChar Read GetSkinConfigFile write SetSkinConfigFile;
    property FontName: WideString read GetFontName write SetFontName;
    property FontSize: Integer read GetFontSize write SetFontSize;
    property SelectedImgPath: WideString read GetSelectedImgPath write SetSelectedImgPath;
    property SeperatorImgPath: WideString read GetSeperatorImgPath write SetSeperatorImgPath;
    property IconArrowPath: WideString read GetIconArrowPath write SetIconArrowPath;
    property ItemHiliteColor: COLORREF read GetItemHiliteColor write SetItemHiliteColor;
    property ItemToolTip: PWideChar read GetItemToolTip write SetItemToolTip;
    property ItemIconPath: WideString read GetItemIconPath write SetItemIconPath;
    property ItemTextAlligment: TTextAlligment read GetItemTextAlligment write SetItemTextAlligment;
    property ItemHeight: Integer read GetItemHeight write SetItemHeight;
    property ItemWidth: Integer read GetItemWidth write SetItemWidth;
    property ItemLeft: Integer read GetItemLeft write SetItemLeft;
    property ItemTop: Integer read GetItemTop write SetItemTop;
    property ItemShadow: Integer read GetItemShadow write SetItemShadow;
    property ItemTextLeft: Integer read GetItemTextLeft write SetItemTextLeft;
    property ItemEnabled: BOOL read GetItemEnabled write SetItemEnabled;
    property SubMenuItemCount: Integer read GetSubMenuItemCount write SetSubMenuItemCount;
    property ImageStateMax: Integer read GetImageStateMax write SetImageStateMax;
    property UseSideBar: BOOL read GetUseSideBar write SetUseSideBar;
    property SideBarImgPath: WideString read GetSideBarImgPath write SetSideBarImgPath;
    property SideBarCaption: WideString read GetSideBarCaption write SetSideBarCaption;
    property SideBarCaptionLeft: Integer read GetSideBarCaptionLeft write SetSideBarCaptionLeft;
    property SideBarCaptionTop: Integer read GetSideBarCaptionTop write SetSideBarCaptionTop;
    property IsSubMenu: BOOL read GetIsSubMenu write SetIsSubMenu;
    property MouseTracking: BOOL read GetMouseTracking write SetMouseTracking;
    property PrivateFont: Pointer read GetPrivateFont write SetPrivateFont;
    property TrackUser32: BOOL read GetTrackUser32 write SetTrackUser32;
    function GetWndInfo(WinHandle: HWND; var WndInfo: TSubMenuWindow): Boolean;
    procedure CreateSubMenu(ItemHandle: HWND; Count: Integer);
    function SubWindowProc(WinHandle: HWND; Msg: UINT; wP: WParam; lP: LParam): LRESULT; stdcall;
    function CreatePopUpMenu(ParentHandle: HWND): HWND;
    destructor Destroy; override;
    constructor Create;
    procedure DestroyWindow;
  end;
Und du willst mir erzählen das die DLL jetzt noch funktionieren soll?
Das möchte ich schwer bezweifeln.

Es geht mir darum das man jedes einzelne Interface inklusive der Classe Sortieren muss.
Tut man es nicht funktioniert die DLL und die Anwendung nicht mehr.
So! Wenn man nun 40 > Units mit Interface hat kann man sich vorstellen wie viel Aufwand es bedarf diese alle zu sortieren.
Sorry das ist Spielerei für mich.
Entweder alles im kompletten Projekt verglichen mit der GUID und zugehöriger Classe oder gar nichts ... so macht es jedenfalls keinen sinn wie es momentan ist.
Da macht man mehr kaputt als es gut ist.

Zusätzlich sollte man sich im klaren sein das wenn man so ein Tool verwendet und solche gravierenden dinge ändert
keine vorherige Anwendung mit dieser DLL mehr funktionstüchtig ist.
Daher entschließt sich mir die Nutzbarkeit eines solchen Tools. (Meine Meinung).

gruss

Daniel 21. Mai 2018 22:43

AW: MMX für Delphi ist ab sofort kostenlos!
 
Derart umfangreiche Testfälle bitte via Mail direkt an Uwe senden. Derlei punktuelle Fehlerdiskussionen führen zu weit vom grundsätzlichen Thema weg.

EWeiss 21. Mai 2018 23:03

AW: MMX für Delphi ist ab sofort kostenlos!
 
Zitat:

Zitat von Daniel (Beitrag 1402636)
Derart umfangreiche Testfälle bitte via Mail direkt an Uwe senden. Derlei punktuelle Fehlerdiskussionen führen zu weit vom grundsätzlichen Thema weg.

OK Daniel.. Sorry

gruss

Uwe Raabe 21. Mai 2018 23:06

AW: MMX für Delphi ist ab sofort kostenlos!
 
Du hast es zwar richtig zitiert, aber offenbar nicht richtig gelesen:
Zitat:

Zitat von jaenicke (Beitrag 1402602)
Solange das Interface sich in einer gemeinsamen Unit für Hostanwendung und DLL befindet

Die Betonung liegt auf gemeinsam.

Zitat:

Zitat von EWeiss (Beitrag 1402634)
Mein öffentliches Interface sortiert.. (unit SKAeroAPI;) in der Anwendung
Delphi-Quellcode:
ISkinPopUpMenu = interface
  ['{712A92E4-6D43-45DC-9A85-77DDF5EB19B5}']
...
Meine Master Interface Unit.. (unit uInterface;) in der DLL unsortiert
Delphi-Quellcode:
ISkinPopUpMenu = interface
  ['{712A92E4-6D43-45DC-9A85-77DDF5EB19B5}']

In deinem Fall gibt es das Interface also zweimal in jeweils eigenen Units für Hostanwendung und DLL. Oder habe ich deinen Beitrag falsch verstanden?

Übrigens: Die Sortierung der implementierenden Klasse ist vollkommen egal. Die Zuordnung der Interface-Methoden zu den Methoden der Klasse geht entweder über den Methodennamen oder eine Method Resolution Clause.

EWeiss 21. Mai 2018 23:10

AW: MMX für Delphi ist ab sofort kostenlos!
 
Zitat:

In deinem Fall gibt es das Interface also zweimal in jeweils eigenen Units für Hostanwendung und DLL. Oder habe ich deinen Beitrag falsch verstanden?
Ja.. Und sorry das ich da soweit ausgeholt habe.
Und es ruft noch zusätzliche Interface auf die in der Class definiert sind. (ISkinPopUpMenuEx)
Welchen Einfluss das sortieren dann darauf hat habe ich nicht getestet.

Zitat:

Die Betonung liegt auf gemeinsam.
Wollte es @jaenicke nur dokumentieren das es so nicht geht.

Ja im normal fall aber ich mache meine Interface direkt publik ohne sie aus der DLL zu exportieren.
Deshalb komme ich nicht Drumherum dafür 2 Units anzulegen.

EDIT:
Nur um das richtig zu stellen.
Ich möchte das Tool nicht verteufeln es hat bestimmt mächtige Funktionen die einem die Arbeit erleichtern.
Und ich finde es gut das Uwe sich dessen angenommen hat.

Aber wie so meist der erste Eindruck ist Entscheidend und der war halt.. nun bescheiden.
Ich finde es auch nicht so gut das man ins besondere auf der Schiene von Kostenlos herumfährt.. das hat irgendwie einen faden Beigeschmack.
Deshalb mein Einspruch nur weil Kostenlos muss es nicht gut sein!.
Aber gut ich habe fertig.. ;)

gruss

Aviator 22. Mai 2018 00:05

AW: MMX für Delphi ist ab sofort kostenlos!
 
Zitat:

Zitat von Uwe Raabe (Beitrag 1402638)
Du hast es zwar richtig zitiert, aber offenbar nicht richtig gelesen:
Zitat:

Zitat von jaenicke (Beitrag 1402602)
Solange das Interface sich in einer gemeinsamen Unit für Hostanwendung und DLL befindet

Die Betonung liegt auf gemeinsam.

Zitat:

Zitat von EWeiss (Beitrag 1402634)
Mein öffentliches Interface sortiert.. (unit SKAeroAPI;) in der Anwendung
Delphi-Quellcode:
ISkinPopUpMenu = interface
  ['{712A92E4-6D43-45DC-9A85-77DDF5EB19B5}']
...
Meine Master Interface Unit.. (unit uInterface;) in der DLL unsortiert
Delphi-Quellcode:
ISkinPopUpMenu = interface
  ['{712A92E4-6D43-45DC-9A85-77DDF5EB19B5}']

In deinem Fall gibt es das Interface also zweimal in jeweils eigenen Units für Hostanwendung und DLL. Oder habe ich deinen Beitrag falsch verstanden?

Übrigens: Die Sortierung der implementierenden Klasse ist vollkommen egal. Die Zuordnung der Interface-Methoden zu den Methoden der Klasse geht entweder über den Methodennamen oder eine Method Resolution Clause.

Wow. Das kommt ja alles ziemlich stark an meinen Thread ran den ich gestartet habe. Den hätte ich ja dann gar nicht öffnen müssen wenn hier ja auch schon alles beantwortet wird. :-D

ULIK 25. Mai 2018 09:44

AW: MMX für Delphi ist ab sofort kostenlos!
 
Auch von mir noch ein herzliches Dankeschön für das weitere Pflegen des MMX. :thumb::thumb::thumb:

Ich arbeite ja damit schon seit Delphi 7 und bin ziemlich glücklich damit. :-D


Alle Zeitangaben in WEZ +1. Es ist jetzt 08:37 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz