Source file: /~heha/mb-iwp/NA/MSVC.zip/src/PiezoMess.h

#pragma once
#define WIN32_LEAN_AND_MEAN
#define _WIN32_WINNT 0x0501
#define _CRT_SECURE_NO_WARNINGS
#include <windows.h>
#include <windowsx.h>	// Makros
#include <shlwapi.h>	// nützliche Funktionen
#include <commctrl.h>
#define _USE_MATH_DEFINES
#include <math.h>

/************
 * Globales *
 ************/

#ifdef UNICODE
# define CF_TXT CF_UNICODETEXT
# ifndef _UNICODE
#  define _UNICODE
# endif
#else
# define CF_TXT CF_TEXT
#endif

#include <stdio.h>
#include <tchar.h>

#define elemof(x) (sizeof(x)/sizeof((x)[0]))
#define T(x) TEXT(x)
#define nobreak

#ifdef WIN32
# define Send_WM_Command(ToWnd,CtlId,NotifyCode,FromWnd)\
  SendMessage(ToWnd,WM_COMMAND,MAKELONG(CtlId,NotifyCode),(LPARAM)FromWnd);
#else	// Win16
# define Send_WM_Command(ToWnd,CtlId,NotifyCode,FromWnd)\
  SendMessage(ToWnd,WM_COMMAND,CtlId,MAKELONG((UINT)FromWnd,NotifyCode));
#endif

#ifdef _DEBUG
void _cdecl DebugPrintf(const char*,...);
# define _debug(x) DebugPrintf x
#else
# define _debug(x) {}
#endif

/*** PiezoMess.cpp ***/
extern HINSTANCE ghInstance;
extern HWND ghMainWnd;

struct RECTS{
 short left,top,right,bottom;
 void operator=(const RECT&r) {
  left=(short)r.left;
  top=(short)r.top;
  right=(short)r.right;
  bottom=(short)r.bottom;
 }
 void toRect(RECT&r) const{
  r.left=left;
  r.top=top;
  r.right=right;
  r.bottom=bottom;
 }
};

extern struct CONFIG{
 RECTS WndPos;
 char ShowCmd;
 BYTE SerialNo;		// 0 = COM1 usw.
 BYTE HidNo;
 BYTE flags;		// Bit 0 = COM oder HID
			// Bit 7 = bRunningUpdate
 BYTE GuiDelay;		// Aktualisierungsintervall in ms
}Config;

struct Trace{
 TCHAR const *name;	// Text
 TCHAR const *unit;	// Einheit
 COLORREF color;
 BYTE penwidth,penstyle;
 Trace(TCHAR const*n,TCHAR const*u,COLORREF c,BYTE w,BYTE s=PS_SOLID)
	:name(n),unit(u),color(c),penwidth(w),penstyle(s) {}
};

extern const struct Divider{
 COLORREF color;
 BYTE penwidth,penstyle;
}divider[2];

extern const struct ScaleCfg{
 TCHAR const *fontname;
 BYTE fontsize;
}scalecfg;

extern TCHAR gCsvName[MAX_PATH];
extern TCHAR sDecimal[2];	// je nach Windows-Einstellung
#ifdef _M_IX86
__forceinline __int64 llrint(double f) {
 __int64 i;
 _asm	fld	f
 _asm	fistp	i
 return i;
}
#else
__forceinline __int64 llrint(double f) {return (__int64)floor(f+0.5);}
#endif
#define lrint(x) (int)llrint(x)

void _fastcall InitStruct(PVOID,UINT);
typedef const TCHAR*PCTSTR;
int _cdecl MBox(HWND,PCTSTR,DWORD,...);
enum{
 MB_Sound	= 0x00200000L,	// Ton ausgeben
 MB_ErrorText	= 0x00400000L,	// System-Fehlerbescheibung (1. DWORD-Argument) nach 1 Leerzeile anhängen
};

extern const union _uNaN{
 __int64 ll;
 double d;
 float f;
}uNaN;
#define NaN uNaN.d
#define fNaN uNaN.f

int FloatToStringW(double f, int nk, PWSTR s, int slen);
int FloatToStringA(double f, int nk, PSTR s, int slen);

#ifdef UNICODE
#define FloatToString FloatToStringW
#else
#define FloatToString FloatToStringA
#endif

