Steve
Steve

Reputation: 2520

Strange regional character/datetime issue with Delphi7 program under Windows7

My Delphi7 program is in a non-English language and uses some Win1250 ANSI characters extensively. (aáíóőű)

I have noticed that under English language Windows XP/Vista/7 systems many accented characters appear non-accented (ie.: o instead of ő, u instead of ű) in Form and Label Captions.

On localized Windows XP/Vista systems there are no problems. But on some Windows 7 systems (maybe only on 64bit versions, I'm not sure) even if the Windows instance is localized, accented characters aren't displayed normally.

What I've also noticed is that on these systems DateToStr will output 11/17/2010 instead of 2010.11.17 - which is the standard localized format. The funny thing is that I've checked it under the regional settings, and the default date format is set to yyyy.mm.dd - why is DateToStr giving me back dd/mm/yyyy instead?

I've noticed the same behaviour with currencies ("," appearing as the decimal separator instead of ".", etc.).

Any ideas?

Thanks!

Upvotes: 4

Views: 6363

Answers (5)

Toby
Toby

Reputation: 390

Late post I know, but this thread may have the reason and answer: GetThreadLocale returns different value than GetUserDefaultLCID?

Possibly due to changing the locale setting when installing the OS.

Simply changing the regional language after installation to something else and then changing it back to what you want to use seems to fix it.

Upvotes: 0

Ian Boyd
Ian Boyd

Reputation: 256671

The problem with formatting of dates in Delphi is that Delphi assumes that the date separator character is only one character, e.g.:

  • "/" (e.g. English - United States)
  • "." (e.g. French - Canada)

This fails in locales that use more than one character for the date separator:

  • ". " (e.g. Slovak - Slovakia)

In this case Delphi, when asking Windows for the date separator character:

GetLocaleInfo(LOCALE_SDATE, ...)

fails and instead hard-codes the use of /.

In order to correctly convert a date to a string in Delphi you must use the Windows API function designed to convert a date to a string, GetDateFormat:

function DateToStrW(const Value: TDateTime; const Locale: LCID=LOCALE_USER_DEFAULT): WideString;
var
    pf: PWideChar;
    cch: Integer;
    TheDate: SYSTEMTIME;
    DateStr: WideString;
begin
    //Code is released into the public domain. No attribution required.
    SysUtils.DateTimeToSystemTime(Value, TheDate);

    cch := Windows.GetDateFormatW(Locale, DATE_SHORTDATE, @TheDate, nil, nil, 0);
    if cch = 0 then
        RaiseLastWin32Error;

    SetLength(DateStr, cch);
    cch := Windows.GetDateFormatW(Locale, DATE_SHORTDATE, @TheDate, nil, PWideChar(DateStr), Length(DateStr));
    if (cch = 0) then
        RaiseLastWin32Error;

    SetLength(DateStr, cch-1); //they include the null terminator  /facepalm
    Result := DateStr;
end;

Upvotes: 0

vcldeveloper
vcldeveloper

Reputation: 7489

I have noticed that under English language Windows XP/Vista/7 systems many accented characters appear non-accented (ie.: o instead of ő, u instead of ű) in Form and Label Captions.

Delphi 7 applications are non-unicode (except if you use components like TNT Components), so you need to check active CodePage for non-Unicode applications in Windows. In Win7, go to Control Panel | Region and Language | Administrative | Change system locale, and change the default ANSI CodePage for Windows.

What I've also noticed is that on these systems DateToStr will output 11/17/2010 instead of 2010.11.17 - which is the standard localized format. The funny thing is that I've checked it under the regional settings, and the default date format is set to yyyy.mm.dd - why is DateToStr giving me back dd/mm/yyyy instead?

This seems to be same as the below report: http://social.technet.microsoft.com/Forums/en-US/w7itprogeneral/thread/b4f90f07-206c-494b-8d14-ee17bfa689e0

It seems to be a bug in Windows. I had the same problem in one of my projects written for a Slovenian customer. I told the customer to set change current Date/Time settings to something different, save the changes, then go back to Date/Time settings, and change it back to his desired format. That would fix the problem.

Also in the link above, a programming workaround is mentioned:

From S.B.Christensen:

Hi Tim

I just had the same issu as you (also doing Delphi development).

If you wish to avoid your users to do the workaround themselves, use the following unit as the first in your project:

unit Win7;

interface

uses SysUtils, Windows;

implementation

initialization SetThreadLocale(LOCALE_USER_DEFAULT); GetFormatSettings; end.

I haven't tested the code myself, cuz the previous workaround worked fine for me.

Upvotes: 4

Jens Mühlenhoff
Jens Mühlenhoff

Reputation: 14873

You can set the default codepage for applications that do not support Unicode in the regional options of Windows.

In Delphi you can read (but not modify) this setting with the Windows API function GetACP.

http://msdn.microsoft.com/en-us/library/ms905215.aspx

Delphi versions before Delphi 2009 will always use this ANSI codepage to display the strings that you use to set label captions, etc. (at least for the default components)

The locale settings for some Delphi functions like FloatToStr can take a second parameter of type TFormatSettings to control the format used for the conversion.

http://docwiki.embarcadero.com/VCL/en/SysUtils.TFormatSettings

This is still the case with newer Delphi versions, too.

There is a set of default TFormatSettings in the SysUtils unit that gets initialized with Windows defaults at startup, see the Variables section of the SysUtils documentation:

http://docwiki.embarcadero.com/VCL/en/SysUtils

Upvotes: 0

Mike Taylor
Mike Taylor

Reputation: 2524

We have also observed this with Delphi applications. When we investigated the windows API calls where actually returning what appeared to be the incorrect values.

Simply try changing the Language and locale under the regional settings to another option then back to the one you use. this works every time for us.

EDIT:-> Just worth a mention that with us MS word was using the incorrect locale as when we asked it to insert the current date and time it used the wrong format.

Upvotes: 2

Related Questions