How to convert OWL/BP7 application to Delphi? - delphi

Which tool/approach would you suggest to convert of a large 16bit Windows GUI application, written in old Borland Pascal 7 / OWL, to Delphi?
Understanding the pretty heavy differences between OWL and VCL, as well as the differences between the pointer manipulations in 16bit pascal and the state-of-art using of strings and objects in Delphi - are there any ways/tools which could help to avoid almost complete rewrite of the application?

I think you need to determine;
a) how much of the code is to do with business logic, data(base) manipulation and things like proprietary file structures, mathematical processing etc? This is stuff that might lift largely 'as-is' because it's more likely to be written in 'pascal' with much smaller, obvious elements of OWL/BP7. For instance, when I did this with an application I had a series of units that dealt with loading/saving proprietary files, stuff to calculate easter, stuff to do maths on arrays etc - all of this stuff went from BP7 to Delphi (1) with almost no changes.
b) how much of the code is to do with the GUI (and nothing else) - message loop handlers, dialog element constructors, properities of controls etc. This stuff will take a lot of work to port to Delphi and unless you can find someone with a nice line in .RES->.DFM (or similar), I think you'll be looking at building this bit from scratch. No bad thing because if it's a 16bit Windows app then you'll probably want to take the opportunity to at least make it look a bit more 'modern' anyway. I think this will be the most labour-intensive part of the project.
c) how much of the code is using stuff that you know can be done differently in Delphi, but that would work as it stands in pascal right now? This is where #BloodySmartie's point about migrating to an older version of Delphi makes sense to me. You ought to be able to port that project to something like Delphi 5/7 making obvious (and well-understood) changes to things like string manipulation. The more of this stuff that you can leave unported, the better in my view. Get something that runs and that you check basic behaviour with, and then embark on a process of refactoring/refining to make the most of Delphi as and when the resources allow it. You might have (as I did) arrays of pointers in BP7, where each pointer goes to an array of pointers which ultimately lead to an object - this was how we got around memory limitations in the 16bit Windows world. When I first ported my app, these arrays of pointers to arrays of pointers still worked fine in Delphi and I left them alone until I had the time to do something more 'Delphi-like' with the structures.
But before you do all of that - why are you porting the app? If you're porting it because you're about to make a reasonable number of changes to the app's functionality anyway, then it might really be the right time to rewrite the app. As you're rewriting in Delphi, you are still going to be able to use chunks of functions and procedures that are business-rule based anyway, so it's not necessarily a complete and total rewrite from scratch.

I guess there is no tool to support your migration but i'd try to start in an old Delphi Version like 1,2 or 3. This syntax should be much nearer on BP7 than the syntax of newer Delphi Versions.
At this time, you should first try to just bring your app logic to delphi, without any visual stuff. Then use the form designer to rebuild your GUI.
A important point you should pay attention to is that a DOS string is an ASCII-String, while the Delphi strings up to Delphi 2007 are ANSI-encoded. In Delphi 2009, the string keyword describes a unicode string.

Long-long time ago when I swapped OWL to VCL (in C++) it was just easier to write everything from scratch. There might be some code parts that don't deal with user interface and string manipulations, but otherwise it's totaly different.
In fact one of my biggest app is still in OWL, because I just don't bother to rewrite it. As long as it works, let it be.

we also had - and still have - tons of owl-applications.
so we did port the 16bit owl to 32bit owl and are therefor still developing and maintaining our owl-based applications (actually with Delphi 2007 for win32).
you may find this way easier and faster than switch to vcl.
cheers
Andrej

FrameworkPascal.com provides an effective solution with minimal changes to the original windows 3.1 code. We did it for a while but now we provide a rounded solution with 32 bit compatible OWL units. We also provide with it ODBC SQL units, MAC address based security technology and special units CRT like units which can handle code written for DOS text and graphic modes mode, mixed, with and new 32 bit graphics and targeted at Windows 32/64 GUI applications. Legacy code can be which can be compiled with OWL Windows MDI starting with model applications demos which can be quickly modified.

Related

Migration to XE5 without making change in Delphi 7 datatypes [duplicate]

