Entwickler-Ecke

Open Source Projekte - DFM-Editor


_frank_ - Di 23.05.06 17:51
Titel: DFM-Editor
Hi,
ich wollte dieses Forum mal nutzen um meinen DFM-Editor bekannt zu machen.
Wer möchte, kann diesen ja mal testen, Sourcecode/Binaries liegen bei sourceforge.
Grundphilosophie ist Unterstützung aller delphi-versionen, somit kein automatisches Hinzufügen von Eigenschaften.
Vorschau, Eigenschaften-Enumeration und viele andere Sachen sind bereits integriert.
Ich verwende ihn auf einer USB-Variante von Delphi, die keine Installation voraussetzt.

http://dfmedit.sf.net
betas: http://www.fw-web.de/dfmedit_beta.php

//edit
letzte beta (Direktlink):
binary mit package-support (benötigt vcl30.dpl):
http://www.fw-web.de/download.php?file=dfmedit_0.3.0.4b.zip
binary ohne Package-Support:
http://www.fw-web.de/download.php?file=dfmedit_0.3.0.4b_nopackage.zip
source:
http://www.fw-web.de/download.php?file=dfmedit_0.3.0.4b_src.zip

Hoffe auf viel Feedback.

Gruß Frank


alias5000 - Di 23.05.06 18:58

Könntest du bitte 1-2 Screenshots anhängen?


_frank_ - Di 23.05.06 19:23

ist alles auf der Sourceforge-seite zu finden.


_frank_ - So 28.05.06 03:00

ich hab mal ne neue Beta hochgeladen (0.1.1.2b), Sie erlaubt jetzt erstellen/bearbeiten sowie kopieren/verschieben (strg+X/C/V) von Controls in der Vorschau.
Link im ersten Posting...

Bitte mal auf Herz und Nieren testen ;)


Lannes - So 28.05.06 10:59

Hallo,

die Direktlinks zur Beta-Version funktionieren nicht :(


_frank_ - So 28.05.06 17:58

Hi,
also hab sie grade probiert..bei mir gehen sie...musst ein Sückchen warten, ist ne weiterleitung ;)

Gruß Frank


Leuchtturm - So 28.05.06 17:59

Bei mir funktioniert der Link auch


BenBE - So 28.05.06 21:52

Bei Listviews mit vordefinierten Columns scheint die Vorschau zu haken. Mir stürzt er dort immer ab, dass er da die Eigenschaft nicht lesen kann.


Lannes - So 28.05.06 22:21

Hallo,

user profile icon_frank_ hat folgendes geschrieben:
...musst ein Sückchen warten, ist ne weiterleitung...
hab es gerade mal ne halbe Stunde laufen lassen (DSL), die Weiterleitung auf die Zip wird begonnen, aber nach kurzer Zeit in der Statuszeile als "Fertig" signalisiert. Danach erfolgt eine erneute Weiterleitung mit dem gleichen Ergebnis. Und das solange man möchte :?

Hab jetzt die Zip unter Umgehung der Weiterleitung geladen :wink:
Kannst doch die Zips als Anlage an diesen Thread anhängen.

Und nun zum Programm, erstmal :zustimm: , interessantes Teil.
Das werd ich mir noch genauer anschauen.

Drei Fehler sind mir aufgefallen:

1. In der Ausgabe kann ich Teile der Einträge löschen, z.B das '=', die Meldung dann mit Nein beantwortet, es wird trotzdem gelöscht. Das führt dann zu Fehlern, wenn die Vorschau aufgerufen wird.

2. Neue Objekte lassen sich auf/in beliebigen Objekten erstellen:

Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
object Form1:TForm_DFMPreview
  BorderStyle = bsSizeToolWin
  Caption = 'Form1'
  Height = 300
  Left = 505
  Visible = True
  Width = 400
  object Animate1: TAnimate
    Width = 120
    Visible = True
    Top = 10
    Left = 10
    Height = 21
    object TreeView1: TTreeView
      Width = 120
      Visible = True
      Top = 10
      Left = 10
      Height = 21
    end
  end
end


3. Objekte mit gleicher Bezeichnung können angelegt werden, wenn nachträglich im Edit "Edit_Name" der Objektname geändert wird.

ps.: Listviews mit vordefinierten Columns werden bei mir ohne Probleme gelesen.


_frank_ - So 28.05.06 22:42

Hallo, erstmal vielen Dank für den Test... war das die Beta oder die Stable?
user profile iconLannes hat folgendes geschrieben:
Hallo,
hab es gerade mal ne halbe Stunde laufen lassen (DSL), die Weiterleitung auf die Zip wird begonnen, aber nach kurzer Zeit in der Statuszeile als "Fertig" signalisiert. Danach erfolgt eine erneute Weiterleitung mit dem gleichen Ergebnis. Und das solange man möchte :?

Hab jetzt die Zip unter Umgehung der Weiterleitung geladen :wink:
Kannst doch die Zips als Anlage an diesen Thread anhängen.

ungern, da ich momentan ziemlich aktiv dran arbeite und außerdem sehen will, wieviele Downloads der DFM-Editor hat
user profile iconLannes hat folgendes geschrieben:
Und nun zum Programm, erstmal :zustimm: , interessantes Teil.
Das werd ich mir noch genauer anschauen.

was hast du für einen Browser, hast du den text gesehen (downloading dfmedit*.zip). evtl. mal in den Source schauen, nicht dass es bei dir da irgendwas im Code zerhaut...

user profile iconLannes hat folgendes geschrieben:
Drei Fehler sind mir aufgefallen:

1. In der Ausgabe kann ich Teile der Einträge löschen, z.B das '=', die Meldung dann mit Nein beantwortet, es wird trotzdem gelöscht. Das führt dann zu Fehlern, wenn die Vorschau aufgerufen wird.

das mit dem Editieren der Ausgabe ist gewollt so...
man sollte da schon wissen was man macht ;)
normalerweise soll man die Bearbeitung im Treeview machen...

user profile iconLannes hat folgendes geschrieben:
2. Neue Objekte lassen sich auf/in beliebigen Objekten erstellen:

Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
object Form1:TForm_DFMPreview
  ...
  object Animate1: TAnimate
    ...
    object TreeView1: TTreeView
      ...
    end
  end
end


ist prinzipiell Richtig, aber...gerade bei unbekannten Controls weis DFMEdit nicht, ob das "Parent-Control" ein TWinControl ist und weitere Controls enthalten kann. Von daher hab ich da keine EInschränkung reingemacht.

user profile iconLannes hat folgendes geschrieben:
3. Objekte mit gleicher Bezeichnung können angelegt werden, wenn nachträglich im Edit "Edit_Name" der Objektname geändert wird.

das ist definitiv ein Bug...da kümmere ich mich drum ;)

user profile iconLannes hat folgendes geschrieben:
ps.: Listviews mit vordefinierten Columns werden bei mir ohne Probleme gelesen.

Sollte doch auch so sein, oder? :gruebel:

Gruß Frank


Lannes - So 28.05.06 22:52

Hallo,
user profile icon_frank_ hat folgendes geschrieben:

was hast du für einen Browser, hast du den text gesehen (downloading dfmedit*.zip). evtl. mal in den Source schauen, nicht dass es bei dir da irgendwas im Code zerhaut...
IE 6 und den Text "downloading dfmedit*.zip" habe ich gesehen. Hab bisher noch keine Probleme mit Weiterleitungen gehabt.

user profile icon_frank_ hat folgendes geschrieben:

user profile iconLannes hat folgendes geschrieben:
ps.: Listviews mit vordefinierten Columns werden bei mir ohne Probleme gelesen.

Sollte doch auch so sein, oder? :gruebel:

Gruß Frank

bezieht sich auf den Beitrag von user profile iconBenBe vor meinem.


_frank_ - So 28.05.06 23:28

user profile iconBenBE hat folgendes geschrieben:
Bei Listviews mit vordefinierten Columns scheint die Vorschau zu haken. Mir stürzt er dort immer ab, dass er da die Eigenschaft nicht lesen kann.


kannst du ein Beispiel-DFM posten, wo dieser Fehler auftritt?
vermutlich hast du da eine Eigenschaft der items drin, die es unter D3 nicht gibt.
ich kann momentan nur die Eigenschaften der objekte prüfen.

Gruß Frank


_frank_ - Mo 29.05.06 08:30

user profile iconLannes hat folgendes geschrieben:
Hallo,
hab es gerade mal ne halbe Stunde laufen lassen (DSL), die Weiterleitung auf die Zip wird begonnen, aber nach kurzer Zeit in der Statuszeile als "Fertig" signalisiert. Danach erfolgt eine erneute Weiterleitung mit dem gleichen Ergebnis. Und das solange man möchte :?

Fehler behoben...URL= hat im Meta gefehlt...damit kam der IE net klar (Firefox und Opera hats nicht getört...)
user profile iconLannes hat folgendes geschrieben:

3. Objekte mit gleicher Bezeichnung können angelegt werden, wenn nachträglich im Edit "Edit_Name" der Objektname geändert wird.

hab ich in der neuen Beta geändert...

Gruß Frank


_frank_ - Mi 31.05.06 15:34

ich habe die letzte beta (0.1.1.3) nochmal überarbeitet und hochgeladen
link steht im ersten posting

wer will kann mal testen

