Source file: /~heha/hs/Funkuhr.zip/src/DlgStellen.c

/********************************
 * 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
Wrong umlauts? - Assume file is ANSI (CP1252) encoded