windows - Jeg kan ikke deaktivere sommertid med SetDynamicTimeZoneInformation

Indlæg af Hanne Mølgaard Plasc

Problem



Jeg bruger funktionen SetDynamicTimeZoneInformation til at indstille tidszoneoplysningerne (med aktivering/deaktivering af sommertid), under Vista/Win7 eller op, kan du se kodestykker nedenfor.

Koden ser ud til at virke okay, tidszoneoplysninger opdateres korrekt, men jeg har et underligt problem med DynamicDaylightTimeDisabled flag. Tidsprangene ændres med en time, hvis dagslysindstillingen ændres. men når jeg sætter DynamicDaylightTimeDisabled til sand, markeres afkrydsningsfeltet 'Juster automatisk ur til sommertid' fra Vista/Win7 tidszoneindstillinger dialogen.


Så hvad gør jeg forkert? Tak.


type
  TRegTZI = record // a TZI registry value is 44 bytes in this order
    Bias, // 4 bytes
    StdBias, // 4 bytes
    DltBias: integer; // 4 bytes
    StdDate, // 16 bytes
    DltDate: TSystemTime; // 16 bytes
  end;

  TTZIData = record
    TZName: string;
    Display, Dlt, Std: string;
    RegTZI: TRegTZI;
  end;


implementation

    function TZIDtatToWinTDZI(ATZI: TTZIData; DDTDisabled: boolean): TIME\_DYNAMIC\_ZONE\_INFORMATION;
    var
      WinTDZI: TIME\_DYNAMIC\_ZONE\_INFORMATION;
    begin
      WinTDZI.Bias := ATZI.RegTZI.Bias;
      WinTDZI.StandardBias := ATZI.RegTZI.StdBias;
      WinTDZI.DaylightBias := ATZI.RegTZI.DltBias;
      if not DDTDisabled then
      begin
        WinTDZI.StandardDate := ATZI.RegTZI.StdDate;
        WinTDZI.DaylightDate := ATZI.RegTZI.DltDate;
      end;
      StringToWideChar(ATZI.Std, @WinTDZI.StandardName[0], 32);
      StringToWideChar(ATZI.Dlt, @WinTDZI.DaylightName[0], 32);
      StringToWideChar(ATZI.TZName, @WinTDZI.TimeZoneKeyName[0], 128);
      WinTDZI.DynamicDaylightTimeDisabled := DDTDisabled;
      Result := WinTDZI;
    end;

    function GetTZIDataByName(TZKeyName: string; var ATZI: TTZIData): boolean;
    var
      Reg: TRegistry;
      BiRecSize: integer; 
    begin
      Result := False;
      Reg := TRegistry.Create;
      try
        Reg.RootKey := HKEY\_LOCAL\_MACHINE;
        if Reg.OpenKey('SoftwareMicrosoftWindows NTCurrentVersionTime Zones' + TZKeyName, False) then
        begin
          Result := True;
          ATZI.TZName := TZKeyName;
          if Reg.ValueExists('Display') then ATZI.Display := Reg.ReadString('Display');
          if Reg.ValueExists('Dlt') then ATZI.Dlt := Reg.ReadString('Dlt');
          if Reg.ValueExists('Std') then ATZI.Std := Reg.ReadString('Std');
          if Reg.ValueExists('TZI') then BiRecSize := Reg.ReadBinaryData('TZI', ATZI.RegTZI, SizeOf(ATZI.RegTZI));
          Reg.CloseKey;
        end;
      finally
        Reg.free;
      end;
    end;


    function Vista\_SetTimeZone(TZKeyName: string; AutoAdjustEnabled: boolean;
      var ErrStr: string): boolean;
    var
      ATZI: TTZIData;
      WinTDZI: TIME\_DYNAMIC\_ZONE\_INFORMATION;
    begin
      if GetTZIDataByName(TZKeyName, ATZI) then
      begin
        WinTDZI := TZIDtatToWinTDZI(ATZI, not AutoAdjustEnabled);
        Result := SetDynamicTimeZoneInformation (WinTDZI) <> 0;
        if Result then
          SendMessage(HWND\_BROADCAST, WM\_SETTINGCHANGE, 0, 0);
      end;
    end;

Bedste reference