Gruß Frank


_frank_ - Di 13.06.06 02:24

ich hab mal eine neue Beta (0.1.1.6b) hochgeladen (link im 1. Posting),
in dieser ist es erstmals möglich über den Objektinspektor so ziemlich alle Basis-Typen zu setzen (integer,String,Enum-und Set-Typen).
Ich würde mich sehr über Beta-Tester freuen.


_frank_ - Fr 16.06.06 01:18

ich habe den Objektinspektor erweitert (enumeration aller Properties) und suche dringend beta-tester.
um den neuen Objektinspektor zu testen muss der dfmeditor mit parameter /debug (über beiliegende _debugmode.bat) gestartet werden.

Gruß Frank


_frank_ - Di 11.07.06 11:33

:wave:
ich hab mal wieder eine neue beta hochgeladen. neu sind, der automatisch gefüllte Objektinspektor und das laden von packages (d3-dpl's) um die VCL des DFMEdit zu erweitern.
Link ist im ersten post, der OI ist dort auch noch als screenshon angehängt.
per Doppelklick kommt man in den bearbeiten-Dialog.

So, viel Spaß beim testen und mir bitte mitteilen, wenn ihr Bugs findet.

Gruß Frank


Softchaos67 - Di 11.07.06 13:29

Beim Compilieren bekomme ich folgenden Fehler:

Delphi-Quelltext
1:
  [Fataler Fehler] Package 'IcsDel30' wird benötigt, konnte aber nicht gefunden werden                    


Was ist das für ein Package?


_frank_ - Di 11.07.06 14:24

ist das package der internet connection suite. hatte übersehen, dass delphi alle installierten Packages mit als laufzeit-packages reinhaut und diese beim compilieren auch mit braucht...
ihr könnt alle packages außer vcl30 und dclstd30 raushauen (ggf. die packages eurer delphi-version verwenden), hatte ich vergessen (noch nicht sooo viel mit packages gemacht ;))
bitte teilt mir mit, unter welchen delphi-versionen dfmedit sich compilieren lässt.
die forms lassen sich mit Hilfe der batch-konvertierung von dfmedit ins text-format wandeln.

ich hab mal ne modifizierte version hochgeladen (wegen den packages)...
Gruß Frank


Softchaos67 - Mi 12.07.06 07:42

Nächstes Problem:


Delphi-Quelltext
1:
[Fataler Fehler] Package 'dclstd30' wird benötigt, konnte aber nicht gefunden werden                    


Was ist das für ein Package?
Gruss
Matthias


_frank_ - Mi 12.07.06 10:24

dclstd30 ist das delphi3-package mit den standard-komponenten (TButton,TEdit,...)
vcl30 ist imho die Basis-VCL von delphi3

diese beiden Packages müssten halt an eure Delphi-Version angepasst werden.


Softchaos67 - Mi 12.07.06 11:09

Hatte wohl Tomaten auf den Augen.
Mit vcl70 funktionierts :-)


_frank_ - Mi 12.07.06 14:41

also konntest du dfmedit kompilieren? schon eigene Packages eingebaut?
teile mir bitte mit, wenn alles funktioniert oder etwas nicht funktioniert...

habe herausgefunden, dass die Liste der Packages in der *.dof-datei gespeichert wird. Leider gibts da imho keine möglichkeit per compiler-direktiven die liste abhängig von der Delphi-Version anzupassen, oder?

Gruß Frank


Softchaos67 - Mi 12.07.06 15:05

Hab nur vcl30 mit vll70 ersetzt, dann lies sich das projekt kompilieren und starten.
Hab aber das Proggi noch nicht testen können. Werde wieder berrichten.


_frank_ - Do 20.07.06 11:47

hab jetzt mal die Version 0.1.1.12b hochgeladen
neu ist u.a. das bearbeiten von stringlist, bitmap, icon und TPicture-Eigenschaften und der einstellungsdialog. Der Win9x/ME-Bug (bei den Resourcenforms, gemeldet von Monta) sollte behoben sein (hab leider kein 9x mehr hier).

es wird nur noch die vcl30.dpl benötigt, die ist auch auf der beta-seite zu finden.

Gruß Frank


Heiko - Do 20.07.06 12:06

user profile icon_frank_ hat folgendes geschrieben:
Der Win9x/ME-Bug (bei den Resourcenforms, gemeldet von Monta) sollte behoben sein (hab leider kein 9x mehr hier).

Hast du es schon einmal mit dem Kompatibilitätsmodus von XP probiert? Wenn unter 98 etc. Probleme gibt, meckert XP im Kompatibilitätsmodus dann auch rum etc. :) (des wegen finde ich diesen Modus extrem gut ;) ).


_frank_ - Do 20.07.06 13:06

hab den grade mal probiert, da tritt der fehler nicht auf...es ging darum, dass unter win ME die handles von LoadLibrary negativ sind (/sein können).

Gruß Frank


_frank_ - Do 10.08.06 01:37

so,
die nächste beta ist draußen...
neu u.a. ist:
- TCollectionItem-enumeration
- Einstellungsdialog wurde überarbeitet
- bei Sprachwechsel auf Deutsch muss nicht mehr neu gestartet werden
- Position und Größe der Forms definierbar
- multiline-Stringproperties (wird u.a. bei Tlabel unterstützt)
- einige bugs gefixt

diese version ist der RC1 für die nächste stable, d.h. es werden bis zum final nur noch bugfixes durchgeführt und die Hilfedatei aktualisiert.

bitte mal Testen, wer Interesse hat...


Raffo - Do 10.08.06 07:25

Hallo Frank!

Das ist ja echt ein Hammer-Cracker Tool. Habe gerade mal das Copyright meiner eigenen .exe Anwendung überschrieben, Programm läuft! Da muss man sich ab nun wohl verschlüsselte Labels etc. ablegen, damit das Copyright gewahrt bleibt.

Man kann die .exe aber nicht öffnen wenn ein ExePacker drübergelaufen ist, aber das Entpacken ist ja für einen Profi kein Problem.

Aber mein Kompliment! Eine viel interessantere Anwendung würde jedoch eine Übersetzung in andere Sprachen darstellen. Also müsste er nur alle Captions und andere Texteigenschaften auflisten, die man dann bequem übersetzen kann...

Kleiner Hint für Dich: In Einstellungen heisst es auf einem Reiter "Komponenten-Packete", anstatt -Pakete.

Gruß
Ralf


MrSaint - Do 10.08.06 09:26

Hallo!


Ich hab die 0.1.1.13b runtergeladen und wollte es auch mal anschauen. Leider kommt ein Fehler: "Die Anwendung konnte nicht gestartet werden, weil VCL30.dpl nicht gefunden wurde. Neuinstallation der Anwendung könnte das Problem beheben.". Tja, D3 hab ich nicht drauf, aber ich denke, das sollte auch keine Vorraussetzung sein, oder?


MrSaint


passiv - Do 10.08.06 09:54

mir gehts genauso: er will einfach nicht :gruebel:


_frank_ - Do 10.08.06 11:55

Zitat vom 20.07., dieser Thread, 3 Posts über meinem letzten ;)
user profile icon_frank_ hat folgendes geschrieben:

es wird nur noch die vcl30.dpl benötigt, die ist auch auf der beta-seite zu finden.

wer lesen kann...

@Raffo
wegen dem copyright...es gibt schon lange res-editoren, die es ermöglichen sowas zu tun (u.a. ResHacker), nur halt nicht so komfortabel ;)
ups, das mit dem Typo korrigier ich natürlich...
wegen der mehrsprachig...3 Sprachen hab ich schon (de/en/fr)...
schau dir mal die *.lng-dateien (dort sind die Bezeichner aufgelistet, die es gibt inkl. en/fr Übersetzung) sowie die Hilfe unter "configuration files" an.
ich würde mich sehr über neue Sprachen freuen...

Gruß Frank


Raffo - Do 10.08.06 13:24

Oh, ich meinte das mit den Sprachen für EIGENE Programme! In Deinem Tool müsste nur eine Suchroutine sein, die mir z.B. "Caption" ausfiltert und anlistet.


_frank_ - Do 10.08.06 13:54

Achso...
Sowas war eigentlich nicht angedacht, aber evtl. baue ich sowas in der Art ein.
Ich hatte mir gedacht die Suchen-Funktion auch für die Baum-Ansicht (für die DFM-Quelltexte gibts schon Search&Replace) zu implementieren, aber momentan will ich ersteinmal eine neue Stable herausbringen. Ich werde das mit dem Suchen aber mal probieren, vielleicht schaffe ich das noch bis zur Stable...

//edit
habe mal eine Version hochgeladen, was eine solche Suche ermöglicht...(im debugmode [_debugmode.bat])
muss nur noch überlegen, wie ich das in die oberfläche integriere...
//end edit

Bitte Teste das Programm noch intensiver

Gruß Frank


Raffo - Do 10.08.06 21:10

Ach, wenn ich noch was anmerken darf, kannst Du die Caption Änderung auch in Unicode machen, so das man Hyroglyphen eingeben kann.

Es ist ja im Grunde nur ein Filtern der Suchfunktion, aber genaueres weisst ja nur DU.

