Der Vollständigkeit halber soll noch kurz diese Variante demonstriert werden. Zuerst benötigen Sie eine Variable vom Typ pchar. Da Sie anfangs nicht wissen, wie viele Zeichen benötigt werden, müssen Sie genau das zuerst herausfinden:
iLen := GetTimeFormat(LOCALE_USER_DEFAULT,TIME_FORCE24HOURFORMAT,
@st,nil,nil,0);
"iLen" ist dabei eine integer-Variable. Da die Funktion die Anzahl der benötigten Zeichen zurückliefert, können wir abhängig von diesem Ergebnis Speicher für unsere pchar-Variable reservieren:
GetMem(lpBuf,iLen);
Die Funktion "GetMem" löst eine Exception aus, wenn kein freier Speicher zur Verfügung steht. Die weiteren Anweisungen sollten daher in einen try/finally-Block gekapselt werden. Konnte der Speicher reserviert werden, dann rufen Sie die Funktion erneut auf und geben diesmal natürlich die Variable an:
ZeroMemory(lpBuf,iLen);
if(GetTimeFormat(LOCALE_USER_DEFAULT,TIME_FORCE24HOURFORMAT, @st,nil,lpBuf,iLen) = iLen) then SetWindowText(wnd,lpBuf);
In diesem Fall wird die Anzeige der (formatierten) Uhrzeit sogar noch davon abhängig gemacht, ob das Funktionsergebnis der Anzahl der Zeichen entspricht. Am Schluss geben Sie die Variable wieder frei:
FreeMem(lpBuf,iLen);
Das Beispielprogramm enthält beide Versionen, die Sie mit Hilfe eines Compilerschalters auswählen können.
Ein kleines Problem, auf das ich aufmerksam gemacht wurde, soll nicht verschwiegen werden. Gehen wir dabei von dem Fall aus, dass Sie die Funktion ("GetTimeFormat" in dem Fall) zweimal verwenden: einmal bestimmen Sie die Größe des Puffers, beim zweiten Mal lesen Sie die Zeit aus und erhalten Ihren formatierten Zeitstring.
Beispiel: Sie bestimmen um 9 Uhr 30 und 17 Sekunden die Größe des Puffers. Kurz darauf (abhängig von Ihrer Systemauslastung wäre es denkbar, dass es mittlerweile 9 Uhr 30 und 18 ... Sekunden ist) lesen Sie die Zeit aus. In beiden Fällen ist der Puffer meiner Meinung nach ausreichend dimensioniert, so dass es zu keinem Problem kommen sollte.
Anders sieht es dagegen um 9 Uhr 59 und 59 Sekunden aus. Hier bestimmen Sie die Größe des Puffers. Ausgehend von den selben Verzögerungen im System wäre es nun denkbar, dass die Zeit tatsächlich erst um 10 Uhr und X Sekunden ausgelesen wird. In diesem Fall könnte der zuvor bestimmte Puffer bereits wieder zu klein sein. Die Funktion würde als Ergebnis Null zurückliefern, und der Grund wäre (via "GetLastError") der Fehler ERROR_INSUFFICIENT_BUFFER.
Dieses Problem könnte sich evtl. mit folgendem Code provozieren lassen:
iLen := GetTimeFormat(LOCALE_USER_DEFAULT,TIME_FORCE24HOURFORMAT, nil,nil,nil,0);
{ ... }
GetTimeFormat(LOCALE_USER_DEFAULT,TIME_FORCE24HOURFORMAT, nil,nil,lpBuffer,iLen);
Zuerst wird die Puffergröße bestimmt, und da der Zeitparameter nil ist, wird die aktuelle Zeit herangezogen. Nachdem der Speicher reserviert wurde, findet ein weiterer Zugriff statt. Diesmal mit der Puffervariablen und der vorher ermittelten Puffergröße. Und da auch hier der Zeitparameter wieder nil ist, wird erneut die aktuelle Zeit als Grundlage benutzt. (Sie dürfen auch gern absichtlich eine Verzögerung mit "sleep" einbauen, wenn Sie es "mal krachen lassen wollen ..." :o))
Im Fall des Beispielprogramms sollte aber dennoch (zumindest bei der Formatierung der Zeit) nichts passieren. Zum einen wird eine Funktion im Programm aufgerufen, der u.a. eine TSystemTime-Variable übergeben wird. Diese wird dann sowohl zur Bestimmung der Puffergröße als auch zur eigentlichen Formatierung herangezogen. Solange Sie also nicht innerhalb der Funktion die Zeit ein zweites Mal bestimmen lassen, tritt das geschilderte Problem nicht auf.
Außerdem wird, ich erwähnte es ja bereits, die Anzeige der Zeit noch davon abhängig gemacht, ob das Funktionsergebnis mit der zuvor bestimmten Puffergröße identisch ist:
if(GetTimeFormat(LOCALE_USER_DEFAULT,TIME_FORCE24HOURFORMAT, @st,nil,lpBuf,iLen) = iLen) then SetWindowText(wnd,lpBuf);
Das Problem könnte also bestenfalls nur bei der Formatierung des Datums auftreten, da hier der jeweils aktuelle Wert verwendet wird. Aber auch dann dürfte nichts passieren, da die gleiche Absicherung getroffen wurde:
if(GetDateFormat(LOCALE_USER_DEFAULT,DATE_SHORTDATE, nil,nil,lpBuf,iLen) = iLen) then SetWindowText(wnd, lpBuf);
Schlimmstenfalls bleibt also das jeweilige Feld für eine Sekunde leer.