/********************************
* 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
|
|