#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
|
|