Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi Dialog "Zeitzone ändern" nachbauen (https://www.delphipraxis.net/185823-dialog-zeitzone-aendern-nachbauen.html)

TUX_der_Pinguin 9. Jul 2015 10:52

Dialog "Zeitzone ändern" nachbauen
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo DPler,

ich würde gern in meinem Programm die Option anbieten die Zeitzone des Systems zu ändern, ähnlich dem Windows Dialog.

Anhang 43512


Mithilfe der Registry konnte ich mir schon eine ComboBox bauen die die Liste der Zeitzonen enthält, zumindest unter Windows XP hat dies funktioniert für Windows 7 muss ich da wohl noch was anpassen.

Aber zu meinem eigentlichen Problem, wie bekomme ich raus welche Zeitzone (also aus der Liste) zur Zeit eingestellt ist?

Mit GetTimeZoneInformation() z.B. erhalte ich nur "Mitteleuropäische Zeit" und nicht "(UTC+01:00) Amsterdam, Berlin, Bern, Rom, Stockholm, Wien" wie komme ich also an letzteres ran? Und wie ändere ich dann die Zeitzone wenn ich eine andere Zone aus der Liste auswähle?

Ich bin gerade etwas ratlos. :gruebel:

Sir Rufo 9. Jul 2015 10:57

AW: Dialog "Zeitzone ändern" nachbauen
 
Hmmm, es gibt den Dialog doch schon ... einfach in die Systemeinstellung und die Zeitzone ändern, schon wird die Zeitzone des Systems geändert.

Warum willst du einen Dialog nachbauen, obwohl es den schon gibt?

Oder kann es evtl. sein, dass du die Zeitzone eigentlich nur für deine Anwendung ändern müsstest (wenn du nur wüsstest wie)?

TUX_der_Pinguin 9. Jul 2015 11:04

AW: Dialog "Zeitzone ändern" nachbauen
 
Zitat:

Zitat von Sir Rufo (Beitrag 1308191)
Hmmm, es gibt den Dialog doch schon ... einfach in die Systemeinstellung und die Zeitzone ändern, schon wird die Zeitzone des Systems geändert.

Warum willst du einen Dialog nachbauen, obwohl es den schon gibt?

Oder kann es evtl. sein, dass du die Zeitzone eigentlich nur für deine Anwendung ändern müsstest (wenn du nur wüsstest wie)?

Es geht um eine Art Kiosk Anwendung, sprich der Anwender kommt an den Windows Dialog gar nicht ran. ;-)
Der Anwender soll aber ein paar Optionen doch ändern können, Datum und Uhrzeit. Da habe ich gedacht warum
nicht auch die Zeitzone, wichtig wäre das nicht ist mehr interessehalber ob es geht.

hathor 9. Jul 2015 12:15

AW: Dialog "Zeitzone ändern" nachbauen
 
Delphi-Quellcode:
uses Shellapi;
...
ShellExecute(Handle, 'open', 'control', 'date/time', nil, SW_SHOW);
...
Oder so - tut das Gleiche:
Delphi-Quellcode:
procedure TForm1.ButtonClick(Sender: TObject);
var FN, strParams : String;
begin
//rundll32.exe shell32.dll,Control_RunDLL timedate.cpl,,/
 strParams:= 'shell32.dll,Control_RunDLL timedate.cpl,,/';
 FN:='rundll32.exe';
ShellExecute(Application.Handle,NIL,PWChar(FN), PWChar(strParams),NIL, SW_Normal);
end;

TUX_der_Pinguin 9. Jul 2015 14:17

AW: Dialog "Zeitzone ändern" nachbauen
 
Zitat:

Zitat von hathor (Beitrag 1308200)
Delphi-Quellcode:
uses Shellapi;
...
ShellExecute(Handle, 'open', 'control', 'date/time', nil, SW_SHOW);
...
Oder so - tut das Gleiche:
Delphi-Quellcode:
procedure TForm1.ButtonClick(Sender: TObject);
var FN, strParams : String;
begin
//rundll32.exe shell32.dll,Control_RunDLL timedate.cpl,,/
 strParams:= 'shell32.dll,Control_RunDLL timedate.cpl,,/';
 FN:='rundll32.exe';