Also warum ich das mit den Sprachen angesprochen habe: Natürlich kann man ein Projekt gleich mehrsprachig aufbauen, aber bei meiner Software ist leider bei jedem Land eine andere Gesetzgebung und auch eine völlig andere Mentalität, d.h. die User benutzen das Programm völlig anders als auf dem deutschen Markt.

Daher muss ich für jedes Land eine eigene Version herausbringen und es würde sehr helfen, die Captions adhoc ändern zu können. Dann wird die Version ausgekoppelt und läuft eigenständig weiter.


_frank_ - Fr 11.08.06 14:33

das mit dem unicode ist imho in D3 nicht so einfach.
evtl. baue ich das in einer späteren Version ein.
Momentan gilt es erstmal eine (relativ) fehlerfreie Anwendung mit den derzeitigen Features zu veröffentlichen.
die aktuelle beta wurde von mir nochmal verändert, das findNode ist eingebunden sowie ein Objekthierarchie in den Add/Edit-Object-Dialog eingebaut.

Gruß Frank


_frank_ - Mo 14.08.06 20:06

hat denn schon jemand einen Bug gefunden? *push*
ich habe mittlerweile schon einige behoben...

hier mal ein Auszug aus der changelog (die Änderungen gegenüber der letzten stable-version 0.1.1.4):


Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
0.1.1.13:
  saving window-sizes and positions
  no need for restart dfmedit when changing language back to german
  Type-enumeration for TCollections
  Flag-Images for Languages (in Preferences-Dialog)
  allow editing of Stringlist,TPicture,TBitmap and TIcon-Properties in Preview
  preferences-dialog
  lazarus-unit-support
  adding lazarus-form to open-/save-filter (*.lfm)
  result of setproperty
  auto-filled ObjectInspector
  new key-bindings
  help-file updated
  some optimizations
  splitting functions_u.pas (separating RTTI-functions)
  doubleclick on property text shows Add/Edit-Dialog
  loading vcl-packages (for 3rd party components, see help)
  adding escape-key to inspector (restoring last value)
  Autofilled Procedure-names for events
  Statusbar-resizing
  component-hierarchy (in add/edit-dialog)
  find node by text
  supporting unknown properties in TCollection (deleted for preview)
  want-to-close-question if file is changed
  bugs fixed
    - in preview try to create new object, cancel
    - AV in preview when loading a form which has same name as a Form-Resource and changing a property
    - delete-key should only delete node when treeview active
    - file not saved if dfmedit opened with file as parameter
    - inspector-window not visible in maximized state
    - different bugs from previos beta-versions fixed
    - search/replace-pagecontrol visible when importing text to tree
    - changed isNumeric-function to prevent massive breaks when debugger turned on
    - class-properties which has no subproperties (like TImage.Picture) are not shown in Objectinspector
    - handles can be negative on Win9x/ME
    - enter to confirm Edit/Add-Dialog is not working when spinbutton is visible (spinbutton replaced by TUpDown)
    - subclasses not enumerated
    - empty lines in Tstrings cut off
    - relative path of lazres and packages
    - AV when trying to Save Image
    - bug with image/imagelist-tab
    - bug with CB_Value.Style for Enums
    - string decoding is rewritten and Tcollection-Items will now also en-/decoded
    - invalid pointer/AV on exit when deleting special-Type
    - AV when preview a form with TMainMenu+TMenuItems (many thanks to BenBE)
    - prevent tab-changing when node change unconfirmed


Gruß Frank


_frank_ - Do 24.08.06 01:36

hi,
neue Hauptversion (0.2) ist offiziell *push*
nach diversen Beta-Versionen ist nun endlich wieder eine "stable"-Version offiziell.
leider konnte ich noch kein Multiselect implementieren, da die neue Version der Sizing-Komponente noch einige störende Eigenschaften hat, aber im vergleich zu der letzten Stable wurden viele Funktionen hinzugefügt und Fehler beseitigt.
Falls trotzdem Fehler auftreten sollten, bitte mir mitteilen.

( http://dfmedit.sf.net )

Gruß Frank


Raffo - Do 24.08.06 10:36
Titel: Bugs
habe 2 kleine Bugs gefunden, geh mal auf (?) und Menü "über..." => Zugriffsverletzung "Aus einem sichtbaren kann kein modales..."

Habe mir eine Binärdatei geladen und bekomme über TForm_DFMMain.TB_GenPreviewClick eine Ansicht des Formulares. Auf meiner Form liegt ein TWizpanel, wenn ich also hier draufklicke - Zugriffsverletzung.

Würde es gerne auch mal mit meiner Hauptform die sehr komplex ist, aber der Vorgang dauert eine Ewigkeit und dabei gabs auch eine Zugriffsverletzung. Muss ich heute NAchmittag mal durchlaufen lassen, wenn ich eh nicht am Compi sitze...


_frank_ - Sa 02.09.06 07:36
Titel: Re: Bugs
user profile iconRaffo hat folgendes geschrieben:
habe 2 kleine Bugs gefunden, geh mal auf (?) und Menü "über..." => Zugriffsverletzung "Aus einem sichtbaren kann kein modales..."

kann ich leider nicht nachvollziehen, ist evtl. nur unter bestimmten Bedingungen so...versuch mal bitte einzugrenzen.
user profile iconRaffo hat folgendes geschrieben:
Habe mir eine Binärdatei geladen und bekomme über TForm_DFMMain.TB_GenPreviewClick eine Ansicht des Formulares. Auf meiner Form liegt ein TWizpanel, wenn ich also hier draufklicke - Zugriffsverletzung.

Würde es gerne auch mal mit meiner Hauptform die sehr komplex ist, aber der Vorgang dauert eine Ewigkeit und dabei gabs auch eine Zugriffsverletzung. Muss ich heute NAchmittag mal durchlaufen lassen, wenn ich eh nicht am Compi sitze...


beim klick auf das TWizPanel im Preview oder im Treeview kommt die AV?

Gruß Frank


_frank_ - So 24.09.06 20:19

hallo,
ich hab mal wieder eine neue Beta hochgeladen. Das Multiselect ist nun fast komplett implementiert (fehlt eigentlich nur noch OI bei unterschieldichen komponententypen). Es gibt eine optimierungsroutine, dei überflüssige/unerwünschte Eigenschaften löscht (konfigurierbar) und eine Laufzeitcode-generierung (interessant besonders für TurboDelphi-Nutzer). Ich habe auch einige bugs gefixt (u.a. fehlende Dropdown-Menüs in der toolbar bei Copilierung mit Delphi-Version >3).
Die Version ist auf der Beta-seite (http://www.fw-web.de/dfmedit_beta.php) verfügbar. Es sind weitere Kompilierungsinformationen in der Readme.txt.

Es wäre schön, wenn sich noch Beta-Tester finden würden...

Gruß Frank


0xCC - Di 26.09.06 14:12

hi, um die sourcen zu kompilieren waren 2 änderungen nötig:

1) die .dof datei löschen
2) die datei consts.pas löschen und den eintrag im dpr file auf uses consts; ändern (die unit liegt ja bei delphi bei)

hier noch ein hinweis auf eine evtl nützliche sache die du einbauen könntest:
http://www.geocities.com/thaddydekoning/kolfrmdesign.jpg
http://www.geocities.com/thaddydekoning/kolfrmdesign.zip


_frank_ - Di 26.09.06 14:40

user profile icon0xCC hat folgendes geschrieben:
hi, um die sourcen zu kompilieren waren 2 änderungen nötig:

1) die .dof datei löschen

musste ich bei mir nicht (mit D7 und TurboDelphi getested)
user profile icon0xCC hat folgendes geschrieben:
2) die datei consts.pas löschen und den eintrag im dpr file auf uses consts; ändern (die unit liegt ja bei delphi bei)

mit der consts.pas steht in der readme und den eintrag in der dpr musste ich auch nicht löschen. man mus nur noch das Package von vcl30 auf vcl ändern (steht aber auch in der readme).
user profile icon0xCC hat folgendes geschrieben:
hier noch ein hinweis auf eine evtl nützliche sache die du einbauen könntest:
http://www.geocities.com/thaddydekoning/kolfrmdesign.jpg
http://www.geocities.com/thaddydekoning/kolfrmdesign.zip

Was soll da genau erweitert werden (ist ja selbst nur ein form-designer, den ich nicht testen kann mangels kol). ist KOL überhaupt D3-kompatibel?
Ich überlege momentan, wie man ein plugin-system realisieren kann, welches zugriff auf das treeview gestattet. dann kann man dfmedit per plugin-dlls erweitern.
die Varianten, die ich bisher gesehen habe sind ziemlich (mir zu sehr) umfangreich...

schon irgendwelche Bugs gefunden?

Gruß Frank


0xCC - Di 26.09.06 15:02

user profile icon_frank_ hat folgendes geschrieben:
user profile icon0xCC hat folgendes geschrieben:
hi, um die sourcen zu kompilieren waren 2 änderungen nötig:

1) die .dof datei löschen

musste ich bei mir nicht (mit D7 und TurboDelphi getested)

die dof verweist auf die vcl30, aber delphi erstellt selber eine passende datei mit standardeinstellungen. die meisten probleme die ich bisher hatte waren auf die doofen dofs zurückzuführen, nach dem löschen derselben ging es dann aber immer.
user profile icon_frank_ hat folgendes geschrieben:
user profile icon0xCC hat folgendes geschrieben:
2) die datei consts.pas löschen und den eintrag im dpr file auf uses consts; ändern (die unit liegt ja bei delphi bei)

