/********************************
* Projekt: Funkuhr DCF77 *
* Eigenschaftsseite äStellenô *
* Festlegen, wann Systemuhr *
* gestellt wird *
********************************/
#include "Funkuhr.h"
// Editfeld enablen/disablen, nΣchste Stellzeit ein/ausblenden
static void SetShowWindow_AfterHour(HWND Wnd) {
int state=Config.Checkmarks&2?TRUE:FALSE;
EnableDlgItem(Wnd,18,state);
if (state) state=SW_SHOW;
ShowDlgItem(Wnd,21,state); // "Das nΣchste Mal"
ShowDlgItem(Wnd,19,state); // Zeitangabe
}
// nur Editfeld enablen/disablen
static void SetShowWindow_MsgAtDiff(HWND Wnd) {
EnableDlgItem(Wnd,20,Config.Checkmarks&0x10?TRUE:FALSE);
}
static void OnAfterHourChange(void) {
KillTimer(MainWnd,100); // nicht starten
if (Config.Checkmarks&2 && Empfang.Ein!=3) StartWecker();
}
#define ALLOW_POS 1 // Zeit in Zukunft
#define ALLOW_NEG 2 // Zeit in Vergangenheit
// Ausgabe PrΣzision fⁿr StrFromTimeInterval, zur Ausgabe von Minuten
// StrFromTimeInterval hat eine eigenartige Logik!
// <m> = ganze Minuten
// Liefert <2> wenn m=0 zur Anzeige der Sekunden
int PrecisForMinutes(DWORD m) {
int ret=2;
DWORD h;
if (m) { // sonst zweistellige Sekunden
h=m/60; // Kann das der Compiler zusammenfassen??
m%=60;
if (m<10) ret--; // einstellige Minuten
if (h) ret++; // einstellige Stunden
if (h>=10) ret++; // zweistellige Stunden
}
return ret;
}
// Zeitdifferenz zu JETZT oder absolute Zeit ausgeben
// id = 10 ("in %s") oder 9 ("vor %s")
// ft = Zeiger auf Zeitdifferenz (Arrayindex 1) und Absolutzeit (Index 0)
// p = Pufferzeiger, len=Puffergr÷▀e in Zeichen ('\0' wird garantiert)
// Liefert Anzahl Millisekunden, bis Angabe ungⁿltig wird
static DWORD OutDiffOrFix(int id,U64*ft,LPTSTR p,int len) {
DWORD ms;
if (ft[1].ull<24*(ULONGLONG)36000000000) {
TCHAR t[32],q[64];
LoadString(ghInstance,id,t,elemof(t)); // Template laden
ms=(DWORD)(ft[1].ull/10000); // Millisekunden
StrFromTimeInterval(q,elemof(q),ms,PrecisForMinutes(ms/60000));
StrTrim(q,T(" ")); // <q> kommt mit Leerzeichen: weg damit!
wnsprintf(p,len,t,q);
if (ms<60000) return 1000; // sekⁿndlich aktualisieren
ms%=60000; // Rest an Millisekunden
}else{
FileTimeToString(&ft[0].ft,p,len,DATE_SHORTDATE,TIME_NOSECONDS,true);
ms=(DWORD)udiv(ft[0].ull/10000,60000).rem; // Millisekunden der Minute
}
return 60000-ms;
}
// Gibt die DOS-Zeitangabe relativ zur aktuellen Zeit an,
// wenn die Differenz nicht gr÷▀er als ▒24h ist, sonst
// als Datum + Uhrzeit
// Liefert 0 wenn Zeit auf der "falschen" Seite der Zeitskala liegt,
// oder DosTime=0 ist - DosTime ist in SystemTime!
// Liefert Anzahl Millisekunden, bis Angabe ungⁿltig wird
static DWORD SchoeneZeit(DWORD DosTime, ULONGLONG*add, LPTSTR s, int len, BYTE allow) {
U64 ft[2];
if (!DosTime) return 0;
DosDateTimeToFileTime(HIWORD(DosTime),LOWORD(DosTime),&ft[0].ft);
if (add) ft[0].ull+=*add;
ft[1]=GetSystemFileTime(false);
if (ft[0].ull>=ft[1].ull) { // <DosTime> in Zukunft
if (!(allow&ALLOW_POS)) return 0;
ft[1].ull=ft[0].ull-ft[1].ull; // Differenz (nichtnegativ)
return OutDiffOrFix(10,ft,s,len);
}else{ // <DosTime> in Vergangenheit
if (!(allow&ALLOW_NEG)) return 0;
ft[1].ull-=ft[0].ull; // Differenz (positiv)
return OutDiffOrFix(9,ft,s,len);
}
}
// Rⁿckgabewert sollte besser Timer-Wert sein, fⁿr nΣchste Aktualisierung!
// (sozusagen Gⁿltigkeitsdauer)
static void DisplayWeckzeit(HWND Wnd) {
ULONGLONG add;
DWORD dw;
TCHAR s[64];
KillTimer(Wnd,19);
if (!(Config.Checkmarks&2)) return;
add=HOUR2FILETIME(Config.AfterHour);
dw=SchoeneZeit(Config.LastSet,&add,s,elemof(s),ALLOW_POS);
if (dw) SetTimer(Wnd,19,dw,NULL);
else LoadString(ghInstance,7,s,elemof(s)); // "sofort"
SetEditText(Wnd,19,s);
}
static void DisplayZuletztGestellt(HWND Wnd) {
DWORD dw;
TCHAR s[64];
KillTimer(Wnd,22);
dw=SchoeneZeit(Config.LastSet,NULL,s,elemof(s),ALLOW_POS|ALLOW_NEG);
if (dw) SetTimer(Wnd,22,dw,NULL);
else LoadString(ghInstance,8,s,elemof(s)); // "noch nie"
SetEditText(Wnd,22,s);
}
static void DisplayLastAction(HWND Wnd) {
DWORD dw;
TCHAR s[128];
dw=SchoeneZeit(Config.LastActionTime,NULL,s,elemof(s),ALLOW_NEG);
if (dw) {
SetTimer(Wnd,17,dw,NULL);
StrCatBuff(s,T(":\n"),elemof(s));
dw=lstrlen(s);
LoadString(ghInstance,Config.LastActionCode,s+dw,elemof(s)-dw);
}else s[0]=0; // keine Aktion-Anzeige wenn Zeit in Zukunft (murks)
SetDlgItemText(Wnd,17,s);
}
INT_PTR CALLBACK StellenDlgProc(HWND Wnd,UINT Msg,WPARAM wParam,LPARAM lParam) {
DefHelpProc(Wnd,Msg,lParam,102);
switch (Msg) {
case WM_INITDIALOG: {
AttachUpDown(Wnd,18,118,0,255,Config.AfterHour);
AttachUpDown(Wnd,20,120,0,60,Config.MsgAtDiff);
SetCheckboxGroup(Wnd,11,16,Config.Checkmarks);
SetShowWindow_AfterHour(Wnd);
SetShowWindow_MsgAtDiff(Wnd);
if (Config.LastActionCode) DisplayLastAction(Wnd); // sonst "keine" stehen lassen
}return TRUE;
case WM_NOTIFY: {
LPPSHNOTIFY psn=(LPPSHNOTIFY)lParam;
switch (psn->hdr.code) {
case PSN_SETACTIVE: {
DisplayWeckzeit(Wnd);
DisplayZuletztGestellt(Wnd);
}break;
case PSN_KILLACTIVE: {
KillTimer(Wnd,19);
KillTimer(Wnd,22);
}break;
}
}break;
case WM_TIMER: switch ((BYTE)wParam) {
case 17: DisplayLastAction(Wnd); break;
case 19: DisplayWeckzeit(Wnd); break;
case 22: DisplayZuletztGestellt(Wnd); break;
}break;
case WM_FUNKRECV: switch ((BYTE)wParam) {
case 10: DisplayZuletztGestellt(Wnd); break;
case 11: DisplayWeckzeit(Wnd); break;
case 13: DisplayLastAction(Wnd); break;
}break;
case WM_COMMAND: switch ((BYTE)wParam) {
case 11:
case 12:
case 13:
case 14:
case 15:
case 16: {
Config.Checkmarks=Config.Checkmarks&0xC0|GetCheckboxGroup(Wnd,11,16);
switch ((BYTE)wParam) {
case 12: {
SetShowWindow_AfterHour(Wnd);
OnAfterHourChange();
DisplayWeckzeit(Wnd);
}break;
case 15: SetShowWindow_MsgAtDiff(Wnd);
}
}break;
case 18: if (HIWORD(wParam)==EN_CHANGE) {
if (GetUpDownByte(Wnd,118,&Config.AfterHour)) {
OnAfterHourChange();
DisplayWeckzeit(Wnd);
}
}break;
case 20: if (HIWORD(wParam)==EN_CHANGE) {
GetUpDownByte(Wnd,118,&Config.MsgAtDiff); // keine Zuweisung wenn > 60
}break;
}break;
}
return FALSE;
}
Detected encoding: OEM (CP437) | 1
|
|