ShellExecute(Application.Handle,NIL,PWChar(FN), PWChar(strParams),NIL, SW_Normal);
end;

Daran hatte ich noch nicht gedacht. Ich würde aber dennoch gerne wissen wie man die aktuelle Zeitzone in der Liste auswählt und wie man dann die Zeitzone ggf. ändern kann.

markus5766h 9. Jul 2015 14:42

AW: Dialog "Zeitzone ändern" nachbauen
 
Moin,

such mal nach
"GetTimeZoneInformation" und "SetTimeZoneInformation" . . . da sollte sich noch was finden lassen.

TUX_der_Pinguin 9. Jul 2015 15:10

AW: Dialog "Zeitzone ändern" nachbauen
 
Zitat:

Zitat von markus5766h (Beitrag 1308223)
Moin,

such mal nach
"GetTimeZoneInformation" und "SetTimeZoneInformation" . . . da sollte sich noch was finden lassen.

Naja nicht so wirklich den GetTimeZoneInformation liefert, wie ich eingangs geschrieben habe, nur eine unspezifische Antwort ( "Mitteleuropäische Zeit" ). In der Liste stehen aber detaillierte Informationen wie z.b. "(UTC+01:00) Amsterdam, Berlin, Bern, Rom, Stockholm, Wien". Wie sollte ich also mit GetTimeZoneInformation() entscheiden ob "UTC+1 Amsterdam, Berlin" oder "UTC+1 Sarajevo, Skopje" eingestellt ist. Klar die Zeitzone ist schon die gleiche aber ich will ja die Auswahl anbieten die auch der Standard Windows Dialog bietet.

Luckie 9. Jul 2015 15:36

AW: Dialog "Zeitzone ändern" nachbauen
 
Die erweiterten Informationen stehen in der Registry: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones

Die Frage ist jetzt, ob es dafür eine API Funktion gibt oder ob man die selbst zuordnen und auslesen muss.

TUX_der_Pinguin 9. Jul 2015 15:45

AW: Dialog "Zeitzone ändern" nachbauen
 
Zitat:

Zitat von Luckie (Beitrag 1308235)
Die erweiterten Informationen stehen in der Registry: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones

Die Frage ist jetzt, ob es dafür eine API Funktion gibt oder ob man die selbst zuordnen und auslesen muss.

Genau daher kommen die Informationen zum erstellen einer Liste aller im System verfügbaren Zeitzonen, wie sie auch im Standard Windows Dialog aufgelistet werden.

Die Frage ist eher steht da auch irgendwo welche Zeitzone zur Zeit aktuell eingestellt ist und lässt sich das dort ändern und wenn ja wie? Ich denke einfach etwas in der Registry ändern heißt ja nicht unbedingt das das System die Änderung auch mitbekommt und sofort anwendet. Fragen über Fragen. ;-)

Luckie 9. Jul 2015 15:49

AW: Dialog "Zeitzone ändern" nachbauen
 
Was willst du den jetzt machen? Ich dachte dir geht es darum die erweiterten Informationen anzuzeigen? Das diese Information nur zum Lesen und Anzeigen da sind sollte wohl klar sein. Ändern der Zeitzone geht mit SetTimeZone....irgendwas.

Der schöne Günther 9. Jul 2015 16:10

AW: Dialog "Zeitzone ändern" nachbauen
 
Was für ein Zufall, da bin ich momentan auch grade dran: Auf einer Kiosk-Anwendung soll der Inbetriebnehmer jetzt auch die lokale Zeitzone einstellen können.

Die im System vorhandenen Zeitzonen findet man anscheinend wirklich nur, wie schon genannt, in der Registry. Dort musst du den Binarblob auslesen und kannst dir anhand der zwei weiteren Schlüssel dort wieder die Zeitzone zusammenbasteln.

Wenn man auf die .NET-Gegenseite guckt, kann man echt wieder neidisch werden, da ist alles schon fertig. TimeZoneInfo.GetSystemTimeZones() und gut ist (sogar schon sortiert).

Wenn du noch einen Tag wartest, habe ich das fertig. Wenn du nur wissen willst was deine aktuelle Zeitzone ist, das steht auch schon unter
Delphi-Quellcode:
System.DateUtils.TTimeZone.Local
.

