![]() |
Konvertiere TP7 zu Delphi
Liste der Anhänge anzeigen (Anzahl: 1)
Moin Leute :hi:
Wie schon länger angekündigt möchte ich nun meine Konvertierung von Turbo-Pascal 7.0 in Delphi vorstellen. Das ist mein Meilenstein in der DP. Es gibt bestimmt noch so ein paar arme Schweine wie ich, die so ein altes grottiges Ding pflegen müssen. Für mich war es eine Menge Arbeit, bis meine Anwendung entlich als Konsole lief. Ich erzähle mal nicht von den vielen Stolpersteinen sondern von dem Weg, den man gehen muss. Es lohnt sich auf jeden Fall. Unter Delphi hat man die ganzen Begrenzungen nicht, die unter DOS so waren. Reichlich Speicher, deutlich näher an 32 Bit, den Drucker direkt ansprechen ohne Zwischenprogramm, uswusf. Der erste Akt: FindFirst/FindNext/FindClose Hätte ich die ganzen Stellen mit Compilerschaltern versehen, wäre ich heute noch dabei. Also habe ich alle Stellen so umgestellt, dass fast alles über dieses Objekt läuft.
Delphi-Quellcode:
In diesem kleinen Anfang merken einige von euch, wohin der Hase läuft. Es gibt ein paar Stellen dann nur noch wo man mit Kompilerschaltern arbeiten muss.
type
TDirInfo = object {$IfDef Win32} private FDoFindClose : Boolean; public {$EndIf} DirInfo : TSearchRec; constructor Create; function FindFirst( aDatei : PathStr; aAttr : Word):Boolean; function FindNext:Boolean; destructor Free; end; constructor TDirInfo.Create; begin {$IfDef Win32} FDoFindClose := False; {$EndIf} end; function TDirInfo.FindFirst( aDatei : PathStr; aAttr : Word):Boolean; {$IfDef Win32} var lEc : Int32; {$EndIf} begin {$IfDef Win32} if FDoFindClose then SysUtils.FindClose(DirInfo); lEc := SysUtils.FindFirst(aDatei,aAttr,DirInfo); if lEc = 0 then begin FDoFindClose := True; FindFirst := True; end else begin FindFirst := False; end; {$Else} Dos.FindFirst(aDatei,aAttr,DirInfo); FindFirst := DosError = 0; {$EndIf} end; function TDirInfo.FindNext:Boolean; {$IfDef Win32} var lEc : Int32; {$EndIf} begin {$IfDef Win32} lEc := SysUtils.FindNext(DirInfo); FindNext := lEc = 0; {$Else} Dos.FindNext(DirInfo); FindNext := DosError = 0; {$EndIf} end; destructor TDirInfo.Free; begin {$IfDef Win32} if FDoFindClose then SysUtils.FindClose(DirInfo); {$EndIf} end; Die Variable InOutRes gibt es unter Delphi nicht. Hier gibt es aber die Prozedur SetInOutRes die ich dann überall verwende. So ist sie dann im TP eingebunden. Das Umstellen des Quelltextes von InOutRes auf SetInOutRes übernimmt dann die Konvertierung. Dazu später mehr.
Delphi-Quellcode:
Der zweite Akt: Fail in Konstruktoren
{$IfNDef Win32}
procedure SetInOutRes( aEc : Int_Int); begin InOutRes := aEc; end; {$EndIf} Ein Konstruktor darf nur aus Speichermangel in das Fail laufen. Ich hatte das für allmöglichen Kram genutzt. Das wird jetzt reine Handarbei. Ich bin einfach dabeigegangen und habe alle Stellen mit "{ok}" markiert, wo das Fail durch einen Speichermangel ausgeführt werden könnte. Unter Delphi passiert das eh nicht, da gibt es kein MemAvail und MaxAvail. Unter Kompilerschalter habe ich die Funktionen selbst geschrieben und einfach Max(Int32) übergeben. Die nativen Typen erkläre ich gleich. Alle anderen Stellen müssen so überarbeitet werden, dass das Fail rausfliegt. Einfach den Konstruktor mit weniger Parameter aufrufen und eine weitere Funktion mit der extrahierten Arbeit beauftragen. Ja, das kann verdammt viel werden und lange dauern. Der dritte Akt: Auf Funktionalität verzichten Ich habe Modemgeschichten und Grafikausgaben einfach deaktiviert. Falls jemand diesen Teil noch braucht, ist das kein Problem. Ich kann mein FOS als DOS- und Win32-Applikation kompilieren. Wer den alten "Mist" noch braucht, soll das DOS-Programm starten. Beim deaktivieren Kompilerschalter verwenden! Der vierte Akt: Die Hauptdatei In der Hauptdatei sind nur noch die Uses-Anweisung, ein Include-Aufruf und im Programmblock der Start der Anwendung. Auf diese Art wird dann später auch die DPR erstellt. So sieht jetzt die PAS-Datei aus:
Delphi-Quellcode:
Und ein Einblick in die DPR-Datei:
program FOSdos;
{$M 65500,0,655360} uses FosOver,Overlay, FosChars,Crt,Dos,Fosmenue,Fostast,Fosfiles,Fosunter, Fosan,Fosbuch,Foscheck,Fosmanam,Fospersm,Fosterm,Fosakt,Fosmastm, Fostunde,Fosgrund,FosGrun2,Foslizen,FosMBox,FosRout,FosDyna,FosBase, FosRout2,FosRout3,FosObj,FosAbsch, FosMUnit, FosTEdit,FosBrows,FoStatik, FosInput,Netzwerk,FosGlob,FoSchon,FosMonov,FoSerie,FosBitL, FosDebug, FosDump, FosRes,fosdatum,FosDialo,FoSicher,FosPrint,FosBruch, FosCMD,FoShell,FosTime,FosMask,Fos2dStr,FosKMenu,FosArchi,FosAn2, FosWork,FosXMS,FosNInfo,Drucken,Killer,PipeStr,DruckObj,Vorbest, HeapUse, {$IFNDEF DPMI} ShowHeap, {$ENDIF DPMI} Einstell,KeyLoop,Kasse,Connect,Mouse, Vorlagen,BestWerb,Ortsteil,Bondruck,Kalender,Tastatur,RecBaseU, FosMPack; {$O ShowHeap.Pas} {$O GDISupp.Pas } {$O FosLZSS.Pas } {$O FORMULAR.PAS} {$O FOSDIALO.PAS} {$O FOSOBJ.PAS } {$O FosInput.Pas} {$O FosWork } {$O FoSerie.Pas } {$O FOSABSCH.PAS} {$O FOSAKT.PAS } {$O FOSAN.PAS } {$O FOSAN2.PAS } {$O FOSARCHI.PAS} {$O FOSBASE.PAS } {$O FosBitL.Pas } {$O FOSBROWS.PAS} {$O FosBruch.Pas} {$O FOSBUCH.PAS } {$O FOSCHECK.PAS} {$O FosCMD.Pas } {$O FosDebug.Pas} {$O FosDump.Pas } {$O FoShell.Pas } {$O FoSicher.Pas} {$O FOSLIZEN.PAS} {$O Netzwerk.Pas} {$O FOSMANAM.PAS} {$O FOSMASTM.PAS} {$O FOSMBOX.PAS } {$O FosMCons.Pas} {$O FOSMENUE.PAS} {$O FosMHelp.Pas} {$O FosMonoV.Pas} {$O FosMPack.Pas} {$O FosMUnit.Pas} {$O FOSPERSM.PAS} {$O FosPrint.Pas} {$O FOSTAPEL.PAS} {$O FoStatik.Pas} {$O FosTEdit.Pas} {$O FOSUNTER.PAS} {$O FosMask.Pas } {$O Fos2dStr } {$O FosKMenu } {$O FosXMS } {$O FosNInfo } {$O Drucken } {$O Killer } {$O DruckObj } {$O Vorbest } {$O Einstell } {$O Formular } {$O Kasse } {$O Connect } {$O Mouse } {$O Vorlagen } {$O BestWerb } {$O Ortsteil } {$O Tastatur } {$O Kalender } {$O KMenu2 } {$O Bondruck } {$O FosRes } {$O FOSFILES.PAS} {$O Fostunde } {$O PipeStr } {$I Fosystem.Inc} begin Haupt; end.
Delphi-Quellcode:
Schön zu sehen ist die Prüfung auf mindestens einen installierten Drucker und dass GetTickCount nicht überläuft. Auch schön zu sehen, wie ich mit Umlauten umgehe. Die Konvertierung stellt alle Sonderzeichen als Konstante dar.
program Fosystem;
{$APPTYPE CONSOLE} uses {$IfDef Win32}SysUtils,FosDelphi,{$EndIf} BestWerb in 'BestWerb.pas', Bondruck in 'Bondruck.pas', Connect in 'Connect.pas', Crt in '.\Units\Crt.pas', Dos in '.\Units\Dos.pas', Drucken in 'Drucken.pas', DruckObj in 'DruckObj.pas', Einstell in 'Einstell.pas', Formular in 'Formular.pas', Fos2dStr in 'Fos2dStr.pas', Fosabsch in 'Fosabsch.pas', Fosakt in 'Fosakt.pas', Fosan in 'Fosan.pas', Fosan2 in 'Fosan2.pas', Fosarchi in 'Fosarchi.pas', Fosbase in 'Fosbase.pas', FosBitL in 'FosBitL.pas', FosBrows in 'FosBrows.pas', FosBruch in 'FosBruch.pas', Fosbuch in 'Fosbuch.pas', Foschars in 'Foschars.pas', Foscheck in 'Foscheck.pas', FoSchon in 'FoSchon.pas', FosCMD in 'FosCMD.pas', FosDatum in 'FosDatum.pas', FosDebug in 'FosDebug.pas', FosDialo in 'FosDialo.pas', FosDyna in 'FosDyna.pas', FoSerie in 'FoSerie.pas', Fosfiles in 'Fosfiles.pas', FosGlob in 'FosGlob.pas', FosGrun2 in 'FosGrun2.pas', FosGrund in 'FosGrund.pas', FoShell in 'FoShell.pas', Fosicher in 'Fosicher.pas', FosInput in 'FosInput.pas', FosKMenu in 'FosKMenu.pas', Foslizen in 'Foslizen.pas', Fosmanam in 'Fosmanam.pas', FosMask in 'FosMask.pas', Fosmastm in 'Fosmastm.pas', FosMBox in 'FosMBox.pas', Fosmenue in 'Fosmenue.pas', FosMonoV in 'FosMonoV.pas', FosNInfo in 'FosNInfo.pas', FosObj in 'FosObj.pas', Fospersm in 'Fospersm.pas', FosPrint in 'FosPrint.pas', FosRes in 'FosRes.pas', FosRout in 'FosRout.pas', FosRout2 in 'FosRout2.pas', FosRout3 in 'FosRout3.pas', FoStapel in 'FoStapel.pas', Fostast in 'Fostast.pas', FoStatik in 'FoStatik.pas', FosTEdit in 'FosTEdit.pas', Fosterm in 'Fosterm.pas', FosTime in 'FosTime.pas', Fostunde in 'Fostunde.pas', Fosunter in 'Fosunter.pas', FoSWork in 'FoSWork.pas', GDISupp in 'GDISupp.pas', Graph in '.\Units\Graph.pas', HeapUse in 'HeapUse.pas', Kalender in 'Kalender.pas', Kasse in 'Kasse.pas', KeyLoop in 'KeyLoop.pas', Killer in 'Killer.pas', KMenu2 in 'KMenu2.pas', Mouse in 'Mouse.pas', Netzwerk in 'Netzwerk.pas', Ortsteil in 'Ortsteil.pas', PipeStr in 'PipeStr.pas', Printers, RecBase in 'P:\RecBase\RecBase.pas', RecBaseU in 'RecBaseU.pas', SListDOS in 'SListDOS.pas', Statik2 in 'Statik2.pas', Tastatur in 'Tastatur.pas', Vorbest in 'Vorbest.pas', Vorlagen in 'Vorlagen.pas', Windows, XmsEmu in '.\Units\XmsEmu.pas'; {$I Fosystem.Inc} var lCount : Int32; lTicks : DWord; begin lCount := Printer.Printers.Count; if lCount > 0 then begin lTicks := GetTickCount; if lTicks < 3974400000 then {46 Tage * 24 Stunden * 60 Minuten * 60 Sekunden * 1000} begin try Haupt; except on E:Exception do begin MessageDlg(symStop ,'Exception aufgetreten (' + E.ClassName + '):'#13 +BreakStrToStrList(AnsiToAscII(E.Message),70,255) ,mdxEnter + mdxEsc ,mdpMitte); end; end; end else begin WriteLn('Der Rechner l' + _aumlk + 'uft schon l' + _aumlk +'nger als 45 Tage. Bitte neu starten.'); Write('Enter dr' + _uumlk + 'cken...'); ReadLn; end; end else begin WriteLn('Es ist kein Drucker unter Windows installiert!'); Write('Enter dr' + _uumlk + 'cken...'); ReadLn; end; end. Der fünfte Akt: XMS-Speicher Unter Delphi werden die DOS-Funktionen nicht unterstützt. Da ich über ein Objekt den Speicher verwendet habe, arbeitet mein Delphi-Objekt einfach mit Heap-Speicher und tut so, als ob es XMS sein. Dem Programm ist das egal, hauptsache es läuft wie vorher. So, grobe Vorarbeit ist getan. Mit den Umstellungen und vielleicht ein paar Erneuerungen kann man locker ein Release ausliefern, das Ding läuft genauso wie vorher. Verwendete Typen: Das Dilemma kennen sicherlich einige, die Source für TP und Delphi schreiben mussten. Ich habe das mit klaren Typen umschifft.
Delphi-Quellcode:
Jetzt höre ich schon einen Aufschrei! Ist der bekloppt? Weiß der, wie oft diese Typen verwendet wurden?
{$IfDef Win32}
Int16 = SmallInt; Int32 = Integer; Word_Int = Integer; Int_Int = Integer; Int32_Cardinal = Cardinal; {$Else} Int16 = Integer; Int32 = LongInt; Word_Int = Word; Int_Int = Integer; ShortString = string; Int32_Cardinal = LongInt; TSearchRec = SearchRec; TFileRec = FileRec; TextFile = Text; {$EndIf} KLAR! Die Umstellung übernimmt die Konvertierung. Schon sieht das ganze viel geschmeidiger aus. Es bedarf natürlich eine Menge Handarbeit. SetInOutRes() will in Dos Int16 und in Delphi Int32 haben. Über den Typ Int_Int(vor dem Unterstrich DOS, hinter dem Unterstrich Delphi) ist das simpel gelöst. Was ist mit den DOS-Units? Crt.pas gibt es im Netz. Wo ich meine gefunden habe, weiß ich nicht mehr. In der Unit steht das drin:
Delphi-Quellcode:
DOS.pas habe ich selbst aufgesetzt:
(*-------------------------------------------------------------------------
Portions Copyright (c) 1988-2003 Borland Software Corporation Portions Copyright (c) 2006-2009 W.Ehrhardt Disclaimer: =========== This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. If you use this code, please credit me and keep the references to the other authors and sources. Description: ============ This unit is a light version of Will DeWitt's code with several bug fixes (especially readkey, extended key codes etc). Will's 'unit was based heavily off of the Borland CBuilder 5 RTL'. Because of the unclear licence status of Will's unit, my CRT source is not under zlib license. Anyway, in this unit the code from Will/Borland is radically rewritten and rearranged. The guiding requirement was to make it almost BP7 compatible. The basic idea for separate hardware/software sound support is from Rudy Velthuis' freeware console, but the implementation is different. The supported keys for line editing are from BP7 (^A, ^H, ^D, ^F, ^M, ^S, ^Z), the paradigm shift from readkey to keypressed for doing the dirty work is from FP. The key codes / translations / functionalities were taken from the Phoenix BIOS book and a test program compiled with BP7. There is still work to be done for some rare special extended keys, but this work is delayed to bugfixes or problem reports. -------------------------------------------------------------------------*)
Delphi-Quellcode:
Graph.pas ist bei mir voll das fette Teil:
unit DOS;
interface type PathStr = string[79]; DirStr = string[67]; NameStr = string[8]; ExtStr = string[4]; implementation begin end.
Delphi-Quellcode:
Die sollte man vor dem ersten Kompilieren unter Delphi anlegen. Ich hatte zum Anfang überall die Aufrufe mit Kompilerschalter versehen, bis ich auf die Idee mit den leeren Units gekommen bin.
unit Graph;
interface implementation end. Ich hänge die Konvertierung einfach mal komplett dran. Ich habe zum Anfang von einem Ordner in einen anderen Konvertiert. So konnte ich immer wieder in beiden Systemen kompilieren und Stück für Stück nacharbeiten. Unter TP ist dabei das führende System. Ich habe auch mal ein Stück unter Delphi programmiert. Wenn das dann in Ordnung war, habe ich das gleich in den Dosen-Source eingebaut, um die Konsistenz zu wahren. Ich wünsche Viel Spaß bei der Umstellung Stefan |
AW: Konvertiere TP7 zu Delphi
Also ich würde sowas neu schreiben.
Mit Datenbankanbindungen, schönen Dialogen usw. Lieber so, als eine Uraltkrücke mit Klimmzügen als 'Delphi'-Anwendung verhunzen. Wer soll das den pflegen? |
AW: Konvertiere TP7 zu Delphi
zu der leeren Unit Graph:
Da gibt es eine einfachere Möglichkeit, in den Projektoptionen wird einfach ein weiterer Unit-Alias eingetragen
Code:
Wenn der Compiler auf die Klausel
...=Windows;Graph=System
Delphi-Quellcode:
tritt,
uses Graph;
dann bindet er stattdessen die Unit System ein. |
AW: Konvertiere TP7 zu Delphi
Danke für den Tip sx2008. Das schaue ich mir mal an.
@alzaimar Klar würde ich mein Projekt auch ganz neu schreiben. Das ist jetzt auch nichts entgültiges, sondern nur um Probleme mit XP64 und 7 zu umgehen. Mein Programm besteht im Hauptteil aus über 3 MB Sourcecode. Wer ein DOS-Programm pflegt, kann nachvollziehen, dass man so ein Projekt nicht "mal eben" neu schreibt. Ich werde es neu schreiben - in Java mit multipler Datenbankanbindung. Bis das Teil fertig ist, springen mir nur alle Kunden auf dem Dach rum. Ich möchte jetzt nicht für Konsolenanwendungen werben! |
AW: Konvertiere TP7 zu Delphi
Du tust dir keinen Gefallen, das so zu machen, wie geplant. Schreibs neu ! Und glaube mir : ich weiss, wovon ich rede ! Mache Dir mal folgendes klar : grafische Benutzeroberfläche (=Windows) und zeichenbasierte (=DOS/Konsole), das sind zwei paar Schuhe. Ungefähr vergleichbar mit Gunnistiefeln und Balettschühchen. Versuche das mal in Einklang zu bringen. 8-)
Zitat:
|
AW: Konvertiere TP7 zu Delphi
Zitat:
|
AW: Konvertiere TP7 zu Delphi
Ja, das mit den 64 Bit war der Anstoß, überhaupt die Konvertierung zu machen. Glaubt mir, ich freue mich darauf den alten Mist :kotz: in die Tonne kloppen zu können.
Ob der Sourcecode dann gut brennt? :feuerchen: :dancer: <Feuertonne> :dancer2: |
AW: Konvertiere TP7 zu Delphi
"Eingabeaufforderung" ist da nicht mehr vorhanden ? :shock: Ein Grund mehr, alles komplett umzuschreiben. Und er soll direkt anfangen. Ich weiss, dass das viel Arbeit ist, aber es nützt alles nichts. Ich würde nicht zuviel Zeit investieren, um das Programm irgendwie "passend" zu machen. 8-)
|
AW: Konvertiere TP7 zu Delphi
PS: Sowas wie
Delphi-Quellcode:
ist eigentlich auch nicht nötig und ich finde sowas eher unübersichtlicher/fehleranfälliger, als nur
MyUnit in 'MyUnit.pas',
Delphi-Quellcode:
.
MyUnit,
Und absolute Pfade ala
Delphi-Quellcode:
sind doch irgenwie nicht so praktisch?
RecBase in 'P:\RecBase\RecBase.pas',
Schade daß wir keinen 64-Bit-Compiler haben, sonst könntest du es gleich noch weiter hochprotieren. :roll: |
AW: Konvertiere TP7 zu Delphi
Zitat:
Was soll fehlendes 16-Bit Subsystem mit der Eingabeaufforderung zu tun haben? |
Alle Zeitangaben in WEZ +1. Es ist jetzt 08:38 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz