【问题标题】:Strange regional character/datetime issue with Delphi7 program under Windows7Windows 7 下 Delphi 7 程序的奇怪区域字符/日期时间问题
【发布时间】:2011-05-11 10:13:36
【问题描述】:

我的 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?

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

有什么想法吗?

谢谢!

【问题讨论】:

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


    【解决方案1】:

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

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

    我还注意到,在 这些系统 DateToStr 将输出 11/17/2010 而不是 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); 获取格式设置; 结束。

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

    【讨论】:

    • 您好! CodePage 设置为我的语言,但在某些计算机上我仍然得到 o-s 和 u-s 而不是 ő-s 和 ű-s。在编辑框中,它可以正确显示,但由于某种原因,标题(表单和标签)不能很好地显示它们。有什么想法吗?
    【解决方案2】:

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

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

    编辑:-> 值得一提的是,当我们要求它插入当前日期和时间时,MS word 使用了不正确的语言环境。

    【讨论】:

    • 很高兴知道 MS Word 也有这个问题。将测试发布在 MS 论坛上的 Delphi Win7 修复程序。
    【解决方案3】:

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

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

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

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

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

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

    对于较新的 Delphi 版本也是如此。

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

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

    【讨论】:

    • 谢谢我知道 TFormatSettings,但即使代码页设置为我的语言,问题仍然存在。 (见我上面的评论)
    【解决方案4】:

    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;
    

    【讨论】:

      【解决方案5】:

      我知道迟到的帖子,但是这个帖子可能有原因和答案: GetThreadLocale returns different value than GetUserDefaultLCID?

      可能是因为安装操作系统时更改了区域设置。

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

      【讨论】:

        猜你喜欢
        • 2011-07-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-04-12
        • 1970-01-01
        • 2010-10-02
        • 2014-02-05
        相关资源
        最近更新 更多