mit der consts.pas steht in der readme und den eintrag in der dpr musste ich auch nicht löschen. man mus nur noch das Package von vcl30 auf vcl ändern (steht aber auch in der readme).

warum eine unit beilegen die sowieso bei delphi dabei ist ? so gibt es nur versionsschwierigkeiten. (controls wurde mit einer anderen version von consts.pas kompiliert usw)
user profile icon_frank_ hat folgendes geschrieben:
user profile icon0xCC hat folgendes geschrieben:
hier noch ein hinweis auf eine evtl nützliche sache die du einbauen könntest:
http://www.geocities.com/thaddydekoning/kolfrmdesign.jpg
http://www.geocities.com/thaddydekoning/kolfrmdesign.zip

Was soll da genau erweitert werden (ist ja selbst nur ein form-designer, den ich nicht testen kann mangels kol).

naja, halt einen grafischen formdesigner einbauen ? ;)
user profile icon_frank_ hat folgendes geschrieben:
ist KOL überhaupt D3-kompatibel?

afaik ab D4, aber sicher bin ich mir nicht...
user profile icon_frank_ hat folgendes geschrieben:
Ich überlege momentan, wie man ein plugin-system realisieren kann, welches zugriff auf das treeview gestattet. dann kann man dfmedit per plugin-dlls erweitern.
die Varianten, die ich bisher gesehen habe sind ziemlich (mir zu sehr) umfangreich...

schon irgendwelche Bugs gefunden?

ne, das programm war mir dann doch ein wenig zu komplex (darum auch der hinweis auf die grafische variante)


0xCC - Di 26.09.06 15:06

hier mal zum testen das kompilierte bsp.


_frank_ - Di 26.09.06 15:24

user profile icon0xCC hat folgendes geschrieben:

die dof verweist auf die vcl30, aber delphi erstellt selber eine passende datei mit standardeinstellungen. die meisten probleme die ich bisher hatte waren auf die doofen dofs zurückzuführen, nach dem löschen derselben ging es dann aber immer.

achso, so hast du das Problem mit der vcl30 gelöst...aber in der dof-datei werden nicht nur die packages gespeichert. z.B. die Versionsnummer steht da auch, und darauf will ich nicht verzichten ;)
Mal davon abgesehen, dass delphi imho eine dof-datei ohne laufzeitpackages erstellt, d.h. du kannst die package-Funktion nicht verwenden, wenn du delphi die dof erstellen lässt.
user profile icon0xCC hat folgendes geschrieben:
warum eine unit beilegen die sowieso bei delphi dabei ist ? so gibt es nur versionsschwierigkeiten. (controls wurde mit einer anderen version von consts.pas kompiliert usw)

die war dazu gedacht, dass fehlermeldungen auf Englisch kommen und nicht in meiner IDE-Sprache (deutsch).

user profile icon0xCC hat folgendes geschrieben:
naja, halt einen grafischen formdesigner einbauen ? ;)

die Vorschau (Monitor in Toolbar) hast du dir aber schon angeschaut, oder? *g* Denn da ist fast alles graphisch möglich (Positionierung, Größenänderung, neue Komponenten, Eigenschaften ändern [mittels Objektinspektor], Ausschneiden/Kopieren,...). nur die Vorschau-Variante ist nicht immer nötig. die meisten Sachen lassen sich im Treeview schneller/einfacher bearbeiten.
user profile icon0xCC hat folgendes geschrieben:
user profile icon_frank_ hat folgendes geschrieben:
ist KOL überhaupt D3-kompatibel?

afaik ab D4, aber sicher bin ich mir nicht...

dachte du möchtest KOL-Support (z.B. für Laufzeit-codegenerierung).
user profile icon0xCC hat folgendes geschrieben:
ne, das programm war mir dann doch ein wenig zu komplex (darum auch der hinweis auf die grafische variante)

siehe oben, gibt es schon, nur ich nehm die nicht immer...

Gruß Frank


0xCC - Di 26.09.06 15:49

user profile icon_frank_ hat folgendes geschrieben:
user profile icon0xCC hat folgendes geschrieben:

die dof verweist auf die vcl30, aber delphi erstellt selber eine passende datei mit standardeinstellungen. die meisten probleme die ich bisher hatte waren auf die doofen dofs zurückzuführen, nach dem löschen derselben ging es dann aber immer.

achso, so hast du das Problem mit der vcl30 gelöst...aber in der dof-datei werden nicht nur die packages gespeichert. z.B. die Versionsnummer steht da auch, und darauf will ich nicht verzichten ;)

wie duz meinst...

user profile icon_frank_ hat folgendes geschrieben:
user profile icon0xCC hat folgendes geschrieben:
naja, halt einen grafischen formdesigner einbauen ? ;)

die Vorschau (Monitor in Toolbar) hast du dir aber schon angeschaut, oder? *g*

klar, allerdings dauert es verdammt lange, bis das preview erstellt ist.


user profile icon_frank_ hat folgendes geschrieben:
dachte du möchtest KOL-Support (z.B. für Laufzeit-codegenerierung).

das wär gar nicht übel :)
user profile icon_frank_ hat folgendes geschrieben:
user profile icon0xCC hat folgendes geschrieben:
ne, das programm war mir dann doch ein wenig zu komplex (darum auch der hinweis auf die grafische variante)

siehe oben, gibt es schon, nur ich nehm die nicht immer...


im allgemeinen sieht das prog sehr brauchbar aus, vor allem die funktion, aus ner exe das dfm auszulesen.
allerdings scheint es in der preview noch probleme mit dem markieren einzelner komponenten zu geben, manche werden erst nach 2 klicks blau umrandet, manche gar nie.

ich habe ausserdem mal einen testlauf mit fastmm4.pas (eigentlich um die geschw. zu erhöhen) gemacht, und mir wurden einige speicherlecks gemeldet.
das solltest du dir vielleicht mal ansehen.


_frank_ - Di 26.09.06 16:11

user profile icon0xCC hat folgendes geschrieben:

klar, allerdings dauert es verdammt lange, bis das preview erstellt ist.

durchaus möglich dass meine routinen nicht die schnellsten sind, für bessere Varianten bin ich offen ;)
user profile icon0xCC hat folgendes geschrieben:

das wär gar nicht übel :)

gehen natürlich nur die infos, die sich aus der DFM definieren lassen. Dazu brächte ich aber detailierte Infos, wie das bei KOL aussehen muss.
user profile icon0xCC hat folgendes geschrieben:
im allgemeinen sieht das prog sehr brauchbar aus, vor allem die funktion, aus ner exe das dfm auszulesen.
allerdings scheint es in der preview noch probleme mit dem markieren einzelner komponenten zu geben, manche werden erst nach 2 klicks blau umrandet, manche gar nie.

hast du da ne Beispiel-DFM, wo das auftritt. Hatte das Problem noch nicht.
user profile icon0xCC hat folgendes geschrieben:
ich habe ausserdem mal einen testlauf mit fastmm4.pas (eigentlich um die geschw. zu erhöhen) gemacht, und mir wurden einige speicherlecks gemeldet.
das solltest du dir vielleicht mal ansehen.

kenne die fastmm nicht, wird vermutlich auch nicht unter d3 laufen. kanst du mir sagen wo die Speicherlecks auftreten?

Gruß Frank


0xCC - Di 26.09.06 17:54

user profile icon_frank_ hat folgendes geschrieben:
user profile icon0xCC hat folgendes geschrieben:

klar, allerdings dauert es verdammt lange, bis das preview erstellt ist.

durchaus möglich dass meine routinen nicht die schnellsten sind, für bessere Varianten bin ich offen ;)

ich hab mich mal ein bischen gespielt, so 20% konnte ich schon mal rausholen - siehe geänderte sourcen im beigefügten zip (siehe Suche in: Delphi-Forum PERFORMANCE)
user profile icon_frank_ hat folgendes geschrieben:
hast du da ne Beispiel-DFM, wo das auftritt. Hatte das Problem noch nicht.

main_u.dfm
user profile icon_frank_ hat folgendes geschrieben:
user profile icon0xCC hat folgendes geschrieben:
ich habe ausserdem mal einen testlauf mit fastmm4.pas (eigentlich um die geschw. zu erhöhen) gemacht, und mir wurden einige speicherlecks gemeldet.
das solltest du dir vielleicht mal ansehen.

kenne die fastmm nicht, wird vermutlich auch nicht unter d3 laufen. kanst du mir sagen wo die Speicherlecks auftreten?

Suche bei Google FASTMM4 - einfach runterladen und in einen der bibliothekspfade reinstellen, als erste USES in deiner DPR deklarieren.

die lecks treten auf weil du die kompos des Vorschaufensters zur Laufzeit generierst, aber nicht wieder freigibst.
wenn du das Objekt kreierst, solltest du einen pointer in eine Tlist speichern, und das Objekt bei shcliessen des Fenster wieder Free'en.


0xCC - Di 26.09.06 19:03

hab noch ein bischen rumexperimentiert, diesmal ists spürbar schneller.
allerdings wird ungefähr 90% der cpuzeit mit der funktion TTreeView.GetAbsoluteIndex (und in weiterer folge GetLastChild) vertrödelt. Die Generierung deines Memo-textes per TreeView ist äusserst ungünstig, besser wäre die erstellung über eine unsichtbare verkettete liste.