/*****************************
 * Daten vom Mikrocontroller *
 *****************************/

extern struct ADCMEAN{		// Gemittelte A/D-Werte (jeweils das 16-fache der 12-bit-A/D-Werte)
 WORD hv;		// Hochspannung, U = hv*118>>16 V
 WORD ref;		// Referenzspannung des AD8302, U = ref*2.5>>16 V, typ. 1,8 V → 47186 (0,72 @ 2,5V Uref des MSP430)
 WORD temp;		// Temperatur, T = temp*238>>16 - 85 °C
}adcmean;

extern struct FEATURE{
 short g;		// Verstärkung
 short o;		// Offset
 long fu;		// „Untere“ Wobbel-Frequenz (2^28 = 66 MHz), f = {fu|fo|fs}*66666666>>28 Hz
 long fa;		// Addierwert
 long fm;		// Multiplizierwert: f += fa + f*fm>>16
 WORD steps;		// Anzahl Wobbel-Schritte (>=10!)
 WORD hv;		// Sollspannung (Hochspannungsgenerator), U = hv*118>>16 V

 float GetFu();
 float GetFo();
 float GetT();
 bool IsLog();
 float GetHV();
 void SetFu(float v);
 void SetFo(float v);
 void SetT(float v);
 void SetLog(bool l);
 void SetHV(float v);
 void SetSteps(int v);
}feature;

#define SCALEWIDTH 50
#define FSCALE 0.248352684F	// 66.666666>>28 * 1000, Frequenz in Hz
#define TSAMPLE 303E-6F		// 1/Datenliefer-Rate in der Firmware, in s: 3,3 kSa/s
#define HVSCALE 0.0018F		// Hochspannung in V
#define REFSCALE 3876E-7F	// Referenzspannung in V
#define TEMPSCALE 363E-5F-85	// Temperatur in °C (ohne Klammer für Offset!!)

/**************************
 * Gemeinsame GDI-Handles *
 **************************/

struct myRECT:RECT{
 inline int midx() const {return (left+right)>>1;}
 inline int midy() const {return (top+bottom)>>1;}
 inline int width() const {return right-left;}
 inline int height() const {return bottom-top;}
};

extern struct GDI{	// Gemeinsam genutzte GDI-Objekte
 HFONT fntBig;
 HFONT fntScale[4];	// Schrift horizontal und vertikal, normal und fett
 HPEN penGraph[2];	// zwei Graphen dick, zwei dünn
 HPEN penDivider[2];	// Hilfslinien
 HBITMAP bmpBack;	// Doppelpufferungs-Bitmap (nur Graf, ohne Skalen)
 void init();
 void done();
}gdi;

/*** HardwareDlg.cpp ***/

INT_PTR CALLBACK HardwareDlgProc(HWND,UINT,WPARAM,LPARAM);

/*** SweepDlg.cpp ***/

extern struct UNIT{
 int Pre;		// Dezimalstellen, "k" = 3
 float Mul;		// Multiplikator, "k" = 1000
 TCHAR Chr[4];		// Einheitenvorsatz-String
 TCHAR Name[8];		// "Hz"
 TCHAR Text[8];		// Gesamter aktueller Einheitentext ("kHz")
 DWORD Typ;		// HID-Einheitentyp
 void Init(int p=0, PCTSTR n=0);	// Ãœbergabe: Dezimalstellen, Name
}FreqUnit;

enum{
 WM_ContinueInit = WM_USER+0x100,
 WM_Update,
 WM_UpdateFeature,
 WM_ChangeFeature,
 WM_ChangeUnit,
 WM_ComFail,
};

INT_PTR CALLBACK SweepDlgProc(HWND,UINT,WPARAM,LPARAM);
extern HWND hSweepDlg;

/*** SaveTsv.cpp ***/

void SaveCSV();

/*** Axis.cpp ***/

/*******************
 * Diagramm-Achsen *
 *******************/