Die lokale Zeitzone zu ändern ist etwas kniffeliger, da musste man, meine ich, noch vorher wieder an diesen komischen Prozess-Privilegien drehen. Bis morgen kann ich das mal alles zusammenstellen.

BadenPower 9. Jul 2015 16:24

AW: Dialog "Zeitzone ändern" nachbauen
 
Zitat:

Zitat von Der schöne Günther (Beitrag 1308242)
Die lokale Zeitzone zu ändern ist etwas kniffeliger, da musste man, meine ich, noch vorher wieder an diesen komischen Prozess-Privilegien drehen. Bis morgen kann ich das mal alles zusammenstellen.

SetTimeZoneInformation()

Zitat:

Remarks
An application must have the SE_TIME_ZONE_NAME privilege for this function to succeed. This privilege is disabled by default. Use the AdjustTokenPrivileges function to enable the privilege before calling SetTimeZoneInformation, and then to disable the privilege after the SetTimeZoneInformation call. For more information, see Running with Special Privileges.

Windows Server 2003 and Windows XP/2000: The application must have the SE_SYSTEMTIME_NAME privilege.


Sir Rufo 9. Jul 2015 18:46

AW: Dialog "Zeitzone ändern" nachbauen
 
Für die Inbetriebnahme des Systems, kann man natürlich auch einen extra Benutzer anlegen mit exakt den Rechten, die der benötigt.

Dann kann der in den "normalen" Dialogen herumwurschteln und das System einstellen.

Der Kiosk-Benutzer braucht das nicht zu können.

TUX_der_Pinguin 10. Jul 2015 07:24

AW: Dialog "Zeitzone ändern" nachbauen
 
Zitat:

Zitat von Der schöne Günther (Beitrag 1308242)
Wenn du noch einen Tag wartest, habe ich das fertig. Wenn du nur wissen willst was deine aktuelle Zeitzone ist, das steht auch schon unter
Delphi-Quellcode:
System.DateUtils.TTimeZone.Local
.

Ich nutze noch Delphi 2009 da gibt es TTimeZone leider noch nicht, aber wäre natürlich trotzdem schön zu wissen ob und wie es damit gehen würde. Dann könnte ich die Umsetzung verschieben bis ich eine neuere Delphi Version zur Verfügung habe. ;-)


Zitat:

Zitat von Sir Rufo (Beitrag 1308259)
Für die Inbetriebnahme des Systems, kann man natürlich auch einen extra Benutzer anlegen mit exakt den Rechten, die der benötigt.

Dann kann der in den "normalen" Dialogen herumwurschteln und das System einstellen.

Der Kiosk-Benutzer braucht das nicht zu können.

Du hast natürlich vollkommen recht der normale Anwender muss oder sollte das vielleicht auch nicht dürfen. Ich würde die Option vielleicht auch nur in einem Passwortgeschützen Servicebereich anbieten.

Der schöne Günther 10. Jul 2015 18:58

AW: Dialog "Zeitzone ändern" nachbauen
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo-

Es war insgesamt doch mehr Aufwand als ich gedacht hätte.
Anbei ein kleines Konsolenprogramm was dir alle Zeitzonen im System auflistet (formatiert und lokalisiert) und deine lokale Zone ändern kann.

Delphi 2009 war vor meiner Zeit, keine Ahnung wie viel von dem Code man da übernehmen kann.

TUX_der_Pinguin 11. Jul 2015 02:17

AW: Dialog "Zeitzone ändern" nachbauen
 
Ich gucke es mir Montag auf der Arbeit an. Vielen Dank schon mal das du hier deine Arbeit teilst ;-)

TUX_der_Pinguin 13. Jul 2015 08:56

AW: Dialog "Zeitzone ändern" nachbauen
 
So es ist Montag und ich habe mir deinen Code angesehen, soweit sehr gut nur fehlt mir da immer noch die Möglichkeit zu sehen welche Zeitzone zur Zeit im System eingestellt ist. Oder bin ich so blind das ich diese Funktion nicht erkenne !?

Der schöne Günther 13. Jul 2015 09:08

AW: Dialog "Zeitzone ändern" nachbauen
 
