如何用编程实现TDateTimePicker的24小时制到12小时制的转换?

类别:Delphi 点击:0 评论:0 推荐:

昨天有一位网友在群聊中提到了这个问题,晚上回去想了很久。花了三个小时,终于找到了解决的方法,现在拿出来与大家分享:

  首先想到的是TDateTimePicker控件有没有属性来实现这一功能的转换,因为这样做的好处不言而知。在我看了TDateTimePicker、
TCommonCalendar这两个类的源码后得出了结论,不能用控件的属性或过程来实现这一转换。
  于是只好改变思路:
    我们知道,在Windows下可以修改时间的显示方式,具体方法如下:
    “控制面板”->“区域选项”(WINXP则是“日期与时间的显示方式”)->“时
     间”。在“时间格式”一栏中可以修改时间的显示格式,具的显示格式可在在“外观
     示例”中可以看到。
    现在可以知道“H:mm:ss”显示的是24小时制,而“tt h:mm:ss”显示的则是12小时
    制。

  我们把“时间格式”设置为“tt h:mm:ss”后再点击“确定”按钮退出。
  现在再来在窗体上放一个TDateTimePicker控件,OK,达到的预期的效果。

刚准备舒一口气,又转念一想,程序到了别人的电脑那不是又不行了??
看来,还得继续工作。

我们知道Windows的系统设置一般都保存在注册表中。现在的关键是找到时间显示格式所保存的注册表主键。
想一下,用的注册表搜索功能。
    我现在的系统时间是12小时制,它的显示格式是“tt h:mm:ss”。好,就来搜索这个
    吧。终于找到了第一个,仔细思量一下,应该是的:主键是:
        HKEY_CURRENT_USER\Control Panel\International
    而其中的sTimeFormat键值名就是时间格式。
    但是,里边还有那么多的键值,要修改哪些呢?又是一个问题。
    想了一下,行,就用这个办法:
       1、导出主键
       2、在控制面板中把系统时间改为24小时制
       3、再导出主键
       4、运行两个记事体实例,分别打开刚才导出的主键(扩展名为.reg)
       5、比较,删除键值名和数据都相同的行
    现在出来了结果:
      12小时制和24小时制有三个键值的数据不同
        键值名      12小时制的值          24小时制的值
         iTime                   0                                      1
              iTimePrefix           1                                      0
             sTimeFormat       H:mm:ss                        tt h:mm:ss

  现在余下的问题就是如何编程序来实现了。
  Delphi对注册表的操作一般都是用TRegistry类来实现,具体的操作请参考相关资料。
  现在贴出其源码:

unit SetTimeSotryUnit;

interface

uses
  Windows, Registry;


Type
  Time_Story  =   (ts_12,       {12 小时制}
                          ts_24        {24 小时制}
                           );

procedure SetTimeStory(const Story: Time_Story);
function GetTimeStory: Time_Story;

implementation

{ ---------------------------------------------------------------------------
//
//   把系统时间的显示方式设置为指定类型
//
//   参数   :
//          Story       :       指定类型
//
  --------------------------------------------------------------------------}
procedure SetTimeStory(const Story: Time_Story);
var
  Reg: TRegistry;
begin
  Reg := TRegistry.Create;
  {设置根主键为  HKEY_CURRENT_USER}
  Reg.RootKey := HKEY_CURRENT_USER;
  {打开主键   '\Control Panel\International'}
  Reg.OpenKey('\Control Panel\International', False);
  Try   {写入数据}
    Case Story of
      ts_12:    {12 小时制}
        begin
          Reg.WriteString('iTime', '0');
          Reg.WriteString('iTimePrefix', '1');
          Reg.WriteString('sTimeFormat', 'tt h:mm:ss');
        end;
      ts_24:    {24 小时制}
        begin
          Reg.WriteString('iTime', '1');
          Reg.WriteString('iTimePrefix', '0');
          Reg.WriteString('sTimeFormat', 'H:mm:ss');
        end;
    end;
  Finally;
    Reg.CloseKey;       {关闭主键}
    Reg.Free;
  end;
end;

{ ------------------------------------------------------------------------
//
//   返回当前系统时间的显示方式
//
//   返回值 :
//          默认的返回为 24 小时制
//
  -----------------------------------------------------------------------}
function GetTimeStory: Time_Story;
var
  Reg: TRegistry;
begin
  Result := ts_24;
  Reg := TRegistry.Create;
  Reg.RootKey := HKEY_CURRENT_USER;
  Reg.OpenKey('\Control Panel\International', False);
  Try
    if Reg.ReadString('sTimeFormat') = 'tt h:mm:ss' then
       Result := ts_12
    else
       Result := ts_24;
  Finally;
    Reg.CloseKey;
    Reg.Free;
  end;
end;

end.

以上的实现功能的转换,而我们要在TDateTimePicker创建之前就要设置好系统时间格式。
所以还要修改.dpr的文件,如下:
program Project1;

uses
  Forms,
  SetTimeSotryUnit in 'SetTimeSotryUnit.pas' {Form1};

{$R *.res}

begin
  Application.Initialize;
  if GetTimeStory = ts_12 then {如果为 12 小时制则显示为 24 小时制}
     SetTimeStory(ts_24)
  else                         {//如果为 24 小时制则显示为 12 小时制}
     SetTimeStory(ts_12);
  Application.CreateForm(TForm1, Form1);
  Application.Run;
end.

至此全部完成....

本文地址:http://com.8s8s.com/it/it5217.htm