Our company have a software that has been in development for over 10 years, so there are some really dated stuff in there. It's still quite functional and everything, but I see the new features on Delphi XE and it makes me want to switch. Problem is that the source code itself is over 300mb of .pas files (1gb total with components, etc).
We're using custom components, old jvcl stuff and the latest devexpress.
How hard can I expect things to be if I decide to migrate from Delphi 7 to Delphi XE?
Thank you.
The only real problem is conversion to Unicode. You should learn how Unicode support is implemented in Delphi - start from Marco Cantu White Paper: Delphi and Unicode
It is impossible to estimate the amount of work required to upgrade old applications to Unicode without knowing the actual code. If you were using string types in the standard way, the conversion would be easy. Any low-level tricks with string types (like storing binary data in strings) are now deprecated and the correspondent code should be rewritten.
Some small tools either migrate without needing to do any modifications, or just a couple of unicode fixes to get it to run.
However, if your codebase is as huge as you're explaining, you shouldn't completely rely on what anyone here is going to tell you. Just get a copy of XE and load the code. See what problems you run into to get a feel for the amount of effort it's going to take.
At this moment I've ported all of my code to XE (even old projects). I re-use the same libraries as much as possible, so once I've converted most of those, "porting" applications from Delphi 7 to Unicode Delphi's was usually merely a repetitive task to either deal with updated interfaces in the libraries, or to fix compiler errors and warnings.
Most common errors that I've encountered:
Unicode stuff. This will take 90% of the time. It's annoying if the code does a lot of low-level string handling, but most of the problems can easily be fixed by adding some typecasts.
the compiler bitches when you use c in ['a'..'z']. You're supposed to use CharInSet() for unicode strings.
If you set ShortDateFormat, you'll get a compiler warning that you should use FormatSettings.ShortDateFormat instead. In new code that's a good idea. If you're porting, just ignore it initially if you just want to get going.
Additionally, you'll probably upgrade your third party libraries to newer versions, so that you don't have to port those yourself. It's not uncommon for those to have changed their interfaces or workings, so i'd download some trial versions of those to see what has been changed.
You mentioned SQL in one of your response comments... Does your database support unicode? If not, you could be in for a lot of work. You may need to convert databases on-the-fly or make a conversion tool for your users. You may need to upgrade the database or even switch to something else. For example, DBISAM is not unicode capable, but the vendor makes ElevateDB which is. The transition is not trivial. And some other libraries like Hyperstring, written largely in assembler, are another sore spot.
I've been doing quite a few of those conversions.
You should prepare by making your current code base testable. Preferably using automated unit tests, but at least have a good end-user testing plan.
Then you should plan for the biggest portion: the Unicode conversion for both your app and your database.
Finally there are less major, but potentially very time consuming aspects:
if you are using BDE, this is the time to get rid of it
the Delphi XE is more strict than Delphi 7
3rd party library versions that bump up quite a few versions and are usually far less backward compatible than the VCL is
When you have ported it, it is time to change things: since you have seen the whole code base, now you know where your weak points are, so you can start refactoring them and get a better app than you had before.
My project is about a million lines of code and I recently ported from CB9 to XE. To cut down on the amount of work I first rewrote a lot so I was no longer dependant on 3rd party component packs, then carefully went over everything string related (unicode) and only then moved to XE. The preparation was a lot of work, the actual port was relatively easy.
It is definitely a challenge for this MIGRATION to be executed. But need good PLANNING!
We first need to find all the possible components which also needs to be migrated along with the Code. If there are 3rd party components used in Delphi7 project which are not available then its quite complicated to get further on.
Secondly, the other type conversion related to Unicode, which is quite easy.
And finally ofcourse we need to get other supporting libraries, BDE, and Database Adapaters in place.
For Rich User Interface, Delphi FireMonkey can be used.
Delphi is getting better and better as it has now support from Desktop to Web to Mobiles application development.

How to handle legacy app?