_frank_ - Di 26.09.06 19:12

sehe grade du nimmst noch die stable 2.0.0, richtig. weil in den Betas hab ich schon auf eine andere Sizing-Kompo umgestellt. aber ich schau mir die änderungen mal an...

- in der Main.pas hast du die Aktualisierungsrate der progreesbar runtergenommen, ist sinnvoll bei großen DFMs, aber bei kleinen wird imho zuviel übersprungen. evtl. muss diese berechnung in die generate-procedure. die callback wird von dort aufgerufen.
mal eine Änderung von mir:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
  pStep:=Treeview.Items.Count div 100;
  pNext:=pStep;
  while ...
    if (isObject(tn)) and (assigned(callback)) and (tn.AbsoluteIndex>pNext) then
    begin
      callback((100*tn.AbsoluteIndex) div treeview.items.count,'');
      inc(pNext,pStep);
    end;

so wird die callback nur bei jedem prozentpunkt einmal aufgerufen, was auch ein Geschwindigkeitsvorteil sein sollte.

- das mit dem inline/inherited ist interessant...bringt das wirklich so viel performance? eigentlich würde das erste Zeichen doch reichen...
- mit temp (lowercase) ist klar...
- so wie ich das sehe werden myTrim und somit needsTrim nicht verwendet
- fastmm funktioniert erst ab d4 evtl. kannst du mir die stellen sagen, wo speicherlecks entstehen.
du meinst doch mit Erstellen das nachträgliche Erstellen von Komponenten, "Objekt hinzufügen", oder?

Gruß Frank


0xCC - Di 26.09.06 19:20

jeder zugriff auf das TreeView Objekt kostet viel Zeit, speicher doch öfters verwendete properties in einer variable, z.b:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
  X := Treeview.Items.Count;
  pStep:=X div 100
  pNext:=pStep; 
  while ... 
    if (isObject(tn)) and (assigned(callback)) and (tn.AbsoluteIndex>pNext) then 
    begin 
      callback((100*tn.AbsoluteIndex) div X ,''); 
      inc(pNext,pStep); 
    end;


das mit dem inline bringt nicht sooo viel, weil die proc nur ca. 100 mal aufgerufen wird, die zugriffe auf das TTreeView gehen aber in die tausende. ansonsten würde es schon viel bringen, weil nicht jedesmal mit COPY ein neuer string alloziert werden muss....

die dauernden trims könnte man auch vermeiden indem man die vorhergehende copy-funktion genauer arbeiten lässt - bei jedem durchlauf eine string-alloziierung erspart.

die genauen stellen der speicherlecks kenne ich nicht, fastmm meldet nur dass welche da sind, aber nicht an welcher codestelle sie entstanden sind.


_frank_ - Di 26.09.06 20:18

user profile icon0xCC hat folgendes geschrieben:
jeder zugriff auf das TreeView Objekt kostet viel Zeit, speicher doch öfters verwendete properties in einer variable, z.b:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
  X := Treeview.Items.Count;
  pStep:=X div 100
  pNext:=pStep; 
  while ... 
    if (isObject(tn)) and (assigned(callback)) and (tn.AbsoluteIndex>pNext) then 
    begin 
      callback((100*tn.AbsoluteIndex) div X ,''); 
      inc(pNext,pStep); 
    end;

das mit dem inline bringt nicht sooo viel, weil die proc nur ca. 100 mal aufgerufen wird, die zugriffe auf das TTreeView gehen aber in die tausende.

treeview.items.count wird genau 101x verwendet 1x beim start und bei jedem prozentpunkt 1x => so viel ist das doch nicht, oder?
user profile icon0xCC hat folgendes geschrieben:
ansonsten würde es schon viel bringen, weil nicht jedesmal mit COPY ein neuer string alloziert werden muss....

auf welche stelle bezihst du dich da, den leerstring oben?
user profile icon0xCC hat folgendes geschrieben:
die dauernden trims könnte man auch vermeiden indem man die vorhergehende copy-funktion genauer arbeiten lässt - bei jedem durchlauf eine string-alloziierung erspart.

die genauen stellen der speicherlecks kenne ich nicht, fastmm meldet nur dass welche da sind, aber nicht an welcher codestelle sie entstanden sind.

schon klar, aber tritt der fehler immer auf oder nur wenn du im preview componenten anlegst?

die weiteren Änderungen von dir werde ich mir mal anschauen (wegen Tstrings).

mit unsichtbarer verketteter liste meinst du sicher, ich soll das treeview von seiner hierarchie unsichtbar nachbauen? glaube, das ist im moment bisschen viel Arbeit.

Gruß frank


0xCC - Di 26.09.06 20:45

user profile icon_frank_ hat folgendes geschrieben:
user profile icon0xCC hat folgendes geschrieben:
das mit dem inline bringt nicht sooo viel, weil die proc nur ca. 100 mal aufgerufen wird, die zugriffe auf das TTreeView gehen aber in die tausende.

treeview.items.count wird genau 101x verwendet 1x beim start und bei jedem prozentpunkt 1x => so viel ist das doch nicht, oder?

doch, es wird pro durchlauf einmal zu oft verwendet. am besten wäre es sogar den wert per parameter an die funktion zu übergeben, dann muss sie im ganzen programmablauf nämlich nur einmal aufgerufen werden.


user profile icon_frank_ hat folgendes geschrieben:
user profile icon0xCC hat folgendes geschrieben:
ansonsten würde es schon viel bringen, weil nicht jedesmal mit COPY ein neuer string alloziert werden muss....

auf welche stelle bezihst du dich da, den leerstring oben?

ich beziehe mich auf das if copy(s,1,6) = 'inside' oder so ähnlich
user profile icon_frank_ hat folgendes geschrieben:

schon klar, aber tritt der fehler immer auf oder nur wenn du im preview componenten anlegst?

nein, das leck tritt auf sobald ein preview angezeigt (erstellt) wird.
user profile icon_frank_ hat folgendes geschrieben:
die weiteren Änderungen von dir werde ich mir mal anschauen (wegen Tstrings).

mit unsichtbarer verketteter liste meinst du sicher, ich soll das treeview von seiner hierarchie unsichtbar nachbauen? glaube, das ist im moment bisschen viel Arbeit.

musst du nicht nachbauen, guck dir mal diese komponente an:
http://www.delphi-gems.com/VirtualTreeview/VT.php


_frank_ - Mi 27.09.06 12:07

user profile icon0xCC hat folgendes geschrieben:

doch, es wird pro durchlauf einmal zu oft verwendet. am besten wäre es sogar den wert per parameter an die funktion zu übergeben, dann muss sie im ganzen programmablauf nämlich nur einmal aufgerufen werden.

hab das ausprobiert (nur einmal Treeview.items.count am anfang bei zuweisung zu Integer-var), bringt nicht wirklich einen Unterschied in der performance
user profile icon0xCC hat folgendes geschrieben:
ich beziehe mich auf das if copy(s,1,6) = 'inside' oder so ähnlich

mhm...meinst, ich soll auf i am anfang prüfen und einmal copy bis zum leerzeichen (oder festwert) machen, statt 2x copy?
user profile icon0xCC hat folgendes geschrieben:
nein, das leck tritt auf sobald ein preview angezeigt (erstellt) wird.

füge mal

Delphi-Quelltext
1:
if assigned(Comp) then freeandnil(comp);                    

direkt nach der while-schleife in Generate ein. ist die einzige Stelle, die mir einfällt, wo ein solches Leck entstehen könnte (letzter durchlauf, nachdem tn=nil ist)
user profile icon0xCC hat folgendes geschrieben:
musst du nicht nachbauen, guck dir mal diese komponente an:
http://www.delphi-gems.com/VirtualTreeview/VT.php

VirtualTreeview ist mir ein Begriff, jedoch gibts das erst ab D5 (oder D4? jedenfalls nicht für D3)

Ansonsten hat das umschreiben auf string (statt Stringlist) und die inline-sache in meiner Test-DFM ~7800 Zeilen knapp 13 sek (35 vs. 22) herausgeholt. Ist schonmal ganz gut ;) Danke
musste es nur selbst implementieren, da du noch die 0.2.0.0 verwendet hast, ich bereits bei der 0.2.0.8 bin.
hab die aktuelle mal angehängt...

Gruß Frank


0xCC - Mi 27.09.06 17:19

so, ich erklär dir das mal mit der inline-sache:

du hattest:


Delphi-Quelltext
1:
        if copy(tn.Text,1,2)<>'On' then //fehler wegen fehlender event-methoden beheben                    

hier wird bei jedem durchlauf ein neuer string erzeugt, und überprüft ob er 'On' ist

ich habe draus folgendes gemacht

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
function isCharAtPos(s:pchar; c:char; p: integer):boolean; // ungefährliche funktion, da bei ein leerer oder zu kurzer string durch IsBadReadPtr abgefangen wird
begin
  result := false;
  if (p = 0or (s=nilthen exit;
  inc(s,p-1);
  if not IsBadReadPtr(s,1then begin
    if s^ = c then result := true;
  end;
end;

function isFirstChar(s:pchar; c:char):boolean;
begin
  result := isCharAtPos(s,c,1);
end;

...
        if not ((isFirstChar(pchar(tn.Text),'O')) and (isCharAtPos(pchar(tn.Text),'n',2))) then


ich überprüfe, ob das erste zeichen des BESTEHENDEN strings 'O' ist, und ob das zweite 'n' ist.
das resultat wird direkt über ein cpu-register (EAX) zurückgeliefert, erfordert also keinerlei speicher-alloziierung
alles in allem werden hier vielleicht 20 cpu-befehle durchgeführt, bei deiner variante weit über 1000.

bei einer schleife, die einige hundert mal läuft, kann man dabei bereits einen beträchtlichen geschw. unterschied feststellen.

oder bei der inline-geschichte:
du hattest:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
      if (copy(s,1,1)='i'then // bei jedem durchlauf ein string alloziert
      begin
        if copy(s,1,6)='inline' then  // und wenn der mit 'i' anfängt, gleich nochmal
          s:='object'+copy(s,7,length(s)-6);
        if copy(s,1,9)='inherited' then // und nochmal, fall die vorherige bedingung nicht zutraf
          s:='object'+copy(s,10,length(s)-9); 
      end;


ich hingegen:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
      if (isFirstChar(pchar(s),'i')) and IsCharAtPos(pchar(s),'n',2then //überprüfe direkt an der speicheradresse ob der string mit 'in' beginnt: aufwand: ca 40 zeilen assembler
      begin
        if copy(s,1,6)='inline' then // und nur falls der mit 'in' anfängt, wird dann mit speicher rumhantiert...
          s:='object'+copy(s,7,length(s)-6);
        if copy(s,1,9)='inherited' then
          s:='object'+copy(s,10,length(s)-9);
      end;


ich hoffe du hast es nun verstanden, um das ganze besser nachvollziehen zu können setze einen breakpoint an der betreffenden stelle und wenn dieser erreicht wird, drücke STRG-ALT-C für das CPU fenster. mit F7 kannst du dann mit einzelschritten durchsteppen und siehst wieviele schritte die cpu ausführt, bis die fogende delphi-quelltext-zeile erreicht wird....

ich habe noch ein paar verbesserungen eingebaut, siehe attachment, der code ist noch gut 20% schneller als die letzte version

übrigens: das problem mit dem speicherleck existiert in der aktuellen version nicht mehr.
// nachtrag, nein, ich habe nur auf die fastmm4.pas vergessen, ich hänge dir noch das logfile an

vielleicht solltest du dir wirklich mal überlegen auf einen moderneren compiler zu wechseln, die D7 Personal ist eh Freeware


_frank_ - Do 28.09.06 12:55

user profile icon0xCC hat folgendes geschrieben:
so, ich erklär dir das mal mit der inline-sache:

heist das "inline" oder meinst du nur den stringvergleich mit 'inline'?
user profile icon0xCC hat folgendes geschrieben:
du hattest:


Delphi-Quelltext
1:
        if copy(tn.Text,1,2)<>'On' then //fehler wegen fehlender event-methoden beheben                    

hier wird bei jedem durchlauf ein neuer string erzeugt, und überprüft ob er 'On' ist

ist klar...
user profile icon0xCC hat folgendes geschrieben:
ich habe draus folgendes gemacht

Delphi-Quelltext
1:
...                    


ich überprüfe, ob das erste zeichen des BESTEHENDEN strings 'O' ist, und ob das zweite 'n' ist.

byteweiser vergleich (um keinen longstring=pointer zu bekommen?), wenn ich das richtig sehe...
user profile icon0xCC hat folgendes geschrieben:
das resultat wird direkt über ein cpu-register (EAX) zurückgeliefert, erfordert also keinerlei speicher-alloziierung
alles in allem werden hier vielleicht 20 cpu-befehle durchgeführt, bei deiner variante weit über 1000.

ohne speicherallozierung, pointer, stack, etc. ist klar, wenn alles in den registern abläuft...
user profile icon0xCC hat folgendes geschrieben:
bei einer schleife, die einige hundert mal läuft, kann man dabei bereits einen beträchtlichen geschw. unterschied feststellen.

oder bei der inline-geschichte:

aso, mit pchar holt man sich nur die speicheradresse...dachte da wird ein neuer string angelegt (+#0) und dessen adresse zurückgegeben...
hab die 3 fälle (on, inline, >) mal so geändert, aber schneller ist es noch nicht geworden...
user profile icon0xCC hat folgendes geschrieben:
ich hoffe du hast es nun verstanden, um das ganze besser nachvollziehen zu können setze einen breakpoint an der betreffenden stelle und wenn dieser erreicht wird, drücke STRG-ALT-C für das CPU fenster. mit F7 kannst du dann mit einzelschritten durchsteppen und siehst wieviele schritte die cpu ausführt, bis die fogende delphi-quelltext-zeile erreicht wird....

naja, bin nicht so der profi in ASM somit kann ich mit dem CPU-Fenster (gibts in D3 eh nicht (zumindest nicht im menü gefunden), strg+alt+C ist imho auch schlecht gewählt)
user profile icon0xCC hat folgendes geschrieben:
ich habe noch ein paar verbesserungen eingebaut, siehe attachment, der code ist noch gut 20% schneller als die letzte version

werd ich mir mal anschauen...danke erstmal...
treeview1.visible => bringt nur ~60ms
@problem mit dem speicherleck
naja, viel kann ich dem nicht entnehmen...les ich das richtig, dass das Speicherleck vom Typ TCellOptions ist? sind das soviele speicherlecks? (~122 á 12b)?
TCellOptions ist für den Objectinspector, enthält infos für das Stringgrid (Datentyp der eigenschaft pPropdata). Aber so viele Eigenschaften sind doch da pro durchlauf eigentlich nicht drin...
Probier mal folgendes und sag mal bitte, ob das speicherleck dann Weg ist:


Delphi-Quelltext
1:
2:
3:
4:
procedure TForm_DFMInspector.FormDestroy(Sender: TObject);
begin
  freeObjects;
end;

TCellOptions werden im GetPropValues erstellt, davor werden aber evtl. existierende freigegeben (bevor an dem Stringgrid irgendwas gemacht wird).
Wichtig für multiselect (unterschiedliche Typen):

Delphi-Quelltext
1:
2:
3:
4:
procedure TForm_DFMInspector.SetOIOnlySize;
begin
  freeObjects;
...


user profile icon0xCC hat folgendes geschrieben:
vielleicht solltest du dir wirklich mal überlegen auf einen moderneren compiler zu wechseln, die D7 Personal ist eh Freeware

die personal hab ich schonmal draufgehabt, aber irgendwie lief die net so toll (und vcl-code fehlt, logisch bei freeware)...evtl. probier ichs nochmal, ändert aber an der tatsache nichts, dass dfmedit in d3 (bzw. d3 kompatibel) bleibt ;)

die geänderte ist wieder auf der beta-seite verlinkt.
ist nur noch das treeview (items.count) offen, ist der Unterschied wirklich so extrem, dass sich der Umbau wirklich lohnt?

Gruß Frank


0xCC - Do 28.09.06 15:02

user profile icon_frank_ hat folgendes geschrieben:
user profile icon0xCC hat folgendes geschrieben:
so, ich erklär dir das mal mit der inline-sache:

heist das "inline" oder meinst du nur den stringvergleich mit 'inline'?

ich meine den vergleich mit 'inline' usw.

user profile icon_frank_ hat folgendes geschrieben:
user profile icon0xCC hat folgendes geschrieben:
du hattest:


Delphi-Quelltext
1:
        if copy(tn.Text,1,2)<>'On' then //fehler wegen fehlender event-methoden beheben                    

hier wird bei jedem durchlauf ein neuer string erzeugt, und überprüft ob er 'On' ist

ist klar...
user profile icon0xCC hat folgendes geschrieben:
ich habe draus folgendes gemacht

Delphi-Quelltext
1:
...                    


ich überprüfe, ob das erste zeichen des BESTEHENDEN strings 'O' ist, und ob das zweite 'n' ist.

byteweiser vergleich (um keinen longstring=pointer zu bekommen?), wenn ich das richtig sehe...

nein, damit kein neuer string alloziiert wird...
user profile icon_frank_ hat folgendes geschrieben:
hab die 3 fälle (on, inline, >) mal so geändert, aber schneller ist es noch nicht geworden...

ich weiss mindestens 4 fälle (auch das mit '='), aber ich habe die änderungen bereits in die 0.2.0.8 eingebaut.
warum nimmst du nicht einfach meinen source (die stelle mit dem perf-counter kannst ja auskommentieren) ?
bei mir dauert es nun bei main_u.dfm statt 1,31 sek 1,11 sek
user profile icon_frank_ hat folgendes geschrieben:

werd ich mir mal anschauen...danke erstmal...

nicht anschauen, einbauen :mrgreen:
user profile icon_frank_ hat folgendes geschrieben:
treeview1.visible => bringt nur ~60ms

na, immerhin - schneller ist besser
user profile icon_frank_ hat folgendes geschrieben:
@problem mit dem speicherleck
naja, viel kann ich dem nicht entnehmen...les ich das richtig, dass das Speicherleck vom Typ TCellOptions ist? sind das soviele speicherlecks? (~122 á 12b)?

nein, es gibt mehrere -> siehe screenshot (vermutlich eines für jede erzeugte kompo der preview (gilt alles für main_u.dfm)
user profile icon_frank_ hat folgendes geschrieben:
ist nur noch das treeview (items.count) offen, ist der Unterschied wirklich so extrem, dass sich der Umbau wirklich lohnt?

der umbau lohnt, da ich ihn doch bereits für dich vorgenommen habe.

installier dir halt das D7 Pers noch dazu und mach da deine Lecktests.
ich hab auch mehrere delphi-versionen installiert.


_frank_ - Do 28.09.06 16:07

user profile icon0xCC hat folgendes geschrieben:

ich weiss mindestens 4 fälle (auch das mit '='), aber ich habe die änderungen bereits in die 0.2.0.8 eingebaut.
warum nimmst du nicht einfach meinen source (die stelle mit dem perf-counter kannst ja auskommentieren) ?
bei mir dauert es nun bei main_u.dfm statt 1,31 sek 1,11 sek

weil ich das selber einbauen will ;), da verstehe ich die Änderungen besser bzw. kann ich mir die auch besser merken...
user profile icon0xCC hat folgendes geschrieben:
nein, es gibt mehrere -> siehe screenshot (vermutlich eines für jede erzeugte kompo der preview (gilt alles für main_u.dfm)


user profile icon0xCC hat folgendes geschrieben:
der umbau lohnt, da ich ihn doch bereits für dich vorgenommen habe.

installier dir halt das D7 Pers noch dazu und mach da deine Lecktests.
ich hab auch mehrere delphi-versionen installiert.

hab mir die personal mal installiert und bekomme die fehlermeldung "für den Zugriff auf 'isMultiThead' von Unit FastMM4 wird die Referenz auf importierte Daten ($G) benötigt".
im Projektquellcode kann ich $G nicht setzen ({$G+} am anfang), mach ich das in der Main_u.pas bleibt der Fehler. in den Projektoptionen finde ich nichts mit "Importierte Daten".
Wie bekomme ich den Fehler weg?

ein paar speicherlecks (TTypeObject) müssten sich so entfernen lassen:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
//functions_u.pas:
procedure FreeSLObjects(list:TStrings);
var i:integer;
begin
  for i:=0 to list.Count-1 do
    if assigned(list.Objects[i]) then
    begin
      list.Objects[i].free;
      list.Objects[i]:=nil;
    end;
end;
//rttifunctions_u.pas
procedure GetComponentProps(AComponent:string;List:TStrings;AppendSubclasses:boolean);
var
...
begin
  //classe:=getclass(AComponent);
  FreeSLObjects(list);
  list.clear;

//addproperty_u.pas:
procedure TForm_DFMAdd.FormDestroy(Sender: TObject);
begin
  FreeSLObjects(cb_Name.Items);
  FreeSLObjects(cb_SubClass.Items);
end;


Gruß Frank


0xCC - Do 28.09.06 18:12

user profile icon_frank_ hat folgendes geschrieben:

hab mir die personal mal installiert und bekomme die fehlermeldung "für den Zugriff auf 'isMultiThead' von Unit FastMM4 wird die Referenz auf importierte Daten ($G) benötigt".
im Projektquellcode kann ich $G nicht setzen ({$G+} am anfang), mach ich das in der Main_u.pas bleibt der Fehler. in den Projektoptionen finde ich nichts mit "Importierte Daten".
Wie bekomme ich den Fehler weg?

vermutlich direkt in der fastm4.pas setzen


_frank_ - Do 28.09.06 19:49

leider nicht...hab dafür mal nen neuen Thread aufgemacht, da das mit DFMedit nicht wirklich was zu tun hat...

http://www.delphi-forum.de/viewtopic.php?p=390342

Gruß Frank


_frank_ - Fr 29.09.06 17:59

so, hab alle Leaks gefixt, die ich gefunden habe

aktuelle Version wie immer auf der Beta-Seite

Gruß Frank


0xCC - Sa 30.09.06 17:49

Bravo !

Ich hab noch 2,3 kleinere Änderungen vorgenommen, u.a. auf die Progressbar verzichtet, wodurch die parse-zeit auf 0,7 sek gesunken ist, und die progressbar überflüssig macht...

siehe anlage.

mittlerweile könntest dann eigentlich mal die versionsnummer um eins erhöhen (alles was unter 1.0 ist, ist sowieso beta..)


_frank_ - Sa 30.09.06 20:38

Hi,
also bei meiner Test-dfm ~7800 Zeilen macht das Entfernen der Progressbar inkl. der gesamten callback-routine gar nichts aus. Es ist nur unschön, da das programm einfriert.
Den Rest habe ich soweit übernommen.

warum machst du das:
< if isFirstChar(pchar(s),'i') then
---
> if (isFirstChar(pchar(s),'i')) and (isCharAtPos(pchar(s),'n',2)) then
?
das Prüfen des ersten Zeichens reicht aus, da immer umgewandelt werden soll, wenn nicht object dasteht ;)
hab das ganze daher bisschen vereinfacht:

Delphi-Quelltext
1:
2:
3:
4:
5:
  if isFirstChar(pchar(s),'i'then
  begin
    p:=pos(' ',s);
    s:='object'+copy(s,p,length(s)-p+1);
  end;


dieser code ist übrigends nur nötig für delphi-versionen, die das inline/inherited nicht kennen (für D7 z.B. nicht). Weis aber nicht, ab welcher delphi-Version das implementiert wurde, da könnte man das per Compilerschalter deaktivieren.

hab übrigends auch eine isLastChar erstellt... (in der functions_u). macht intern das gleiche wie du nur in ner funktio

wegen der Versionsnummer...ich mach deshalb noch keine 1.0 da noch einige Sachen nicht unterstützt werden ;)

ich wollte noch sowas wie automatisierte Eigenschaften-Anpassung einbauen, weis aber noch nicht, wie ich das realisiere (evtl. jemand eine Idee?).
u.a. soll man damit z.B. von Toolbuttons der imageindex ab einem bestimmten knoten erhöht werden können (wenn z.b. ein Button eingefügt wird, habe gern die images in der Imagelist wie die toolbuttons ;) ). ist sonst eine lästige Arbeit.
Vor der nächsten Stable möchte ich auch eine Objektersetzung realisieren, um. z.B. die tntControls durch ihre Standard-Komponenten darzustellen, wenn diese nicht integriert sind, anstatt sie durch TUnknownControl darzustellen. Evtl. noch eine Personalisierung des TUnknownControl. soweit meine Ideen...

Gruß Frank


0xCC - Mo 02.10.06 00:58

die isLastChar habe ich bewusst weggelassen, da durch einen aufruf von length der pchar wieder in einen neuen string kopiert wird, und bei strlen der komplette string durchgegangen wird, um das abschliessende #0 zu finden.

die folgende variante umgeht dieses problem durch einen dirty hack:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
function isLastChar(s:pchar; c:char):boolean;
// achtung: funktioniert nur wenn s auf einen "richtigen" delphi-string zeigt !
begin
  result := false;
  if (s=nilthen exit;
  result := isCharAtPos(s,c,pcardinal(cardinal(s) - 4)^);
end;


den unterschied kannst du mit folgendem testcode sehen:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
var time : integer;
procedure StartPerfCounter;
begin
  time := Gettickcount;
end;

function StopPerfCounter:string;
begin
  result:=formatfloat('0.00',(Gettickcount - time) / 1000);
end;

function isCharAtPos(s:pchar; c:char; p: integer):boolean; // ungefährliche funktion, da bei ein leerer oder zu kurzer string durch IsBadReadPtr abgefangen wird
begin
  result := false;
  if (p = 0or (s=nilthen exit;
  inc(s,p-1);
  if not IsBadReadPtr(s,1then begin
    if s^ = c then result := true;
  end;
end;

function isLastChar(s:pchar; c:char):boolean;
// achtung: funktioniert nur wenn s auf einen "richtigen" delphi-string zeigt !
begin
  result := false;
  if (s=nilthen exit;
  result := isCharAtPos(s,c,pcardinal(cardinal(s) - 4)^);
end;

function isLastCharSlow(s:pchar; c:char):boolean;
// deine variante
begin
  result := isCharAtPos(s,c,length(s));
end;

procedure TForm1.Button1Click(Sender: TObject);
var s: string;
  i : integer;
begin
  s := 'bla';
  s := s + ' blubb';
  startperfcounter;
  for i := 1 to 10000000 do
   if islastcharSlow(pchar(s),'b'then asm nop end;
  caption := stopperfcounter;
end;


procedure TForm1.Button2Click(Sender: TObject);
var s: string;
  i : integer;
begin
  s := 'bla';
  s := s + ' blubb';
  startperfcounter;
  for i := 1 to 10000000 do
   if islastchar(pchar(s),'b'then asm nop end;
  caption := stopperfcounter;
end;


_frank_ - So 08.10.06 22:32

ich hab mal unter Versionsnummer 0.2.0.9 die RC1 für die 0.3 hochgeladen.

Es wird vor der 0.3 nur noch bugfixes geben ( also testen testen testen ;) ) .
Neu sind u.a. eine automatische positionsanpassung beim einfügen in der Vorschau (wenn durch einfügen die Komponente im neuen Parent nicht mehr sichtbar ist), eine Klassenersetzung (z.B. TNT-Controls im Preview durch die Standard-Komponenten darzustellen), eine löschliste für eigenschaften die mit der Ersetzung nicht mehr kompatibel sind, ein Bug beim bringtofront/sendtoback im Preview.

Hoffe, es finden sich noch Tester...

Gruß Frank


_frank_ - Do 19.10.06 14:58

hab mal einiges umgebaut (u.a. gibt es jetzt die Möglichkeit Pas-Dateien nach dem Erstellen/Ändern gleich zu öffnen).

RC2 = 0.2.0.10b

Schon jemand Bugs (in der RC1) gefunden?

Gruß Frank


_frank_ - Mi 17.01.07 18:12

ich wollte mal nachfragen, ob schon bugs in der rc2 (0.2.0.10b) gefunden wurden, da ich diese jetzt als Stable hochladen will...

Gruß Frank


Sinspin - Mi 17.01.07 18:47

ich habe D7 drauf. bei mir kommt immer die fehlermeldung das vcl30.dpl nicht gefunden wird. was hat das zu bedeuten?
... außer das ich mir D3 installieren soll.


_frank_ - Mi 17.01.07 19:12

probiere mal die dfmedit2.dpr

//edit
die vcl30 ist ein Laufzeitpackage, welches du auch von der Beta-seite runterladen kannst (wenn du das programm-Packet nimmst)

Gruß Frank


_frank_ - Fr 26.01.07 01:39

habe eine neue Stable hochgeladen, für interessierte

Gruß Frank


0xCC - Di 13.02.07 00:28

hi, deine aktuelle version stuerzt ab wenn ich folgendes dfm file oeffne, und dann auf den speichern button klicke.


_frank_ - Fr 16.02.07 01:39

hab mir das ganze mal angeschaut und ne neue beta hochgeladen...
funktioniert jetzt mir deiner dfm :)

Gruß Frank


_frank_ - Fr 01.06.07 00:29
Titel: Re: DFM-Editor
hab nach langer Wartezeit mal eine neue Beta (0.3.0.3b)...
wesentliche Neuerung ist die Komponenten-Palette für den Design-Modus. Würde mich sehr über Beta-Tester freuen...
die Einträge können auch mit images hinterlegt werden (hab noch keine Antwort von Borland bezüglich der Delphi-Toolbar-Icons, somit sind diese nicht mit drin). Es exisitert aber eine images_.bmp, welche (wenn der unterstrich entfernt wird) von DFM-Edit verwendet wird.
Wenn soweit keine Probleme weiter aufkommen, werde ich noch den Menü-Editor versuchen einzubauen...

Frank


_frank_ - Di 19.06.07 04:48

Moin,
ich schmeiß mal eine neue Beta (0.3.0.4b) in die Runde ;)
ich hab die Komponenten-Palette etwas verbessert (Toolbar-Images, SubControl-Check).
der Objektinspektor hat jetzt einen (eigentlich 3) Inplace-Editor (wird noch erweitert) und
es existiert ein einfacher Menü-Editor (Zugriff über Kontextmenü von Treenode eines TPopupMenu/TMainMenu).

weiterhin gibt es eine 3. Projektdatei (dfmedit_nopackage.dpr) um eine binary zu erstellen, welche keine packages benötigt/unterstützt.

würde mich sehr über Feedback freuen...natürlich auch Bug-Reports (bitte bugs.txt beachten).

Gruß Frank


_frank_ - So 24.06.07 15:15

hat denn schon jemand Bugs gefunden? *push*

für diejenigen, die ein Hauptmenü einer Toolbar vorziehen (oder auch beides haben wollen), hab ich jetzt ein solches TMainMenu eingebaut.
weiterhin hab ich tab und shift+Tab im OI eingebaut, den Menü-Editor um die default-eigenschaft ergänzt und die Hilfe bisschen aktualisiert.

die bugs in TCollection-Items und beim speichern hab ich schon gefixt (denke ich). weiterhin hab ich noch eine Datei-History und eine Möglichkeit geschafen, Eigenschaftsnamen zu ändern (sinnvoll in Verbindung mit <replace>, z.b. hat TTntCombobox eine eigenschaft Items.Widestrings, dese kann man durch Items.Strings ersetzen, wenn man dieses Control als TCombobox darstellt).

villeicht finden sich noch tester ;)

Gruß Frank


_frank_ - Mo 30.07.07 16:39

Aufgrund der Tatsache, dass ich die aktuelle beta soweit als Stable betrachte, bitte ich nochmals um einige Beta-Tester. *push*

sollten sich binnen der nächsten 2 Wochen keine Bugs mehr finden und ich die französische Übersetzung zeitnah bekommen steht dem release eigentlich nichts mehr im Wege.

dann kann ich mich voll und ganz auf die Entwicklung/Einbindung der Background-Klasse konzentrieren :)

Gruß Frank


0xCC - Mi 19.03.08 20:16
Titel: reusability
hi frank, ich wollte mir grade ein kleines tool basteln, das, basierend auf deinen quellen, per kommandozeile ein bin-dfm in ein text-dfm umwandelt.
dies gestaltet sich allerdings schwierig, da deine units nicht wirklich wiederverwendbar sind:
du verweist z.b. innerhalb der dfmparse_u auf main.pas, was im prinzip eine verwendung ausserhalb des programmes unmöglich macht, wenn man nicht alles neu coden bzw umschreiben will. auch die verwendung von ttreeviews und tstringlists als funktionsparameter halte ich nicht für geglückt. es dürfte auch relativ fehleranfällig sein.

hier mal eine funktion, wie sie brauchbarer wäre:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
function file2string(filename : string): string;
var f: Thandle;
    fs:dword;
    dwRead:DWORD;
begin
    result:='';
    f:=CreateFile(@filename[1],GENERIC_READ,FILE_SHARE_READ or FILE_SHARE_WRITE,nil,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);
    if f <> INVALID_HANDLE_VALUE then begin
       fs:=GetFileSize(f,nil);
       if fs <> 0 then begin
         setlength(result,fs);
         readfile(f,pointer(result)^,fs,dwRead,nil);
       end;
       closehandle(f);
    end;
end;

function LoadDFMFile(filename:string;var DestString: String):boolean;
var 
  fc  : string// filecontent in a stringbuffer.  
  buf : string;
begin
    fc := file2string(filename);
    buf:=lowercase(copy(fc,1,6));
    result:=(buf <> 'object'and (buf <> 'inline'and (buf <> 'inheri');
    if result then
    begin
      ObjectResourceToText(fc, deststring)
    end else
      deststring := fc;

end;

//und hier mein programmgerüst (ich will eigentlich sowenig units wie möglich einbinden damit die exe-grösse schlank bleibt:
program dfmconvert;
// saves a binary DFM file as text.
// based on DFMEDIT by frank wunderlich
{$APPTYPE CONSOLE}

uses
  fastmm4,
  windows,
  stringtools,
//  functions_u,
 // dfm_parse_u,
  SysUtils;

procedure Showsyntax;
begin
  writeln('DFMConvert 1.0'#13#10'Converts a binary DFM to text-dfm.'#13#10'File will be replaced after *.bak file is written'#13#10'Syntax: DFMConvert filename.dfm');
  halt(0);
end;

procedure InvalidDFM;
begin
  writeln('invalid or non-binary input file');
  halt(1);
end;


var
  s: string;
  bin: boolean;

begin
  if (paramcount = 0or (not fileexists(paramstr(1)) then begin
    showsyntax;
  end;
  s := file2string(paramstr(1));
  if (length(s) = 0or (s[1] <> #255then begin
    InvalidDFM;
  end;
  createbackup(paramstr(1));
  bin:=dfmparse_u.loaddfmFile(fn,sl); // <- grummel
  if not bin then InvalidDFM;
  dfmparse_u.SaveDFMFile(fn,sl,false); // <- grummel 2


end.


nachtrag: hat sich erledigt... die magie wird vom befehl ObjectResourceToText erledigt.

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
program dfmconvert;
// saves a binary DFM file as text.
{$APPTYPE CONSOLE}

uses
  fastmm4,
  windows,
  classes,
  SysUtils;

procedure Showsyntax;
begin
  writeln('DFMConvert 1.0'#13#10'Converts a binary DFM to text-dfm.'#13#10'File will be replaced after *.bak file is written'#13#10'Syntax: DFMConvert filename.dfm');
  halt(0);
end;

procedure InvalidDFM;
begin
  writeln('invalid or non-binary input file');
  halt(1);
end;


var
  c : char;
  f : file of char;
  ins : TFileStream;
  ous : TMemoryStream;

begin
  if (paramcount = 0or (not fileexists(paramstr(1))) then begin
    showsyntax;
  end;
  assignfile(f,paramstr(1));
  reset(f);
  if filesize(f) = 0  then c := #0 else read(f,c);
  closefile(f);
  if (c <> #255then InvalidDFM;
  CopyFile(pchar(paramstr(1)),pchar(paramstr(1) + '.bak'),false);
  ins := TFileStream.Create(paramstr(1),fmOpenRead or fmShareDenyNone);
  ous := TMemoryStream.Create;
  ObjectResourceToText(ins, ous);
  ins.Free;
  ous.SaveToFile(paramstr(1));
  ous.Free;
end.