在Windows 7下使用Delphi 7程序发生奇怪的区域字符/日期时间问题

时间:2010-11-17 13:25:34

标签: delphi datetime character-encoding delphi-7 currency

我的Delphi7程序使用非英语语言,并广泛使用一些Win1250 ANSI字符。 (aáíóőű)

我注意到在英语Windows XP / Vista / 7系统中,许多重音字符在表单和标签字幕中都显示非重音符号(即:o而不是ő,u而不是ű)。

在本地化的Windows XP / Vista系统上没有问题。但是在某些Windows 7系统上(可能只有64位版本,我不确定)即使Windows实例已本地化,重音字符也不会正常显示。

我还注意到,在这些系统上,DateToStr将输出11/17/2010而不是2010.11.17 - 这是标准的本地化格式。 有趣的是,我已经在区域设置下检查了它,默认日期格式设置为yyyy.mm.dd - 为什么DateToStr会给我回dd / mm / yyyy呢?

我注意到货币的相同行为(“,”显示为小数点分隔符而不是“。”等。)

有什么想法吗?

谢谢!

5 个答案:

答案 0 :(得分:4)

  

我注意到在英语下   语言Windows XP / Vista / 7系统   出现许多重音字符   非重音(即:o而不是ő,你   在Form和Label中代替ű)   字幕。

Delphi 7应用程序是非unicode(除非您使用TNT组件之类的组件),因此您需要在Windows中检查非Unicode应用程序的活动CodePage。在Win7中,转到“控制面板”|地区和语言|行政|更改系统区域设置,并更改Windows的默认ANSI CodePage。

  

我也注意到了这一点   这些系统DateToStr将输出   2010年11月17日而不是2010.11.17 -   这是标准的本地化   格式。有趣的是,我   在区域下检查它   设置和默认日期格式   设置为yyyy.mm.dd - 为什么   DateToStr给了我dd / mm / yyyy   代替?

这似乎与以下报告相同: http://social.technet.microsoft.com/Forums/en-US/w7itprogeneral/thread/b4f90f07-206c-494b-8d14-ee17bfa689e0

这似乎是Windows中的一个错误。我在为斯洛文尼亚客户编写的一个项目中遇到了同样的问题。我告诉客户将当前日期/时间设置更改为不同的设置,保存更改,然后返回日期/时间设置,并将其更改回所需的格式。这样可以解决问题。

同样在上面的链接中,提到了编程解决方法:

来自S.B.Christensen:

  

嗨蒂姆

     

我和你有同样的问题(也是   做Delphi开发)。

     

如果您希望避免用户这样做   解决方法本身,使用   以下单位作为你的第一个单位   项目:

     

单位Win7;

     

接口

     

使用SysUtils,Windows;

     

实施

     

初​​始化   SetThreadLocale(LOCALE_USER_DEFAULT);   GetFormatSettings;   端。

我自己没有测试过代码,因为之前的解决方法对我来说很合适。

答案 1 :(得分:2)

我们也用Delphi应用程序观察到了这一点。当我们调查windows API调用时实际返回看似不正确的值。

只需尝试将区域设置下的语言和区域设置更改为其他选项,然后再返回到您使用的选项。这对我们来说每次都有效。

编辑: - >值得一提的是,与我们一起使用MS word时使用了错误的语言环境,因为我们要求它插入当前日期和时间时使用的格式错误。

答案 2 :(得分:0)

您可以在Windows的区域选项中为不支持Unicode的应用程序设置默认代码页。

在Delphi中,您可以使用Windows API函数GetACP读取(但不能修改)此设置。

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

Delphi 2009之前的Delphi版本将始终使用此ANSI代码页来显示用于设置标签标题等的字符串(至少对于默认组件)

某些Delphi函数(如FloatToStr)的区域设置可以采用类型TFormatSettings的第二个参数来控制用于转换的格式。

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

对于较新的Delphi版本,情况仍然如此。

SysUtils单元中有一组默认的TFormatSettings在启动时使用Windows默认值进行初始化,请参阅Variables文档的SysUtils部分:

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

答案 3 :(得分:0)

在Delphi中格式化日期的问题是Delphi假定日期分隔符字符只有一个字符,例如:

  • "/"(例如英语 - 美国)
  • "."(例如法语 - 加拿大)

在使用多个字符作为日期分隔符的语言环境中失败:

  • ". "(例如斯洛伐克 - 斯洛伐克)

在这种情况下,Delphi在向Windows询问日期分隔符时:

GetLocaleInfo(LOCALE_SDATE, ...)

失败,而是硬编码使用/

为了正确将日期转换为Delphi中的字符串,您必须使用旨在将日期转换为字符串的Windows API函数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;

答案 4 :(得分:0)

我知道最新的帖子,但是此主题可能有原因和答案: GetThreadLocale returns different value than GetUserDefaultLCID?

可能是由于在安装操作系统时更改了语言环境设置。

在安装后只需将区域语言更改为其他语言,然后将其更改回您要使用的语言似乎可以解决此问题。