struct AXIS{
 double a,e;		// Anfangs- und Endwert
 double tick;		// große Striche
 bool log;		// Logarithmische Darstellung?
 bool vert;		// Vertikale Achse?
 bool mirror;		// rechts- oder linksseitige Ticks?
 myRECT bbox;		// Darstellungsgrenzen (bei WM_SIZE nachführen!)
 int nk;		// Nachkommastellen (oder besser: Formatbezeichner für Zahlenausgabe??)
// void Draw(HDC) const;	// TODO: Hervorhebung Nulllinie, Verteilung der Zahlen
 double FromNative(double) const;	// skaliert einen Wert 0..1 auf a..e
 double ToNative(double) const;	// skaliert einen Wert a..e auf 0..1
 bool okay() const;	// Kein NaN bei a, e, tick; e>a bei tick>0
 bool beyond(double) const;
 double begin() const;
 double next(double) const;
 void AutoCalcTicks();
};

struct XAXIS:AXIS {
 TCHAR const *name;	// Text
 TCHAR const *unit;	// Einheit
 void Draw(HDC) const;
};

struct YAXIS:AXIS {
 Trace *trace;
 void Draw(HDC) const;
};

/*** Sweep.cpp ***/

struct SDATA{		// So kommen die Daten von der seriellen Schnittstelle
 char ap[3];
 inline unsigned short amp() const {return *(unsigned short*)ap&0xFFF;}		// Amplitudenwert
 inline unsigned short pha() const {return *(unsigned short*)(ap+1)>>4;}	// Phasenwert, 0 = ±90°
};

extern struct SWEEP{	// Irreführender Name: Diagramm!
 int width;		// Anzahl erwarteter Samples
 int nsamp;		// Anzahl eingelesener Messwerte (von fstart gerechnet)
 myRECT bbox;		// nur für das Diagramm
 HANDLE hMutex;
 XAXIS x;
 YAXIS amp,pha;
 void Draw(HDC dc, bool all=true) const;
 void Resize(int cx, int cy);
 void Resize(LPARAM lP) {Resize(GET_X_LPARAM(lP),GET_Y_LPARAM(lP));};
 void ChangeScale();
 void GenXPositions(const RECT*rcBack, POINT*pt) const;
 void GenYPositions(const RECT*rcBack, POINT*pt, const SDATA *data, bool pha=false) const;
 SDATA *data, **backup;
 int nbackup;		// Anzahl Backups im <backup>-Vektor
 int writtento;		// letztes beschriebens Sample von data
}sweep;
#if 0
union IF4{
 long i;
 float f;
};

struct SINFO{		// Sample-Info, ähnlich HIDP_???
 IF4 minLog, maxLog;
 IF4 minPhys, maxPhys;
 char unitExp;
 long unitCode;
 WORD bitOffset;	// 0..65535, typ. einige Bits
 BYTE bitLen;		// 1..32
 WORD strucLen;		// max. 8 KByte, typ. einige Byte
 long GetI4(const void*data, int i) {
  const BYTE*p=(const BYTE*)data;
  p+=i*strucLen+(bitOffset>>3);
  long r;
  memcpy(&r,p,(bitLen+(bitOffset&7)+7)>>3);
  char w=32-bitLen;
  r<<=w-(bitOffset&7);		// SLL: Barrel-Shift MSB-bündig
  if (minLog.i<0) {
   r>>=w;			// SRA (vorzeichenbehaftet)
  }else{
   *(unsigned long*)&r>>=w;	// SRL (vorzeichenlos)
  }
  return r;
 }
};
#endif

/*** Worker.cpp ***/

extern struct WORKER{
 void start(HWND);
 void stop();
 void post(BYTE c, void*data, int dlen);
// bool okay()	{return hCom!=0;}
protected:
 HANDLE hCom;
 HANDLE hThread;
 OVERLAPPED o;		// <hCancel> MUSS sich direkt nach <o> befinden!!
 HANDLE hCancel;	// Thread soll beendet werden
 DWORD ThreadId;
 HWND InfoWnd;
// static const int timeout_ms=80;
 void ThreadProc();
 static DWORD CALLBACK ThreadProc(PVOID p) {((WORKER*)p)->ThreadProc(); return 0;}
 void OpenCom();
 void clear();
 int wait();
 int send(const void*buf, int buflen);	// Synchrones Datensenden
 int recv(void*buf, int buflen);	// Synchroner Datenempfang
 int GetData(char command, void*buf, int buflen);
 int SetData(char command, const void*buf, int buflen);
}w;
Detected encoding: UTF-80