I have inherited a legacy app written in C++ (VS2003) MFC that was not updated in years.
I have limited experience in C++, being mainly a Delphi developer. All other apps of the company are written in Delphi.
Going forward, I see a few choices:
1) Keep the app as is and become a C++ MFC developer. But I don't like the idea of using an outdated technology (MFC) for years to come, trying to keep up with new Windows versions and UI standards. It somehow feels like making several steps backwards and I don't think this is the best way to go (?)
2) Convert the app to any modern UI technology offered with C++ and become a C++ developer, but at least using modern technology. Might be a lot of work, not sure.
3) Rebuild the app from scratch in Delphi, where I will be a lot more productive thinking about the future. It's a lot more work right now, but it might pay off later.
Obviously, I personally prefer 3) but I would like to know from your experience which way is the best for the product.
It's a long term decision to make and I will have to stick with it, therefore I don't want to rush into one direction.
(I have intentionally not tagged this question as C++, trying to get answers from Delphi developers in similar situations)
EDIT:
Thanks to all for your answers.
After learning that it is possible to switch to C++ Builder with a MFC application, this seems to be the best solution.
It combines the least amount of modifications to the current app with the possibility to go forward using the VCL for future GUI improvements.
EDIT2:
It's not possible to combine MFC and VCL in one app, therefore C++ Builder won't be an option. (thanks David for pointing this out)
In general everything depends on how complex the application's logic is and what is the projected life time of the application. If it requires maintenance for another 20 years, then
I'd rewrite the UI in Delphi and move the business logic into C++ DLL (for beginning and possibly rewrite it in Delphi either). Then it can turn that the application can be maintained this way for another 10 years and relatively easily ported to other platforms if needed (less work would be required).
This is a hard question to answer generically. Can you provide any more information about your specific app? What sort of technologies does it use? How separated is the UI from underlying layers and logic?
Some general-ish points though:
Rewriting an app is generally a bad idea, for the following reasons:
It's surprisingly hard to get an accurate idea of the requirements. You're sure you know what it does (after all, it's right there in front of you!), but then you release your rewritten app and you get complains that functionality you didn't know was there is missing, that functionality is harder to access if you've changed something, etc.
It introduces bugs. The code, especially if it's old, is full of bugfixes, tweaks, etc. You will lose all that if you rewrite, especially if it's a different language and you can't reuse any code at all.
When using a different UI layer (MFC to something else) separating the UI can be very hard if the app wasn't written well in the first place. You will probably end up doing a lot of refactoring, even if you don't do a complete rewrite and simply move from MFC to 'something else'.
MFC is kept up to date (ish) - there is a MFC Ribbon control, for example, as well as modern controls and Windows 7 support. The least amount of work, probably, would be to upgrade to a modern version of Visual C++ and become a C++ developer. However, you're quite right that MFC is an old technology and is unpleasant to use, not only because of its design, but also because modern form designers etc are great to use.
You're a Delphi developer. Without rewriting the entire thing, you could consider migrating to C++Builder. Consider this:
You can use old versions of MFC with C++Builder. I've never done this, since the VCL is miles ahead, but it's possible and there are a number of people who do it. Check out this forum, for example. (Credit for that link: this thread.)
Once you have your app compiling and working with C++Builder, you can start migrating to the VCL. As a Delphi developer you'll find using this, even with C++, very familiar. It's the same form designer of course, and using it from C++ is pretty simple - it's a different language but code is often line-for-line translatable. Everything you're used to (DFM files, units, event handlers, etc) all translate.
Not only that, but Delphi code can be used in C++ projects. Just add the units to the project, and in your C++ code include the auto-generated unitname.hpp file. You can't (easily) use C++ code from Delphi, but you could create new modules in Delphi and use them from C++. As you do this, more and more of your app will slowly become Delphi code - ie, you don't need to rewrite in a different language all in one go.
As a Delphi developer, I'd suggest going the C++Builder route. Get it working with MFC, and then migrate your windows to the VCL. At that point, you could start rewriting modules in Delphi, or you may find yourself comfortable enough in C++ to continue developing as is.
Edit: I noticed in a reply above you like the idea above of making it a C++ DLL. The link I gave a paragraph or two above of using C++ object from Delphi might be more applicable than I thought. It would fit the RAD Studio (mix of C++ and Delphi) method as well.
Keeping the app as is, tying you to MFC, is likely not very productive - You'll need to learn a GUI toolkit you'll most likely never use for something else (Delphi is great for GUI, MFC doesn't even come close IMO), in addition to a new language.
That leaves you with the choice of rewriting it in a somewhat unfamiliar language using an unfamiliar GUI toolkit, which'll take a lot more time than rewriting it in a familiar language using a familiar GUI toolkit. So you should just get started porting this to Delphi.
Rewriting C++ code in Delphi isn't as easy as you think. A better way to rewrite it is by just redesigning it from scratch, without looking at the old code. Feel free to look how the old application worked, so you can rebuild it. Just don't look at the code. That way, you should get a more modern result.
Of course, if you use the RAD Studio then you have both the C++ as Delphi compiler, thus it should be able to continue to develop the C++ application, although this means you have to learn C++. Then again, any good programmer should be able to just move to another programming language and learn to use it within 2 weeks to a month. C++ can be complex but still, learning C++ and then maintaining the legacy app should take a lot less time than a complete rewrite.
Do keep in mind that any generic C++ application should be able to be compiled for any platform, although the MFC will probably restrict this to just Windows. Still, it's a language that has an even better backwards compatibility than Delphi!
But to keep in mind, will this app run on a different platform in the future? Should it become a .NET application? Or run on Linux? Should it support tablet computers? Android? Your choices today might be outdated again in two years. And since Delphi has a bit uncertain future right now, mostly because C#/.NET became so popular, you might have a more safe bet with C++. Try to replace the MFC libraries with a more modern UI technology, preferably one that's available for multiple platforms, and think very, very well about the future usages of this application.
In general I'd say:
If it's a tiny tool application, and it takes just a couple of days to do a full rewrite: go for it. Don't waste your time creating dll wrappers or to interface with the existing code in other ways. Just do a full rewrite and be done with it.
Otherwise: you'll probably be making changes in one specific area of the application at the time only. Unless the code is a complete spaghetti, you could even get away with making some local changes without fully understanding the implementation details of the rest of the code.
In any case, you need to invest some time into understanding the application and its language + frameworks.
You have a great opportunity to learn C++ and MFC. Take advantage of it. When Delphi goes astray you will have the required knowledge to keep on coding with a language that won't go away so easily, and you can even broaden your development horizons to areas Delphi (and C++ Builder) will never reach. MFC is no more outdated than the VCL is (although I agree the original design is worse).
Good UI programming has nothing to do with the ability to drop controls on a form visually. Many great applications are not built that way. Actually, trying to rewrite it in Delphi could bring you issue in the future, as long as Embarcadero delivers slowly, and without a credible roadmap.
I recommend
1) Keep the app as is and become a C++ MFC developer. But I don't like the idea of using an outdated technology (MFC) for years to come, trying to keep up with new Windows versions and UI standards. It somehow feels like making several steps backwards and I don't think this is the best way to go (?)
Since MFC is well supported and keeps going with the time. MFC is also a what-you'd-call intrusive framework, meaning that the framework dependencies are usually not easily refactored. (The author of CPPDepend published some nice stats on that IIRC, but I can certainly vouch for this from my own experience with large MFC applications).
If you're gonna rewrite to any modern UI framework, don't code the UI in C++ (judging from the fact that Delphi is an option, it is not about realtime visualizations or something like that).
(I'll unask the unasked question here: I you're gonna rewrite, XXXXXXXXXXXXX?) please gentle(wo)men, let's not do the flame
Does the app come with a descent amount of automated tests? If not you're pretty much stuck with option 1 and hope for the best. If there are many tests you can do a lot more with the code without breaking all kinds of things you didn't know were there.

How hard is it to migrate a project from Delphi 7 to Delphi XE?

Our company have a software that has been in development for over 10 years, so there are some really dated stuff in there. It's still quite functional and everything, but I see the new features on Delphi XE and it makes me want to switch. Problem is that the source code itself is over 300mb of .pas files (1gb total with components, etc).
We're using custom components, old jvcl stuff and the latest devexpress.
How hard can I expect things to be if I decide to migrate from Delphi 7 to Delphi XE?
Thank you.
The only real problem is conversion to Unicode. You should learn how Unicode support is implemented in Delphi - start from Marco Cantu White Paper: Delphi and Unicode
It is impossible to estimate the amount of work required to upgrade old applications to Unicode without knowing the actual code. If you were using string types in the standard way, the conversion would be easy. Any low-level tricks with string types (like storing binary data in strings) are now deprecated and the correspondent code should be rewritten.
Some small tools either migrate without needing to do any modifications, or just a couple of unicode fixes to get it to run.
However, if your codebase is as huge as you're explaining, you shouldn't completely rely on what anyone here is going to tell you. Just get a copy of XE and load the code. See what problems you run into to get a feel for the amount of effort it's going to take.
At this moment I've ported all of my code to XE (even old projects). I re-use the same libraries as much as possible, so once I've converted most of those, "porting" applications from Delphi 7 to Unicode Delphi's was usually merely a repetitive task to either deal with updated interfaces in the libraries, or to fix compiler errors and warnings.
Most common errors that I've encountered:
Unicode stuff. This will take 90% of the time. It's annoying if the code does a lot of low-level string handling, but most of the problems can easily be fixed by adding some typecasts.
the compiler bitches when you use c in ['a'..'z']. You're supposed to use CharInSet() for unicode strings.
If you set ShortDateFormat, you'll get a compiler warning that you should use FormatSettings.ShortDateFormat instead. In new code that's a good idea. If you're porting, just ignore it initially if you just want to get going.
Additionally, you'll probably upgrade your third party libraries to newer versions, so that you don't have to port those yourself. It's not uncommon for those to have changed their interfaces or workings, so i'd download some trial versions of those to see what has been changed.
You mentioned SQL in one of your response comments... Does your database support unicode? If not, you could be in for a lot of work. You may need to convert databases on-the-fly or make a conversion tool for your users. You may need to upgrade the database or even switch to something else. For example, DBISAM is not unicode capable, but the vendor makes ElevateDB which is. The transition is not trivial. And some other libraries like Hyperstring, written largely in assembler, are another sore spot.
I've been doing quite a few of those conversions.
You should prepare by making your current code base testable. Preferably using automated unit tests, but at least have a good end-user testing plan.
Then you should plan for the biggest portion: the Unicode conversion for both your app and your database.
Finally there are less major, but potentially very time consuming aspects:
if you are using BDE, this is the time to get rid of it
the Delphi XE is more strict than Delphi 7
3rd party library versions that bump up quite a few versions and are usually far less backward compatible than the VCL is
When you have ported it, it is time to change things: since you have seen the whole code base, now you know where your weak points are, so you can start refactoring them and get a better app than you had before.
My project is about a million lines of code and I recently ported from CB9 to XE. To cut down on the amount of work I first rewrote a lot so I was no longer dependant on 3rd party component packs, then carefully went over everything string related (unicode) and only then moved to XE. The preparation was a lot of work, the actual port was relatively easy.
It is definitely a challenge for this MIGRATION to be executed. But need good PLANNING!
We first need to find all the possible components which also needs to be migrated along with the Code. If there are 3rd party components used in Delphi7 project which are not available then its quite complicated to get further on.
Secondly, the other type conversion related to Unicode, which is quite easy.
And finally ofcourse we need to get other supporting libraries, BDE, and Database Adapaters in place.
For Rich User Interface, Delphi FireMonkey can be used.
Delphi is getting better and better as it has now support from Desktop to Web to Mobiles application development.

Is there a Delphi obfuscator that works for >= Delphi 2007

I used to use Pythia to obfuscate my D6 program. But it seems Pythia does not work anymore with my D2007.
Here's the link of Pythia (no update since early 2007) : http://www.the-interweb.com/serendipity/index.php?/archives/86-Pythia-1.1.html
From link above, here's what I want to achieve
Over the course of time, a lot of new language features were added.
Since there is no formal grammar available, it is very hard for tool vendors (including Embarcadero themselves) to keep their Delphi language parsers up at the same level as the Delphi Compiler.
It is one of the reasons it takes tool vendors a bit of time (and for Delphi generics support: a lot of time!) to update their tools, of they are update at all.
You even see artifacts of this in Delphi itself:
the structure pane often gets things wrong
the Delphi modelling and refactoring sometimes fails
the Delphi code formatter goes haywire
Pythia is the only obfuscator for the native Delphi language I know of.
You could ask them on their site if they plan for a newer version.
Personally, I almost never use obfuscators for these reasons:
reverse engineering non-obfuscated projects is difficult enough (it would take competitors long enough to reverse engineer, so the chance to lessen the backlog they already have in the first place is virtually zero)
their added value is limited when you have multi-project solutions (basically they only hide internal or private stuff)
they make bug hunting production code far too cumbersome
--jeroen
You may try UPX - Ultimate Packer for Executable). It will compress the resources and all the text entries are non-readable without de-compress first.
I don't know any good free solutions, but if you really need some protection you can always buy something like:
http://www.aspack.com/asprotect.html
or
http://www.oreans.com/themida.php

