Source file: /~heha/basteln/PC/oszi/scopecard 220/oszitest.zip/OSZI.C

#define STRICT
#include <windows.h>
#include <stdlib.h>

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; x<bmsize.x; x+=tick.x) if (x%step.x) {
   Line(dc,x,middle.y-tick.y,x,middle.y+tick.y);
  }
  if (tick.y>1) for (y=tick.y; y<bmsize.y; y+=tick.y) if (y%step.y) {
   Line(dc,middle.x-tick.x,y,middle.x+tick.x,y);
  }
 }
 SelectObject(dc,OldPen);
}

void pascal GrafLinie(HDC dc, KANAL*kanal) {
 HPEN KPen,OldPen;

 KPen=CreatePen(PS_SOLID,1,kanal->farbe);
 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; i<zeit.samples; i++, pp++) {
  pp->x=MulDiv(i,bmsize.x-1,zeit.samples);
  pp->y=y=(bmsize.y-1)/2-MulDiv(*sa++,bmsize.y-1,128);
  if (y<ymin) ymin=y;
  if (y>ymax) 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<zeit.samples; i++) {
    kanal[0].data[i]=random(10)-5;
    kanal[1].data[i]=random(15)-28;
   }
   CalcGraf(&kanal[0]);
   CalcGraf(&kanal[1]);
   dc=GetDC(Wnd);
   SetViewportOrgEx(dc,Rand.left,Rand.top,NULL);
   if (DispOpt&DO_DB) {
    MaleOsziSchirm(bltdc);
    BitBlt(dc,0,0,bmsize.x,bmsize.y,bltdc,0,0,SRCCOPY);
   }else{
    MaleOsziSchirm(dc);
   }
   ReleaseDC(Wnd,dc);
  }break;

  case WM_MOUSEMOVE:{
   HDC dc=GetDC(Wnd);
   SetViewportOrgEx(dc,Rand.left,Rand.top,NULL);
   if (DispOpt&DO_DB) Fadenkreuz(bltdc);
   Fadenkreuz(dc);
   lastmouse.x=(short)LOWORD(lParam)-Rand.left;
   lastmouse.y=(short)HIWORD(lParam)-Rand.top;
   Fadenkreuz(dc);
   if (DispOpt&DO_DB) Fadenkreuz(bltdc);
   ReleaseDC(Wnd,dc);
  }break;

  case WM_SIZE:{
   size.x=(short)LOWORD(lParam);
   size.y=(short)HIWORD(lParam);
   tick.x=size.x/11/5;
   tick.y=size.y/9/5;
   step.x=tick.x*5;	//etwas Rand lassend (später Schriftgröße einrechnen)
   step.y=tick.y*5;
   bmsize.x=step.x*10+1;
   bmsize.y=step.y*8+1;
   SetRect(&Rand,(size.x-step.x*10)/2,(size.y-step.y*8)/2,
     Rand.left+bmsize.x,Rand.top+bmsize.y);
   SetDispOpt(DispOpt,DO_DB);	// Puffer neu allokieren lassen!
  }break;

  case WM_COMMAND: switch (LOWORD(wParam)) {
   case 109: SendMessage(Wnd,WM_CLOSE,0,0);
   case 111:
   if (hSetupDlg) SetFocus(hSetupDlg);
   else hSetupDlg=CreateDialog(HInstance,MAKEINTRESOURCE(111),Wnd,SetupDlgProc);
   break;
   case 112:
   if (hDisplayDlg) SetFocus(hDisplayDlg);
   else hDisplayDlg=CreateDialog(HInstance,MAKEINTRESOURCE(112),Wnd,DisplayDlgProc);
   break;
   case 199: DialogBox(HInstance,MAKEINTRESOURCE(199),Wnd,AboutDlgProc);
  }break;

  case WM_DESTROY: {
   SetDispOpt(0,0);
   KillTimer(Wnd,1);
   PostQuitMessage(0);
  }break;
 }
 return DefWindowProc(Wnd,Msg,wParam,lParam);
}

#pragma argsused
int PASCAL WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
 static WNDCLASS wc={
   CS_DBLCLKS|CS_HREDRAW|CS_VREDRAW,
   MainWndProc,
   0,0,0,0,0,(HBRUSH)(COLOR_WINDOW+1),MAKEINTRESOURCE(100),"OSZI"};
 MSG msg;

 HInstance=hInstance;

 if (!hPrevInstance) {
  wc.hInstance=hInstance;
  wc.hIcon=LoadIcon(0,IDI_APPLICATION);
  wc.hCursor=LoadCursor(0,IDC_ARROW);
  RegisterClass(&wc);
 }
 zeit.div=0.001;
 zeit.samples=1000;
 kanal[0].div=0.001;
 kanal[0].farbe=0x000080;	// rot?
 kanal[0].data=malloc(zeit.samples*sizeof(int));
 kanal[0].poly=malloc(zeit.samples*sizeof(POINT));
 kanal[1].div=0.002;
 kanal[1].farbe=0x008080;	// gelb?
 kanal[1].data=malloc(zeit.samples*sizeof(int));
 kanal[1].poly=malloc(zeit.samples*sizeof(POINT));

 CreateWindow("OSZI","Oszilloskop",WS_VISIBLE|WS_OVERLAPPEDWINDOW,
   CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,
   0,0,hInstance,NULL);

 while (GetMessage(&msg,0,0,0)) {
  if (hKBHand && IsDialogMessage(hKBHand,&msg)) continue;
  TranslateMessage(&msg);
  DispatchMessage(&msg);
 }
 return msg.wParam;
}

Detected encoding: ANSI (CP1252)4
Wrong umlauts? - Assume file is ANSI (CP1252) encoded