Ich habe das nicht neu gebaut, sondern würde
Delphi-Quellcode:
TTimeZone.Local
aus
Delphi-Quellcode:
System.DateUtils
verwenden. Wenn es das bei dir noch nicht gibt, kannst du
Delphi-Quellcode:
WinApi.Windows.GetDynamicTimeZoneInformation(..)
verwenden.

Bei der Gelegenheit- Der
Delphi-Quellcode:
TTimeZoneHelper
könnte vielleicht noch
Delphi-Quellcode:
Equals(..)
überschreiben um zu prüfen ob zwei Zeitzonen gleich sind.

TUX_der_Pinguin 13. Jul 2015 10:33

AW: Dialog "Zeitzone ändern" nachbauen
 
Zitat:

Zitat von Der schöne Günther (Beitrag 1308524)
Ich habe das nicht neu gebaut, sondern würde
Delphi-Quellcode:
TTimeZone.Local
aus
Delphi-Quellcode:
System.DateUtils
verwenden. Wenn es das bei dir noch nicht gibt, kannst du
Delphi-Quellcode:
WinApi.Windows.GetDynamicTimeZoneInformation(..)
verwenden.

Bei der Gelegenheit- Der
Delphi-Quellcode:
TTimeZoneHelper
könnte vielleicht noch
Delphi-Quellcode:
Equals(..)
überschreiben um zu prüfen ob zwei Zeitzonen gleich sind.

Ich habe mir mal die Testversion von Delphi XE8 heruntergeladen, jedoch ob ich das neue TTimeZone.Local.DisplayName das "ältere" GetTimeZoneInformation oder GetDynamicTimeZoneInformation verwende erhalte ich nur "Mitteleuropäische Zeit" und damit kann ich leider nichts anfangen.

Der schöne Günther 13. Jul 2015 11:44

AW: Dialog "Zeitzone ändern" nachbauen
 
Was hast du denn sonst erwartet?

Willst du den String "(UTC+01:00) Amsterdam, Berlin, Bern, Rom, Stockholm, Wien" haben?

TUX_der_Pinguin 13. Jul 2015 12:10

AW: Dialog "Zeitzone ändern" nachbauen
 
Zitat:

Zitat von Der schöne Günther (Beitrag 1308548)
Was hast du denn sonst erwartet?

Willst du den String "(UTC+01:00) Amsterdam, Berlin, Bern, Rom, Stockholm, Wien" haben?

Ähm ja, wie soll man den sonst wissen welche Zeitzone aus der Liste aktuell im System eingestellt ist!?

Der schöne Günther 13. Jul 2015 12:50

AW: Dialog "Zeitzone ändern" nachbauen
 
Ich hatte anhand von
Delphi-Quellcode:
StandardName
verglichen und war glücklich damit.

Das hatte es nicht mehr in den Upload geschafft.
Delphi-Quellcode:
function TTimeZoneHelper.Equals(Obj: TObject): Boolean;
var
   asTimeZone: TTimeZone;
begin
   if (not (Obj is TTimeZone)) then Exit(False);
   asTimeZone := Obj as TTimeZone;

   Result := ID.Equals(asTimeZone.ID);
end;

TUX_der_Pinguin 13. Jul 2015 13:52

AW: Dialog "Zeitzone ändern" nachbauen
 
Zitat:

Zitat von Der schöne Günther (Beitrag 1308562)
Ich hatte anhand von
Delphi-Quellcode:
StandardName
verglichen und war glücklich damit.

Das hatte es nicht mehr in den Upload geschafft.
Delphi-Quellcode:
function TTimeZoneHelper.Equals(Obj: TObject): Boolean;
var
   asTimeZone: TTimeZone;
begin
   if (not (Obj is TTimeZone)) then Exit(False);
   asTimeZone := Obj as TTimeZone;

   Result := ID.Equals(asTimeZone.ID);
end;

