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

/********************************
 * Projekt: Funkuhr DCF77	*
 * Eigenschaftsseite äEmpfangô	*
 * Kreisf÷rmige Anzeige der Bits*
 * der letzten 3 Minuten; Uhr	*
 ********************************/

#include "Funkuhr.h"

typedef struct{
 POINT Mitte;	// Mittelpunkt
 POINT Radius;	// Au▀enkreis
 POINT Width;	// 6% vom Au▀enkreis
 POINT SekZgr;	// Sekundenzeiger (zum L÷schen per XorPut)
}DRAWINFO;

static DRAWINFO di;

// wertet Bit 0 von <data> und <fehl> aus, liefert Pinsel, NULL bei Ende
static HBRUSH br4data(UINT data, UINT okay) {
 switch (data&1 | (okay&1)<<1) {
  case 1: return GdiObj.brFehl;
  case 2: return GdiObj.brKurz;
  case 3: return GdiObj.brLang;
 }
 return 0;
}

// 1 Sekunden-KΣstchen zeichnen; Pinsel und Ursprung gesetzt
static void DrawKaestchen(HDC dc, const POINT*Radius, int i) {
 POINT Inner,Poly[4];
 Inner.x=Radius->x-di.Width.x;
 Inner.y=Radius->y-di.Width.y;
 Poly[0].x=sinus(Radius->x,i);		// Sinus
 Poly[0].y=sinus(Radius->y,i+45);	// -Kosinus
 Poly[1].x=sinus(Radius->x,i+1);
 Poly[1].y=sinus(Radius->y,i+46);
 Poly[2].x=sinus(Inner.x,i+1);
 Poly[2].y=sinus(Inner.y,i+46);
 Poly[3].x=sinus(Inner.x,i);
 Poly[3].y=sinus(Inner.y,i+45);
 Polygon(dc,Poly,4);
}

// 1 Au▀en-Sekunden-KΣstchen "kurzfristig" zeichnen
static void XorKaestchen(HDC dc,int i) {
 SetROP2(dc,R2_XORPEN);
 SelectPen(dc,GdiObj.peXor);
 DrawKaestchen(dc,&di.Radius,i);
}

static void DrawSekZgr(HDC dc) {
 SetROP2(dc,R2_XORPEN);
 SelectPen(dc,GdiObj.peXor);
 Line(dc,0,0,di.SekZgr.x,di.SekZgr.y);
}

