I have an application which is fully unicode compatible in Delphi 2006. I had replaced all AnsiStrings with WideStrings, replaced all VCL controls with TNT controls, and changed all string functions from AnsiStrings to WideStrings. It looks like all that work was for nothing, because I'm going to have to reverse it all. Is there anyway to Trick Delphi 2009 into thinking Widestrings are in fact UnicodeStrings?
No, there really isn't. But you won't regret the work to truly Unicode enable your application.
The TNT controls can easily be replaced with the regular VCL controls. You can do that pretty simply using the wizard from GExperts (http://www.gexperts.org) that replaces one control type with another automatically.
Then, you can change all your WideString declarations to regular strings. String is now an alias for UnicodeString, and so all your strings can hold Unicode data just fine.
BTW, the author of the TNT controls, Troy Wolbrink, now vastly prefers Delphi 2009 over his own controls.
Main advantage of TNT Controls is only that It can work as Ansi program in Windows 9x. It is not full unicode. If you want full unicode support everywhere (such as Stringlist.LoadFromFile, Form.OnKeyPress) it's good to move to Delphi 2009.
I have done the same thing in an application that used different XML files as input. In my case, I was working with UTF-8 (so we could use regular strings) throughout the program and only converted to WideString for display purposes (TNT controls).
I removed the conversions back and forth between WideString and UTF-8 and replaced the TNT controls with regular VCL controls by hand since there were only a handful of forms.
The conversion took about an hour with testing. The code is simpler and the program is noticeably faster.
Related
We have large commercial app that we want to convert from Delphi 6 to 2010. Approx 10 3rd party component sets, all with source code... I have heard warnings about Unicode with 2010 - Does anyone have experience and or suggestions?
There are many resources available that you can read and that you will assist in the migration from Delphi 6 to Delphi 2009/2010 (Unicode).
You can use these articles as a guide.
Unicode Migration Statistics Tool (This utility will hopefully assist you in collecting useful statistics
on how hard (or not) it would be to migrate your older applications to
Unicode.)
Delphi 2009 and Unicode
Delphi 2009 strings explained by example
Upgrading a major project to Delphi 2009
Delphi and Unicode
Dr. Bob Delphi 2009 Unicode
Delphi 2009 - Unicode in Type Libraries
On Strings and Unicode in Delphi 2009
Delphi in a Unicode World Part I: What is Unicode, Why do you need it, and How do you work with it in Delphi?
Delphi in a Unicode World Part II: New RTL Features and Classes to Support Unicode
Delphi in a Unicode World Part III: Unicodifying Your Code
CodeRage 4 : Using Unicode and Other Encodings in your Programs
Bye.
You'll find some useful answers in these StackOverflow questions:
Move project from Delphi 3 to Delphi 2010
When and Why Should I Use TStringBuilder?
Convert function to delphi 2009/2010 (unicode)
Unicode problems with Delphi 2009 / 2010 and windows API calls
Also, for what it is worth, I purchased Marco Cantu's Delphi 2009 Handbook. It was all I needed to make a relatively smooth converstion from Delphi 4 to Delphi 2009 in only a few weeks.
I do, however, recommend that you ensure your 3rd party packages have a Delphi 2009 upgrade, or you may have some real difficulties. Converting your own code is one thing. Converting someone else's is another.
I use two 3rd party packages, both with source code. Both had upgrades available, and the developer of one of them wrote that he had a lot of trouble upgrading his very complex component to the Unicode of Delphi 2009. It took him a few months, but he completed it. And as a result, I had little trouble with my implementation of his component when I did my upgrade.
i've been in the same circumstance recently. you mostly need to pay attention to the "edges" of the app. INI files, file I/O, log files, etc. win API calls from delphi work since they've now connected the unicode API calls instead. check each 3rd party component set to make sure they're at least ready for Delphi 2009...better yet 2010. even my use of databases simply wasn't an issue...nearly everything worked right away. it just wasn't a big deal. anything that relies on the size of a character should be reviewed.
really the transition of most concern is 2007_or_earlier --> 2009_or_later.
there are plenty of discussions/blog entries about it. you could read, read, read...or you could get started & see what happens. (i did some of both). i'm sure there are "stack overflow" issues discussing your question. i'm not pretending to give a detailed description of what could happen.
it's simply not as scary as it sounds.
Approx 10 3rd party component sets, all with source code.
One thing I'd add is if the component doesn't support Delphi 2009/2010, don't try to upgrade it by hacking the code.
Following is what I posted on How do the new string types work in Delphi 2009/2010?:
See Delphi and Unicode, a white paper written by Marco Cantù and I guess
The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets (No Excuses!), written by Joel.
One pitfall is that the default Win32 API call has been mapped to use the W (wide string) version instead of the A (ANSI) version, for example ShellExecuteA If your code is doing tricky pointer code assuming internal layout of AnsiString, it will break. A fallback is to substitute PChar with PAnsiChar, Char with AnsiChar, string with AnsiString, and append A at the end of Win32 API call for that portion of code. After the code actually compiles and runs normally, you could refactor your code to use string (UnicodeString).
I must add this article from Carey Jensen to others mentioned. It is labeled: "Delphi Unicode Migration for Mere Mortals: Stories and Advice from the Front Lines" (in english).
http://www.danysoft.com/free/delphiunicodemigration.pdf
As you can see in the title of it, you will find many experiences and hints and tips. I think it is the answer to your question. After carefully read it, you will sure knows what to do next. :)
Found in: http://www.danysoft.com/productos/migrar-aplicaciones-a-delphi-xe-o-cbuilder-xe.html
Another point to take care of, is the usage of Variant types with strings and the VarType function testing for strings: one needs to use varUString instead of varString.
Assuming AValue is of type Variant and has being assigned a Unicode string value, the following won't work:
if VarType(AValue) = varString then ...
and needs to be changed to
if VarType(AValue) = varUString then ...
I have an application that's compiled using Delphi 2006, and I want to launch an another application compiled in XE2 and pass it a parameter. I am using ShellExecute to launch the 2nd app from D2006, and the 4th parameter in ShellExecute expects PANSIChar (as the parameter passed to the launched application).
My XE2 app is not reading the parameter correctly, presumably due to the change to UNICODE strings.
Is there a way I can launch my XE2 application from my D2006 application and pass it the string as a parameter?
Your Delphi 2006 program is calling the ANSI version of ShellExecute, namely ShellExecuteA. That receives ANSI parameters.
When those arguments arrive in your Delphi XE2 program, they will be retrieved via GetCommandLine. And XE2 programs will call the Unicode version, GetCommandLineW.
But behind the scenes, Windows will have converted from ANSI to Unicode for you.
This sort of context sensitive conversion happens all the time in Windows. For example, you call SendMessageA, for WM_SETTEXT, passing a PAnsiChar. But the window is a Unicode window and so receives a PWideChar. The system has to be this way. Anything else would be anarchy.
The source of your problem is not that one program uses ANSI, and the other Unicode. Your problem is elsewhere.
Where exactly, it's impossible to tell with this information. One obvious possibility is that your argument contains spaces. Those spaces are interpreted as argument separators by the recipient, the XE2 program. Wrap your arguments in quote marks. Like this:
ShellExecute(..., '"argument with spaces"', ...);
Another possibility is that you are perhaps casting the argument to PAnsiChar when you receive it. If so, don't. Just read ParamStr(1) which is a Unicode string. Converted from ANSI for you by Windows.
I'm clearly guessing a little at the end here, but there's frankly not enough information to diagnose the fault definitively. But I can be sure that ANSI text is transparently converted to Unicode in your scenario.
Delphi 2009 and above support unicode. I have few legacy pascal source files that I wish to make it compile in Delphi 2009/2010 as well as Delphi 2007 and below.
A quick and safe way is replace
String to AnsiString
PChar to PAnsiChar
Char to AnsiChar
Is there any utility available that able to parse .pas file and make such replacement?
There is a tool for pointing out areas that might need attention:
http://cc.embarcadero.com/Item/27398
It doesn't convert it automatically, grep would do that but as mghie said it's not that simple.
You can use sed for that.
sed -i bak -e "s/string/AnsiString/g" *.pas
It would be a very bad idea, though. There's no reason your code shouldn't compile in all Delphi versions. The meaning of "string" has changed, but so what? Your Delphi 2007 code doesn't need to be used with your Delphi 2009 code. The DCU file formats are different, so you'd have to recompile anything you change anyway.
By changing everything to AnsiString, you're essentially rejecting everything new that Delphi 2009 offers. If that's what you want to do, you could have saved yourself a lot of money by simply not upgrading to Delphi 2009 at all. Why buy a product and then not use any of its features? Since everything else in the product is Unicode, your program's performance will go down the tubes as it continually converts between string formats. You'll also drown in compiler warnings from all the conversions.
Don't force square pegs into round holes, especially when you have a perfectly good set of round pegs sitting right next to you.
our delphi win32 app uses special characters like micro and copyright. we mostly use the arial. before delphi 2009, we had to provide a way to prevent the micro character from displaying since for some (many/most?) parts of the world, it was not displayed correctly. we'd replace micro with u, copyright with (C)...
now that we're in delphi 2009, can we leave out this option and display the micro & copyright symbols without needing to do this translation.
it would seem to me that this should work everywhere now without this lame replacement scheme now that our app is in unicode.
thank you!
Yes, as long as you're using Unicode strings and not ANSI strings, you can put in whatever extended characters you'd like, and they'll show up properly as long as the font you're displaying in supports them.
I'd test it in a few differnt languages first though. Unicode is not always as Universal as we sometimes believe.
I have a rather large (freeware) project written with Delphi 2007 which is using both the TntUnicodeControls and the TntLXControls library and I'm planning to move to Delphi 2009.
Unfortunately I'm using those libraries everywhere in my project:
Replacement for VCL controls to provide Unicode capability
Win32 API wrappers (mostly for comparing strings)
The feature enhancements of TntLXForms, TntLXRegistry, ...
Third-party components which use TntControls. (VirtualTrees, SpTBXLib, updates for D2009 are available)
Do you have any experience and/or suggestions in porting such a project to Delphi 2009. Is it advisable to first switch to the (commercial) TMS Unicode controls?
Install GExperts; there is "Replace component" IDE addin that can help converting TTntXXX to TXXXX controls. Try for once, and if it's ok just check "Replace evrywhere in project".
SpTbx and VirtualTrees can only be recompiled - they both support D2009.
If you used WinAPI wrappers just to call Unicode API-s they should work in D2009 also.
That leaves you with TntLX controls (TntLXForms, TntLXRegistry, ...). Since they are unsupported, may be it is good time to change them anyway.
I can help with some of this, as I'm porting a C++Builder application that uses TNT from 2007 to 2009. The switch to Unicode in D2009 is overdue and welcome. However, it's unfortunate that the transition is probably easier for those who have NOT needed unicode in the past, and probably still don't. If, like me, you needed Unicode and used Troy Wolbrink's great TNT control to provide it, you have a rather more complex job...
The good news is that there's a new version of TNTControls from TMS Software which supports D2009. I haven't looked at this, but expect it is just a 'facade' layer over the native VCL components to ease portability. I'd consider that if your other libraries can be rebuilt to use it.
However, you may be better going back to native VCL controls, and the reason is string types. TNT control have always used WideString to pass Unicode strings back and forth, and you may well have WideString use scattered through your own code. This will work, but it's not ideal as WideString should really just be used for COM interop as it 'wraps' the COM BSTR type. Native unicode strings in D2009 are reference-counted and should be significantly faster.
If you do decide to replace TNT components with native VCL ones, you can use GExperts "Replace Components" command - or, maybe easier, do a search and replace in your .DFM and .PAS files (which you DO have in text form, don't you) to replace TTNT with T.
I recommend the following resources:
Marco Cantu's Delphi 2009 Handbook Chapter 3 (Porting to unicode)
http://www.marcocantu.com/dh2009/
Nick Hodges' articles (Delphi in a Unicode World)
http://blogs.codegear.com/nickhodges/2008/11/20/39149
I think either way it's going to be a lot of work. Probably more so than if you hadn't done all the work to make it unicode compatible before. I personally would forget about the tms Unicode controls, and go back to the vcl. It will save more pain in the future. (nothing against those controls, mind you.)
Also remember, that D2009's string, is not the same thing as D2007's Widestring which you have undoubtedly used in your app. So all instances of Widestring, which you so diligently changed from string (which was AnsiString), need to go back again to string(which is now unicodestring).