Ich habe mal versucht die Funktion in die Datei "Helper.System.DateUtils.TimeZone.pas" einzubauen ...
Delphi-Quellcode:
   TTimeZoneHelper = class helper for System.DateUtils.TTimeZone
      protected const
         registryBasePath   = 'SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones';
         expectedResFile      = 'tzres.dll';
      protected
         class function CreateFromRegistry(
            const   registry:   TRegistry;
            const   fetcher:   TResourceStringFetcher;
            const   keyName:   String
         ): TPair<TDynamicTimeZoneInformation, String>;
         /// <summary>
         ///     Sortiert absteigend nach UTC-Bias. Von Greenwhich ausgehend
         ///    also von West nach Ost.
         /// </summary>
         class procedure MakeSorted(var items: TArray<TTimeZone>);
         class function GetNamedSystemZones(): TDictionary<TDynamicTimeZoneInformation, String>; virtual;
      public
         class function GetZones(): TArray<TTimeZone>;
         class procedure SetLocalTimeZone(const value: TTimeZone); static;
      class function Equals(Obj: TObject): Boolean;
   end;
... der compiler meckert aber das er mit "ID.Equals()" nichts anfangen kann.
Delphi-Quellcode:
class function TTimeZoneHelper.Equals(Obj: TObject): Boolean;
var
   asTimeZone: TTimeZone;
begin
   if (not (Obj is TTimeZone)) then Exit(False);
   asTimeZone := Obj as TTimeZone;

   Result := ID.Equals(asTimeZone.ID);
end;
Aber naja was solls, es scheint ja irgendwie doch nicht so zu funktionieren wie ich mir das gedacht habe. Ich werde das dann wohl auf unbestimmte Zeit verschieben oder gleich ganz lassen.

Vielen vielen dank Günther für deine mühen und deine Geduld ;-)

Der schöne Günther 13. Jul 2015 16:25

AW: Dialog "Zeitzone ändern" nachbauen
 
Delphi-Quellcode:
ID
ist ein String. Wenn der kein
Delphi-Quellcode:
Equals(..)
kennt hast du
Delphi-Quellcode:
System.SysUtils
nicht in der
Delphi-Quellcode:
uses
-Liste ;-)

Ich muss aber auch sowieso noch eine grafische Oberfläche dazu bauen, habe es damit aber nicht sonderlich eilig. Wenn ich das mal gemacht habe kann ich dir ja auch nochmal Bescheid geben. Denn ich finde, es geht doch an sich alles bestens: Zeitzone feststellen, Zeitzone einstellen. Was vergessen?

hathor 13. Jul 2015 19:33

AW: Dialog "Zeitzone ändern" nachbauen
 
Zitat:

Zitat von TUX_der_Pinguin (Beitrag 1308556)
Zitat:

Zitat von Der schöne Günther (Beitrag 1308548)
Was hast du denn sonst erwartet?

Willst du den String "(UTC+01:00) Amsterdam, Berlin, Bern, Rom, Stockholm, Wien" haben?

Ähm ja, wie soll man den sonst wissen welche Zeitzone aus der Liste aktuell im System eingestellt ist!?

Es gibt in WINDOWS seit WIN7 ein Tool: TZUTIL.exe

Windows-Zeitzonen-Hilfsprogramm

Syntax:
TZUTIL </? | /g | /s TimeZoneID[_dstoff] | /l>

Parameter:
/? Zeigt Informationen zur Syntax an.
/g Zeigt die aktuelle Zeitzonen-ID an.
/s TimeZoneID[_dstoff]
Legt die aktuelle Zeitzone unter Verwendung der angege-
benen Zeitzonen-ID fest. Mit dem Suffix "_dstoff" werden
Sommerzeitanpassungen fr die Zeitzone deaktiviert
(sofern zutreffend).
/l Führt alle gültigen Zeitzonen-IDs und Anzeigenamen auf.
Ausgabe:
<Anzeigename>
<Zeitzonen-ID>

Beispiele:
TZUTIL /g
TZUTIL /s "Pacific Standard Time"
TZUTIL /s "Pacific Standard Time_dstoff"

Anmerkungen:
Durch den Beendigungscode "0" wird angegeben, dass der
Befehl erfolgreich ausgeführt wurde.

Beispiel:
tzutil /l >F:/timezones.txt
schreibt alle gültigen Zeitzonen-IDs und Anzeigenamen in ein File.


Alle Zeitangaben in WEZ +1. Es ist jetzt 20:50 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz