#include "vipsys3.h"
#include <windows.h>
#include <windowsx.h>
#include <setupapi.h>
#include <devguid.h>
//#include <shlwapi.h>
//#include <commctrl.h>
#include <stdio.h>
#include <tchar.h>
//#include "analyzer.h"
#include "tabdata.h"
/*******************
* Hilfsfunktionen *
*******************/
static const DCB DefDcb={
sizeof(DefDcb),9600,
1,0,1,0,1,0,1,0,0,0,0,2,1,0,
0,2048,512,7,2,0,0x11,0x13,0,0,'\n',0};
static TCHAR stCom[]=T("COM%u");
void DLGCONFIG::SetDCB(DCB&dcb, BYTE cfg) {
dcb=DefDcb; // ganze Struktur kopieren!
dcb.ByteSize=7+(cfg&1);
dcb.StopBits=cfg&2;
dcb.Parity=(cfg>>=2)&3;
dcb.BaudRate=300<<(cfg>>=2);
dcb.fParity=dcb.Parity?1:0;
}
static BYTE GetSerialConfigByte(const DCB&dcb) {
BYTE cfg=0;
int i=dcb.BaudRate/300;
while (i>>=1) cfg++;
cfg<<=2;
cfg|=dcb.Parity&3;
cfg<<=2;
cfg|=dcb.StopBits&2;
cfg|=(dcb.ByteSize-7)&1;
return cfg;
}
void DLGCONFIG::ParameterDlg() {
TCHAR ComName[8];
COMMCONFIG cc;
InitStruct(&cc,sizeof(cc));
SetDCB(cc.dcb,serialCfg);
_sntprintf(ComName,elemof(ComName),stCom,serialNo+1);
if (!CommConfigDialog(ComName,Wnd,&cc)) return;
serialCfg=GetSerialConfigByte(cc.dcb);
}
INT_PTR CALLBACK DLGCONFIG::DlgProc(HWND Wnd, UINT Msg, WPARAM wParam, LPARAM lParam) {
DLGCONFIG *p=(DLGCONFIG*)GetWindowLongPtr(Wnd,DWLP_USER);
switch (Msg) {
case WM_INITDIALOG: {
SetWindowLongPtr(Wnd,DWLP_USER,lParam);
p=(DLGCONFIG*)lParam;
p->Wnd=Wnd;
SetCheckboxGroup(Wnd,110,114,p->checkBits);
SendMessage(Wnd,WM_TIMER,1,0);
}return TRUE;
case WM_DEVICECHANGE: SetTimer(Wnd,1,2500,NULL); break;
case WM_TIMER: {
// serielle Schnittstellen (neu) listen (bei jedem WM_DEVICECHANGE bspw. für USB)
HWND hCombo=GetDlgItem(Wnd,101);
ComboBox_ResetContent(hCombo);
HANDLE devs=SetupDiGetClassDevs((GUID*)&GUID_DEVCLASS_PORTS,NULL,0,DIGCF_PRESENT);
if (devs!=INVALID_HANDLE_VALUE) {
SP_DEVINFO_DATA devInfo;
devInfo.cbSize=sizeof devInfo;
for (UINT i=0; SetupDiEnumDeviceInfo(devs,i,&devInfo); i++) {
HKEY hKey;
TCHAR s[16];
DWORD slen=sizeof s;
*s=0;
if ((hKey=SetupDiOpenDevRegKey(devs,&devInfo,DICS_FLAG_GLOBAL,0,DIREG_DEV,KEY_READ))
==INVALID_HANDLE_VALUE) continue;
RegQueryValueEx(hKey,T("PortName"),NULL,NULL,(LPBYTE)s,&slen);
RegCloseKey(hKey);
if (*s=='C') { // assume COMx, filter out LPTx
int idx=ComboBox_AddString(hCombo,s);
int num=_ttoi(s+3)-1; // zero-based
ComboBox_SetItemData(hCombo,idx,num);
if (num==p->serialNo) ComboBox_SetCurSel(hCombo,idx);
}
}
SetupDiDestroyDeviceInfoList(devs);
}
}break;
case WM_COMMAND: switch (LOWORD(wParam)) {
case 101: if (HIWORD(wParam)==CBN_SELCHANGE) {
p->serialNo=(BYTE)ComboBox_GetItemData((HWND)lParam,ComboBox_GetCurSel((HWND)lParam));
}break;
case 102: p->ParameterDlg(); break;
case 1: {
p->checkBits=GetCheckboxGroup(Wnd,110,114);
}nobreak;
case 2: EndDialog(Wnd,wParam); break;
}
}
return FALSE;
}
BOOL EnableDlgItem(HWND Wnd, UINT Id, BOOL Enable) {
if (Enable) Enable=TRUE;
return EnableWindow(GetDlgItem(Wnd,Id),Enable);
}
/************************************
* Was gibt's denn alles überhaupt? *
************************************
ESC M: Record-Nummer (null-basiert), wenn die Daten kommen (Zahlenbasis 62)
Jedes weitere Tarifband 9 weitere Records
1aptttt 2aptttt 3aptttt Saptttt N D (momentan - Average - Peak - Tarifband 1-4)
f 0
I 0 0 0 0 1
U 1 1 1 1 222
P 23I 23I 33I 34I
S 45J 45J 45J 45J
Q 56K 66K 67K 67K
d 77L 78L 78L 78L
c 88 MVen 89 MVen 89 MVen 89 MVen
t 9 MVen 9 MVen 9 NVen A NWfo
W A NWfo C PYhq E Rajs G Tclu
X
Y B OXgp D QZir F Sbkt H Udmv
aux H
ESC mn: Welches n?
1aptttt 2aptttt 3aptttt Saptttt N D
U 2 3 4 1 555
I 2 3 4 1 5
P 2 3 4 1
666 666 666 666 alternativ, 3 Records (1-basiert: 112 122 123 123)
S 777 777 777 777 3 Records
Q 888 888 888 888 3 Records
c 2A BCDE 3A BCDE 4A BCDE 1A BCDE A = 9 Records (1 1 1 1)
t A BCDE A BCDE A BCDE A BCDE A = 9 Records (1 1 2 2)
d 999 999 999 999 2 Records (112 112 112 112)
f 5
W A BCDE A BCDE A BCDE A BCDE A = 9 Records (2 4 6 8)
X
Y A BCDE A BCDE A BCDE A BCDE A = 9 Records (3 5 7 9)
aux F
*/
union ESTIMATE{
DWORD u;
struct{
BYTE requests;// number of different requests (ESC M and ESC mn) needed
BYTE records; // number of STRING records to transfer
WORD ms; // estimated time, for 9600-e-7-1
};
static DWORD estimate(BYTE prefer, VALUE3 val[], unsigned len); // The val[] array must be LocalAlloc(LPTR)ed!
BYTE best(VALUE3 val[], unsigned len); // After function call, the array is compacted to type VALUE!
};
DWORD ESTIMATE::estimate(BYTE prefer, VALUE3 val[], unsigned len) {
ESTIMATE r;
r.u=0;
BYTE *f=(BYTE*)LocalAlloc(LPTR,len); // flag buffer for finished values
BYTE q=prefer;
do{
BYTE records=0;
for (unsigned i=0; i<len; i++) {
if (!f[i]) for (unsigned j=0; j<val[i].info.count; j++) {
if (val[i].loc[j].n!=q) continue;
f[i]++; // mark checked
if (records<val[i].loc[j].record) records=val[i].loc[j].record;
}
}
if (records) {
r.requests++;
r.records+=records;
}
q=(q+1)&0x0F;
}while(q!=prefer);
LocalFree(f);
r.ms=r.records*80+r.requests*250;
return r.u;
}
BYTE ESTIMATE::best(VALUE3 val[], unsigned len) {
ESTIMATE e[16];
WORD best_ms=0xFFFF;
BYTE r;
unsigned i;
// Now, pick-up an optimum retrieving (how to solve??)
// At first, calculate preferring ESC M. Then prefer ESC m1, etc.
for (i=0; i<16; i++) {
e[i].u=estimate(i,val,len);
// Then pick up best value
if (best_ms>e[i].ms) {
best_ms=e[i].ms;
r=(BYTE)i;
}
}
u=e[r].u; // set member variable
VALUE3*s=val;
VALUE*d=(VALUE*)s;
for (i=0; i<len; i++) {
unsigned k;
BYTE l=0xFF;
for (unsigned j=0;j<s->info.count;j++) {
if (l>s->loc[j].n-r) l=s->loc[j].n-r, k=j; // Find the same record as in estimate() routine
}
d->info.u=s->info.u;
d->info.count=0;
d->loc.u=s->loc[k].u;
d++, s++;
}
LocalReAlloc(val,len*sizeof(VALUE),0);
return r;
}
bool ESCM::makebuffers(VALUE*v,unsigned lv) {
unsigned i;
for (i=0; i<16; i++) {
if (data[i]) LocalFree(data[i]);
data[i]=NULL;
len[i]=0;
}
for (i=0; i<lv; i++, v++) {
unsigned n=v->loc.n;
unsigned l=v->loc.offset+(v->info.valsize&0x0F);
if (len[n]<l) len[n]=l;
}
for (i=0; i<16; i++) {
if (len[i]) {
if (!(data[i]=(BYTE*)LocalAlloc(LPTR,len[i]))) return false;
}
}
return true;
}
struct dlgDATASEL:DLGDATASEL{
HWND Wnd;
void HandleChange(DWORD) const;
void EnableCheck(UINT,BOOL) const;
void DisableCheck(UINT bit,BOOL dis) const {EnableCheck(bit,!dis);};
void HandleCheck(UINT);
void CalcLength() const;
static INT_PTR CALLBACK UpDownEditProc(HWND,UINT,WPARAM,LPARAM);
static void HandleScroll(HWND,int);
};
void dlgDATASEL::CalcLength() const{
VALUE3 *val,*p;
BYTE n=0;
p=val=(VALUE3*)LocalAlloc(LPTR,256*sizeof(VALUE3));
for (BYTE t=0; t<=sel.tariff; t++) {
BYTE b=0x10; // start with frequency (Hz)
BYTE k,r;
do{ // go all combinations
BYTE add=1;
k=b&0x0F; // column
r=b>>4; // row (measure)
if (t && (k&12)!=4) continue;// short-circuit, only averages for tariff bands available
if (sel.u&1<<r) { // allowed measure (row)
if (k==12) { // "special" column, for f, I, U, and a
switch (r) {
case 1: if (sel.u&0xF0000UL) break; continue; // include if any of {1-2-3-S} is checked
case 2: if (sel.n) break; continue; // include if N column is checked
case 3: add=3; if (sel.v) break; continue; // include if D column is checked
case 13:if (sel.u&0x70000UL) break; continue; // include if any of {1-2-3} is checked
default: continue; // short-circuit for non-available items
}
if (!sel.inst) continue; // These are all instanteous measures!
}else{
switch (r) { // accumulated measures are always included, independent of inst/avg/peak selection
case 10:
case 11:
case 12: break;
default:
if (!(1<<(k>>2) & sel.u>>24)) continue; // (k>>2) -> 0=inst, 1=avg, 2=peak, 3 should not occur here
}
if (!(1<<(k&3) & sel.u>>16)) continue; // (k&3) -> 0..3, channel nummer 1-2-3-S
}
// Now, this measure is allowed by user, but is this available by VIPsys3 device?
p->info.valcode=b;
p->info.tariff=t;
p->locate();
if (p->info.count) {
p++; // Yes, it's available in at least one protocol, move pointer
n+=add; // count available measurements
}
}
}while ((b+=k==12?4:1)<0xF0); // end with reactive work (kvarh)
}
ESTIMATE e;
e.best(val,int(p-val)); // now, val is a pointer to VALUE (not VALUE3) items
char s[100];
wsprintfA(s,"Anzahl Messwerte: %d\r\nAnfragen: %u, Records: %u\r\nGeschätzte Transferzeit: %u ms",
n,e.requests,e.records,e.ms);
SetDlgItemTextA(Wnd,48,s);
LocalFree(val);
}
void dlgDATASEL::EnableCheck(UINT bit, BOOL ena) const{
EnableDlgItem(Wnd,16+bit,ena);
CheckDlgButton(Wnd,16+bit,ena?sel.u>>bit&1:0); // remove checkmark for disabled buttons, and re-check on enabling
}
void dlgDATASEL::HandleChange(DWORD m) const{
DWORD ch=1<<2|1<<24; // Current on/off / inst. on/off?
if (m&ch) DisableCheck(20,~sel.u&ch); // Column for neutral current
ch=1<<3|1<<24; // Voltage on/off / inst. on/off?
if (m&ch) DisableCheck(21,~sel.u&ch);
ch=1<<24;
if (m&ch) { // inst./avg./peak values (column selection)
EnableCheck(1,sel.u&ch); // frequency: only inst.
EnableCheck(2,sel.u&ch); // current: only inst.
EnableCheck(3,sel.u&ch); // voltage: only inst.
EnableCheck(13,sel.u&ch); // Same for auxiliary values
}
ch=7<<24;
if (m&ch) {
EnableCheck(4,sel.u&ch); // power: all
EnableCheck(5,sel.u&ch);
EnableCheck(6,sel.u&ch);
EnableCheck(7,sel.u&ch); // distortion: all
EnableCheck(8,sel.u&3<<24); // cos phi: no peak
EnableCheck(9,sel.u&2<<24); // tan phi: only avg.
}
if (m&0x7003FFEUL) {
ch=((sel.u>>16)|~0x200)&sel.u&0x3FFEUL; // AND the "avg" bit with the "tan phi" bit
if (!(sel.u&0x7001400UL)) ch=0; // nothing to check
EnableCheck(16,ch);
EnableCheck(17,ch);
EnableCheck(18,ch);
EnableCheck(19,ch);
}
if (m&0x2001700UL) {
ch=((sel.u>>16)|~0x200)&sel.u&0x1700UL; // AND the "avg" bit with the "tan phi" bit
if (!(sel.u&0x2001400UL)) ch=0; // nothing to check
if (ch) {
if (!IsWindowEnabled(GetDlgItem(Wnd,44))) {
SetDlgItemInt(Wnd,44,sel.tariff,FALSE);
EnableDlgItem(Wnd,44,ch);
}
}else{
if (IsWindowEnabled(GetDlgItem(Wnd,44))) {
EnableDlgItem(Wnd,44,ch); // Solve recursion problem by disabling first
SetDlgItemInt(Wnd,44,0,FALSE); // show a zero if disabled
}
}
}
CalcLength();
}
void dlgDATASEL::HandleCheck(UINT id) {
DWORD m=1L<<(id-16);
BOOL sw=IsDlgButtonChecked(Wnd,id);
if (sw) sel.u|=m;
else sel.u&=~m;
HandleChange(m);
}
void dlgDATASEL::HandleScroll(HWND Wnd, int dir) {
dlgDATASEL *p=(dlgDATASEL*)GetWindowLongPtr(GetParent(Wnd),DWLP_USER);
if (!p) return;
dir+=p->sel.tariff;
if (dir<0) dir=0;
if (dir>4) dir=4;
if (p->sel.tariff!=(unsigned)dir) {
p->sel.tariff=dir;
DWORD Sel[2];
SendMessage(Wnd,EM_GETSEL,(WPARAM)Sel,(LPARAM)(Sel+1));
SetDlgItemInt(GetParent(Wnd),44,dir,FALSE);
Edit_SetSel(Wnd,Sel[0],Sel[1]);
}else MessageBeep(MB_ICONEXCLAMATION);
}
static WNDPROC DefEditProc;
INT_PTR CALLBACK dlgDATASEL::UpDownEditProc(HWND Wnd,UINT Msg,WPARAM wParam,LPARAM lParam) {
switch (Msg) {
case WM_VSCROLL: switch (LOBYTE(wParam)) {
case SB_LINEUP: HandleScroll(Wnd,1); break;
case SB_LINEDOWN: HandleScroll(Wnd,-1); break;
}break;
case WM_KEYDOWN: switch (wParam) {
case VK_UP: HandleScroll(Wnd,1); return 0;
case VK_DOWN: HandleScroll(Wnd,-1); return 0;
}break;
}
return CallWindowProc(DefEditProc,Wnd,Msg,wParam,lParam);
}
INT_PTR CALLBACK DLGDATASEL::DlgProc(HWND Wnd, UINT Msg, WPARAM wParam, LPARAM lParam) {
dlgDATASEL *p=(dlgDATASEL*)GetWindowLongPtr(Wnd,DWLP_USER);
switch (Msg) {
case WM_INITDIALOG: {
SetWindowLongPtr(Wnd,DWLP_USER,lParam);
p=(dlgDATASEL*)lParam;
p->Wnd=Wnd;
DefEditProc=SubclassWindow(GetDlgItem(Wnd,44),dlgDATASEL::UpDownEditProc);
SetCheckboxGroup(Wnd,16,16+27,p->sel.u);
SetDlgItemInt(Wnd,44,p->sel.tariff,FALSE);
p->HandleChange((DWORD)-1);
}return TRUE;
case WM_COMMAND: switch (LOBYTE(wParam)) {
case 1:
case 2: EndDialog(Wnd,wParam); break;
case 44: switch (HIWORD(wParam)) {
case EN_CHANGE: { // even triggered by SetDlgItemInt() invoked by HandleScroll()
if (!IsWindowEnabled((HWND)lParam)) break;
BOOL b;
DWORD t=GetDlgItemInt(Wnd,44,&b,FALSE);
if (b && t<=4) {
p->sel.tariff=t;
p->CalcLength();
}else MessageBeep(MB_ICONEXCLAMATION);
}break;
}break;
case 64: { // nothing (visible) checked (leaving phase bits)
p->sel.u&=0x00FF0000UL;
SetCheckboxGroup(Wnd,16,16+27,p->sel.u);
SetDlgItemInt(Wnd,44,p->sel.tariff,FALSE);
p->HandleChange((DWORD)-1);
}break;
case 65: { // all checked
p->sel.u=0x473F3FFE;
SetCheckboxGroup(Wnd,16,16+27,p->sel.u);
SetDlgItemInt(Wnd,44,p->sel.tariff,FALSE);
p->HandleChange((DWORD)-1);
}break;
default: {
p->HandleCheck(LOBYTE(wParam));
}
}
}
return FALSE;
}
Detected encoding: ANSI (CP1252) | 4
|
|