#define STRICT #include #include HINSTANCE HInstance; // Diese Programm-Datensegment (_DS täte es auch) HWND MainWnd; // Hauptfenster HWND hSetupDlg; // Nichtmodaler Setup-Dialog HWND hDisplayDlg; HWND hKBHand; // Dialog-Keyboard-Handler (für nichtmodale Dialoge) COLORREF GridColor=0x008000; COLORREF BackColor=0xFFFFFFL; HPEN GridPen; HPEN XorPen; HBITMAP blt=(HBITMAP)TRUE,NullBitmap; HDC bltdc; HBRUSH BackBrush; POINT size,bmsize; POINT step; // Gitternetz-Schrittweite POINT tick; RECT Rand; // Gitternetz-Rand POINT lastmouse; // Fadenkreuz-Position BOOL xy; // X/Y-Modus (ein Spezialfall) #define DO_LINE 1 // PolyLine statt Punkte #define DO_CLIP 2 #define DO_DB 4 // DoubleBuffer #define DO_GRID 8 // Große Kästchen #define DO_TICK 16 // Kleine Marker #define DO_XOR 32 // Fadenkreuz #define DO_BACK 64 // Hintergrundpinsel (stets vorhanden) WORD DispOpt=0; // Anzeige-Optionen void SetDispOpt(WORD ADispOpt, WORD force) { //Display-Options-Bits setzen, ggf. weitere Datenstrukturen anlegen bzw. entfernen force|=DispOpt^ADispOpt; if (force&DO_GRID) { if (DispOpt&DO_GRID) DeleteObject(GridPen); if (ADispOpt&DO_GRID) { GridPen=CreatePen(PS_SOLID,0,GridColor); if (!GridPen) ADispOpt&=~DO_GRID; } } if (force&DO_DB) { if (DispOpt&DO_DB) { SelectObject(bltdc,NullBitmap); DeleteObject(blt); DeleteDC(bltdc); } if (ADispOpt&DO_DB) { HDC dc=GetDC(MainWnd); bltdc=CreateCompatibleDC(dc); blt=CreateCompatibleBitmap(dc,bmsize.x,bmsize.y); NullBitmap=SelectObject(bltdc,blt); ReleaseDC(MainWnd,dc); if (!blt) ADispOpt&=~DO_GRID; } if (force&DO_XOR) { if (DispOpt&DO_XOR) DeleteObject(XorPen); if (ADispOpt&DO_XOR) XorPen=CreatePen(PS_SOLID,0,0); } if (force&DO_BACK) { if (DispOpt&DO_BACK) DeleteObject(BackBrush); if (ADispOpt&DO_BACK) BackBrush=CreateSolidBrush(BackColor); } } DispOpt=ADispOpt; } typedef struct { float maxwert; float vorteiler; float div; BOOL var; // "div" ungenau int*data; COLORREF farbe; POINT*poly; int polycount; // kann durch Optimierung weniger sein als zeit.samples int ymin,ymax; // für begrenztes Neuzeichnen }KANAL; typedef struct { float div; float rate; BOOL var; // "div" ungenau int samples; }ZEIT; ZEIT zeit; KANAL kanal[2]; #pragma argsused BOOL CALLBACK AboutDlgProc(HWND Wnd, UINT Msg, WPARAM wParam, LPARAM lParam){ switch (Msg) { case WM_INITDIALOG: { }return TRUE; case WM_COMMAND: switch (wParam){ case 1: case 2: EndDialog(Wnd,wParam); }break; } return FALSE; } #pragma argsused BOOL CALLBACK SetupDlgProc(HWND Wnd, UINT Msg, WPARAM wParam, LPARAM lParam){ switch (Msg) { case WM_INITDIALOG: { }return TRUE; case WM_ACTIVATE: hKBHand=wParam?Wnd:0; break; case WM_COMMAND: switch (wParam){ case 2: hSetupDlg=0; DestroyWindow(Wnd); }break; } return FALSE; } #pragma argsused BOOL CALLBACK DisplayDlgProc(HWND Wnd, UINT Msg, WPARAM wParam, LPARAM lParam){ switch (Msg) { case WM_INITDIALOG: { int i; for (i=101; i<=105; i++) { CheckDlgButton(Wnd,i,DispOpt&(1<<(i-101))?1:0); } }return TRUE; case WM_ACTIVATE: hKBHand=wParam?Wnd:0; break; case WM_COMMAND: switch (wParam){ case 101: case 102: case 103: case 104: case 105: { SetDispOpt(DispOpt^(1<<(wParam-101)),0); }break; case 1: case 2: hDisplayDlg=0; DestroyWindow(Wnd); }break; } return FALSE; } /* Mal-Routinen: Gitternetz, Kurven, Fadenkreuz, alles zusammen */ #pragma argsused void _cdecl Line(HDC dc, int x1, int y1, int x2, int y2) { Polyline(dc,(LPPOINT)&x1,2); } void pascal Gitternetz(HDC dc) { int x,y; HPEN OldPen; OldPen=SelectObject(dc,GridPen); if (step.x>1) for(x=0; x<=bmsize.x; x+=step.x) { //waagerecht Line(dc,x,0,x,bmsize.y-1); } if (step.y>1) for(y=0; y<=bmsize.y; y+=step.y) { //senkrecht Line(dc,0,y,bmsize.x-1,y); } if (DispOpt & DO_TICK) { POINT middle; middle.x=bmsize.x>>1; middle.y=bmsize.y>>1; if (tick.x>1) for (x=tick.x; x1) for (y=tick.y; yfarbe); OldPen=SelectObject(dc,KPen); Polyline(dc,kanal->poly,kanal->polycount); SelectObject(dc,OldPen); DeleteObject(KPen); } void pascal GrafPixel(HDC dc, KANAL*kanal) { COLORREF color; POINT *pp; int i; color=kanal->farbe; for(i=kanal->polycount, pp=kanal->poly; i>0; i--,pp++) { SetPixel(dc,pp->x,pp->y,color); } } void pascal Fadenkreuz(HDC dc) { int OldROP; if ((unsigned)lastmouse.x<(unsigned)bmsize.x && (unsigned)lastmouse.y<(unsigned)bmsize.y) { OldROP=SetROP2(dc,R2_NOT); Line(dc,0,lastmouse.y,bmsize.x-1,lastmouse.y); Line(dc,lastmouse.x,0,lastmouse.x,bmsize.y-1); SetROP2(dc,OldROP); } } void pascal MaleOsziSchirm(HDC dc) { RECT R; void pascal (*GrafProc)(HDC, KANAL*)=DispOpt&DO_LINE?GrafLinie:GrafPixel; SetRect(&R,0,0,bmsize.x,bmsize.y); FillRect(dc,&R,BackBrush); if (DispOpt&DO_GRID) Gitternetz(dc); GrafProc(dc,&kanal[0]); GrafProc(dc,&kanal[1]); if (DispOpt&DO_XOR) Fadenkreuz(dc); } void pascal CalcGraf(KANAL*kanal) { POINT *pp; int i,y,*sa; int ymin,ymax; RECT R; ymin=30000; ymax=-30000; for(i=0, sa=kanal->data, pp=kanal->poly; ix=MulDiv(i,bmsize.x-1,zeit.samples); pp->y=y=(bmsize.y-1)/2-MulDiv(*sa++,bmsize.y-1,128); if (yymax) ymax=y; } ymax++; SetRect(&R,Rand.left,min(kanal->ymin,ymin),Rand.right,max(kanal->ymax,ymax)); kanal->ymin=ymin; kanal->ymax=ymax; // InvalidateRect(MainWnd,&R,TRUE); kanal->polycount=i; } LRESULT CALLBACK MainWndProc(HWND Wnd, UINT Msg, WPARAM wParam, LPARAM lParam){ switch (Msg) { case WM_CREATE: { MainWnd=Wnd; SetDispOpt(DO_GRID|DO_DB|DO_LINE|DO_TICK|DO_XOR|DO_BACK,0); SetTimer(Wnd,1,100,NULL); }break; case WM_PAINT:{ PAINTSTRUCT ps; BeginPaint(Wnd,&ps); SetViewportOrgEx(ps.hdc,Rand.left,Rand.top,NULL); if (DispOpt&DO_DB) { BitBlt(ps.hdc,0,0,bmsize.x,bmsize.y,bltdc,0,0,SRCCOPY); }else{ MaleOsziSchirm(ps.hdc); } EndPaint(Wnd,&ps); }return 0; // Simulation von eintreffenden Daten case WM_TIMER: { int i; HDC dc; for (i=0; i