|
Post by avpsoft on Apr 21, 2009 3:16:49 GMT -5
Hello
I use D2009 and the latest VCLZip 4.50 PRO. Now it works with unicode file names and it's good. But only ZIP utility who can read this archive right is WinZip 12. I've read VCLZip docs and undarstand that if I want to create archive with old format names I should compile my software without SUPPORt _ Unicode directive. I want to give a user a choise how to create archive unicode/not unicode (for example If there is no source files with unicode names - only English and for example Russian on Russian Windows Locale).
Is there a way to do that?
Thanks for your help
|
|
|
Post by Kevin on Apr 21, 2009 6:37:04 GMT -5
With Delphi 2009, the Unicode support is automatic and the IMPLEMENT_UNICODE directive has no effect.
What happens when you try to read the archives with zip utilities other than WinZip 12?
Kevin
|
|
|
Post by avpsoft on Apr 21, 2009 7:45:14 GMT -5
For example I have two files on Russian Windows: - with english name - with russian name when I archive them with previous version of VclZip or WinZip <=11 Russian names are ok. And this archive can be read by WinRar,7Zip,... (on RUSSIAN Windows only) Now I use VCLZip 4.5 with D2009. It creates archive and it is ok. But Russian names in this archive (If I open it with WinRar, WinZip 9,10,11) is something like this '@%$@%^#^$%#%^' I can even extract this archive but Russian files will have wrong names. But if I open it with WinZip 12 All names are Ok. So I guess that VCLZip stores all names except English in unicode format? May be I can use some callback procedure that can change arciving file name on fly?
|
|
|
Post by Kevin on Apr 21, 2009 8:20:18 GMT -5
One way that should work in D2009, is to run the filenames through an ansistring first. The best way to do this would be to use the OnStartZip event. This gets called for each file just before it is zipped into the archive. You have access to the ZipHeaderInfo structure here where you can change the filename. All you want to do is take the ZipHeaderInfo.filename and ZipHeaderInfo.directory and put them into an AnsiString and then back, like...
myAnsiString := ZipHeaderInfo.filename; ZipHeaderInfo.filename := myAnsiString; myAnsiString := ZipHeaderInfo.directory; ZipHeaderInfo.directory := myAnsiString;
I have not tested this, but I believe it should work.
Kevin
|
|
|
Post by avpsoft on Apr 21, 2009 8:22:35 GMT -5
I'll try this and write here about results Thanks
|
|
|
Post by Kevin on Apr 21, 2009 12:05:17 GMT -5
Good, I look forward to seeing how that works. :-)
|
|
|
Post by avpsoft on Apr 22, 2009 16:45:02 GMT -5
I've resolved this issue and now I use checkbox in my progam "Do not use Unicode for local file names".
I see that under D2009 IMPLEMENT_UNICODE is not defined so I've modified procedure: TZipHeaderInfo.SaveCentralToStream (kpZipObj.pas) ... // fnameOut: UTF8String; fnameOut: AnsiString; // As soon IMPLEMENT_UNICODE is not defined UTF8String is wideString so I defined it as AnsiString. ... if (not ToOEM(fname)) then // fnameOut := kpWideStringToUTF8(fname) //If IMPLEMENT_UNICODE is not defined this function just returns fname back and doesn't convert it so I've repaced it with coversion. fnameOut := UTF8Encode(fname) ..
That's all now if I use OEMConvert=Flexible local file names (in my case Russian) are not saved in Unicode and I can use WinZip < v11 and WinRar for example to extract them. Unicode file names (not English and not my local Russian) are saved in Unicode format.
If I use OEMConvert = Never all files are saved in Unicode fromat.
Regards
|
|
|
Post by Kevin on Apr 23, 2009 8:47:53 GMT -5
Ahh, that is a good place to put the change. But, you might want to do the same in SaveLocalToStream too since sometimes a zip utility might pull the information from there instead of from the Central headers... ... TZipHeaderInfo.SaveCentralToStream (kpZipObj.pas) ... // fnameOut: UTF8String; fnameOut: AnsiString; // As soon IMPLEMENT_UNICODE is not defined UTF8String is wideString so I defined it as AnsiString. ... if (not ToOEM(fname)) then // fnameOut := kpWideStringToUTF8(fname) //If IMPLEMENT_UNICODE is not defined this function just returns fname back and doesn't convert it so I've repaced it with coversion. fnameOut := UTF8Encode(fname) .. In D2009, fnameOut := kpWideStringToUTF8(fname) should convert behind the scenes when, in the function, a UnicodeString is being put into a UTF8String. Did you try this by JUST changing OEMConvert and without modifying the procedure? I would have thought that would end up doing the same thing.
|
|
|
Post by avpsoft on Apr 27, 2009 0:09:11 GMT -5
Yes I tried change OEMConvert first but without success. Do you have IMPLEMENT_UNICODE defined on your D2009? On my D2009 it is not defined after VCLZIP PRO installation so in this case UTF8String is WIDESTRING and kpWideStringToUTF8(fname) just returns fname without conversion. You can see kpWideStringToUTF8 listing if IMPLEMENT_UNICODE is not defined.
|
|
|
Post by Kevin on Apr 27, 2009 6:34:53 GMT -5
IMPLEMENT_UNICODE is not, and should not be defined in D2009. However, UTF8String is an AnsiString, not a WideString whether IMPLEMENT_UNICODE is defined or not. Here is the definition in the System unit for D2009: UTF8String = type AnsiString(65001); So the conversion SHOULD be taking place in the function: function kpWideStringToUTF8(S: kpWString): UTF8String; begin {$IFDEF IMPLEMENT_UNICODE} result := UTF8Encode(S); {$ELSE} result := S; {$ENDIF} end; In D2009, the line result := S is moving a WideString into a real UTF8String which should cause D2009 to convert to UTF8 behind the scenes. If the characters in S are just normal characters, then the conversion will result in a normal AnsiString, but if S contains Unicode then what is in result will be different from what is in S. So, I am not sure why you are not seeing the conversion take place, unless they are characters that are already normal characters.
|
|
|
Post by Kevin on May 1, 2009 8:14:54 GMT -5
It turns out that filenames that contain characters that are in the Ansi (but non-ascii) character set but no Unicode characters are going through the OEM conversion AND the UTF8 conversion, when they should only be going through the OEM conversion. This did not affect how VCLZip read the archives but could, in some cases affect how WinZip or PKZip would see the filenames. And this is only a problem in VCLZip 4.51 and only when compiled in Delphi or BCB 2009.
We have a fix for this and it will but uploaded, hopefully by the end of today.
Thanks for reporting this. :-)
Kevin
|
|