Is an update to D2010 really meaningful

I am trying to migrate my own projects to delphi 2010. But it seems to be very difficult.
I use TntControls for old projects. If I remove this library, some runtime functions must be re-implemented by myself. For instance: convert UnicodeString to a specified code page.
The "SizeOf", "Length", FillChar() still confuse me. Compiler will throw a warning, if SizeOf() should be replaced with Length(). But I have not found any idiot-safe tutorials for me.
A confusing warning, when trying to cast an AnsiString to UnicodeString. This conversation won't cause a data lose, will it?
Many code (zip, string utils, etc.) must be retested.
Too many headaches... Can someone share experience on migrating existing project from a very old delphi to delphi 2010?
conversion Unicode string to specified code page with only Delphi: Simpler than ever. Thanks to the String class ability to create a string of a desired codepage, and convert cleanly from one codepage to another.
FillChar is bytes, not characters, name is now unfortunate. Not that confusing really.
That warning is there to make you think, which it did. Job done.
Oh yes. But that retesting and re-reading has been the biggest benefit for me.
I have migrated all my projects to Delphi 2009/2010 and found the benefits included:
A. a thorough re-reading of my code brought many ways I needed to clean it up (because it's a bloated old mass of accidents and incremental code-sludge, like most RAD/delphi projects end up), few of which are purely unicode or port related, but all of which made the products better for being forced through the changes.
B. a cleaner world, with fewer third-party components. Dropping TNT, and a dozen or two third party components will make your project smaller, more orthogonal and easier to support.
C. There's no reason in porting to make it one way. None of my project ports are actually "moved" permanently into Delphi 2009/2010. They all build in both worlds just fine. I use the type UnicodeString widely in all my code wherever I need it, and I make a typedef to WideString, when compiling on Delphi 2007 or older versions.
D. The delphi 2010 ide works great on Windows Vista and Windows 7, and the language is a joy to work with. Delphi 2009 and 2010 don't crash, which Delphi 2007 and Delphi 7 often do for me.
If you don't need to support Vista and Win7, and you're 100% happy and glitch-free running TNT components, and your app doesn't make you money, then leave it where it is. If it makes you money, invest your time, and you will soon see the rewards. Delphi 2010 and 2009 are easily the best delphi versions ever, and the only major headache that remains is that the documentation has remained below the quality of Delphi 7 ever since they moved off WinHelp format help files.
If you're using Tnt and you're converting between code pages already, then yes, switching to Delphi 2010 will cause you extra work because you'll need to remove code for things that Delphi now handles intrinsically. Ultimately, your code will be simpler, but it will be a hassle to get it there in the meantime.
SizeOf, Length, and FillChar are very basic concepts that you, as a professional software developer, owe to yourself to understand. Be cognizant of whether you're dealing with character data or non-character data, and when dealing with the latter, don't use character-related types. You've got TBytes; use it. Don't use strings as byte buffers. When you want to know how many bytes you have, use SizeOf; when you want to know how many "things" you have, use Length. Generally avoid FillChar; you probably don't need it as much as you use it today anyway. Since the "char" that things are filled with is almost always zero anyway, you might consider using ZeroMemory instead. It has fewer parameters and is just as fast as FillChar, especially since Delphi supports function inlining.
The compiler warns you when converting from AnsiString to UnicodeString because it's not a simple string assignment but rather a conversion, guaranteed to allocate more memory and copy everything one character at a time. It's a performance warning, not a data-loss warning. Conversions in the opposite direction are both (even when assigning to Utf8String, which technically will never lose data from a UnicodeString, if it's filled only with valid Unicode characters). The best way to avoid the warning is to not use AnsiString in the first place. Use plain old String except for code that really does need to know what code page to encode things as.
I don't think the "retest" argument is very strong. The library code especially should have unit tests that you've been running every time you recompiled. Retesting is something you do several times a day; there's no special effort involved unless something goes wrong.

Resources