// Funkuhr-Empfangsbits zeichnen
static void DrawUhr(HDC dc, const RECT*r, bool Alles) {
 POINT Radius;
 int i,ring,
   Index=Empfang.Index,
   Ringe=min(Config.Minuten,Empfang.Anzahl),
   Sek=Empfang.Sek;
 ULONGLONG data,okay;	// Schieberegister

 di.Mitte.x=(r->right+r->left)/2;
 di.Mitte.y=(r->bottom+r->top)/2;
 di.Radius.x=(r->right-r->left)/2-1;
 di.Radius.y=(r->bottom-r->top)/2-1;
 di.Width.x=MulDiv(di.Radius.x,6,100);	// 6%
 di.Width.y=MulDiv(di.Radius.y,6,100);

 Radius=di.Radius;
 SelectBrush(dc,GetStockBrush(HOLLOW_BRUSH));
 SetViewportOrgEx(dc,di.Mitte.x,di.Mitte.y,NULL);
 if (Alles) {
  TCHAR s[32];
  RECT r;
  SetRect(&r,-di.Radius.x,-di.Radius.y,di.Radius.x,di.Radius.y);
  SelectFont(dc,GdiObj.fnQuer);
  SetTextColor(dc,GetSysColor(COLOR_GRAYTEXT)/*RGB(128,128,128)*/);
  DrawText(dc,s,LoadString(ghInstance,6,s,elemof(s)),&r,
    DT_CENTER|DT_NOPREFIX|DT_SINGLELINE|DT_VCENTER);
  for (ring=0; ring<Ringe; ring++) {
   data=Empfang.Data[Index];
   okay=Empfang.Okay[Index];
   for (i=0; i<59; i++) {
    HBRUSH br=br4data((UINT)data,(UINT)okay);
    if (ring==0 && i>Sek) br=0;
    if (!br) break;	// Abbruch des Kreises
    if (ring==0 && i==Sek && Empfang.Signal) br=GetStockBrush(HOLLOW_BRUSH); // noch keine LΣnge bekannt!
    SelectBrush(dc,br);
    DrawKaestchen(dc,&Radius,i);
    data>>=1;
    okay>>=1;
   }
   Radius.x-=di.Width.x;
   Radius.y-=di.Width.y;
   if (!Index) Index=MINU;
   Index--;
  }
 }else if (Empfang.Signal) {	// hohles KΣstchen (noch keine LΣnge bekannt)
  XorKaestchen(dc,Sek);
  Radius.x-=di.Width.x*Ringe;	// fⁿr Sekundenzeiger vorbereiten
  Radius.y-=di.Width.y*Ringe;
 }else{				// gefⁿlltes KΣstchen?
  HBRUSH br;
  data=Empfang.Data[Index]>>Sek;
  okay=Empfang.Okay[Index]>>Sek;
  br=br4data((UINT)data,(UINT)okay);
  if (br) {
   SelectBrush(dc,br);
   DrawKaestchen(dc,&Radius,Sek);
  }else{
   XorKaestchen(dc,Sek);	// hohles KΣstchen wegnehmen, Telegramm zu Ende
  }
 }
 if (!Alles && (Empfang.Signal || Empfang.Sek==59)) {
  DrawSekZgr(dc);
  di.SekZgr.x=di.SekZgr.y=0;
 }
 if (Alles && Empfang.Luecke
 || !Alles && (Empfang.Signal || Empfang.Sek==59) && Empfang.Luecke) {	// Sekundenzeiger
  di.SekZgr.x=sinus(Radius.x,Sek);
  di.SekZgr.y=sinus(Radius.y,Sek+45);
  DrawSekZgr(dc);
 }
// ggf. Minuten- und Stundenzeiger!?
}

// Legende (ZeichenerklΣrung) zeichnen: hier nur das bunte Rechteck
static void DrawLegende(HDC dc, const RECT*r, UINT id) {
 SelectBrush(dc,(&GdiObj.brKurz)[id]);
 Rectangle(dc,r->left,r->top,r->right,r->bottom);
}

INT_PTR CALLBACK EmpfangDlgProc(HWND Wnd,UINT Msg,WPARAM wParam,LPARAM lParam) {
 DefHelpProc(Wnd,Msg,lParam,105);
 switch (Msg) {
  case WM_INITDIALOG: {
   AttachUpDown(Wnd,13,113,1,MINU,Config.Minuten);
   CheckDlgButton(Wnd,12,Config.Piep);
  }return TRUE;

  case WM_FUNKRECV: switch ((BYTE)wParam) {
   case 0:
   case 1:
   case 2: {
    HWND w=GetDlgItem(Wnd,11);
    if (Empfang.Sek) {
     HDC dc=GetDC(w);
     RECT r;
     GetClientRect(w,&r);
     DrawUhr(dc,&r,false);
     ReleaseDC(w,dc);
    }else InvalidateRect(w,NULL,TRUE);
   }break;
  }break;

  case WM_COMMAND: switch ((DWORD)wParam) {
   case MAKELONG(13,EN_CHANGE): {
    if (GetUpDownByte(Wnd,113,&Config.Minuten)) {
     InvalidateRect(GetDlgItem(Wnd,11),NULL,TRUE);
    }
   }
  }break;

  case WM_DRAWITEM: {
   LPDRAWITEMSTRUCT dis=(LPDRAWITEMSTRUCT)lParam;
   switch ((BYTE)wParam) {
    case 11: DrawUhr(dis->hDC,&dis->rcItem,true); break;
    case 16:
    case 17:
    case 18: DrawLegende(dis->hDC,&dis->rcItem,(UINT)wParam-16); break;
   }
  }break;
 }
 return FALSE;
}
Detected encoding: OEM (CP437)1
Wrong umlauts? - Assume file is ANSI (CP1252) encoded