#include "main.h"
SP_CLASSIMAGELIST_DATA HIDDEV::ild;
void HIDDEV::Enum(HWND hCombo,FILTFUNC mine) {
COMBOBOXEXITEM cbei;
TCHAR buf[12];
if (!IS_INTRESOURCE(hCombo)) {
cbei.mask=CBEIF_TEXT|CBEIF_IMAGE|CBEIF_SELECTEDIMAGE;
cbei.pszText=buf;
cbei.iItem=0;
SetupDiGetClassImageIndex(&ild,(LPGUID)&GUID_DEVCLASS_HIDCLASS,&cbei.iImage);
cbei.iSelectedImage=cbei.iImage;
ComboBox_ResetContent(hCombo);
SetWindowText(hCombo,0);
}
GUID hidGuid;
HidD_GetHidGuid(&hidGuid);
HDEVINFO devs=SetupDiGetClassDevs(&hidGuid,0,0,DIGCF_PRESENT|DIGCF_DEVICEINTERFACE);
if (devs!=INVALID_HANDLE_VALUE) {
SP_DEVICE_INTERFACE_DATA di;
for (DWORD i=0; di.cbSize=sizeof di,SetupDiEnumDeviceInterfaces(devs,0,&hidGuid,i,&di);i++) {
struct{
SP_DEVICE_INTERFACE_DETAIL_DATA d;
TCHAR space[MAX_PATH];
}d;
d.d.cbSize=sizeof d.d;
if (SetupDiGetDeviceInterfaceDetail(devs,&di,&d.d,sizeof d,0,0)) {
HANDLE h=CreateFile(d.d.DevicePath,GENERIC_READ|GENERIC_WRITE,
FILE_SHARE_READ|FILE_SHARE_WRITE,0,OPEN_EXISTING,FILE_FLAG_OVERLAPPED,0);
if (h!=INVALID_HANDLE_VALUE) {
PHIDP_PREPARSED_DATA pd;
if (HidD_GetPreparsedData(h,&pd)) {
HIDP_CAPS hidcaps;
/* Match auf HID-Gerät das passt */
if ((int)HidP_GetCaps(pd,&hidcaps)>=0
&& mine(h,pd,&hidcaps)) {
if (!IS_INTRESOURCE(hCombo)) {
wsprintf(buf,TEXT("HID%u"),cbei.iItem);
SendMessage(hCombo,CBEM_INSERTITEM,0,(LPARAM)&cbei);
if (cbei.iItem==Config.HidNo) ComboBox_SetCurSel(hCombo,cbei.iItem);
cbei.iItem++;
}else if (!hCombo) {
hDev=h;
this->pd=pd;
this->hidcaps=hidcaps;
maxreport=max(max(hidcaps.InputReportByteLength,hidcaps.OutputReportByteLength),hidcaps.FeatureReportByteLength);
report=new BYTE[maxreport];
goto raus;
}else hCombo--;
}
HidD_FreePreparsedData(pd);
}
CloseHandle(h);
}
}
}
raus:
SetupDiDestroyDeviceInfoList(devs);
}
}
void HIDDEV::Close() {
if (report) {delete[] report; report=0;}
if (pd) {HidD_FreePreparsedData(pd); pd=0;}
if (hDev) {CloseHandle(hDev); hDev=0;}
}
/********************************************************
* Spezialisiertes HID-Gerät: Unser Ofentemperturregler *
********************************************************/
bool REGLER::mine(HANDLE,PHIDP_PREPARSED_DATA,PHIDP_CAPS hidcaps) {
return hidcaps->InputReportByteLength==sizeof reportI
&& hidcaps->OutputReportByteLength==3
&& hidcaps->FeatureReportByteLength>=16;
}
void REGLER::onInputReport() {
reportI*pmsg=(reportI*)regler.report;
byte raw=Config.rawview;
SetCheckboxGroup(hMainWnd,56,63,pmsg->flags);
for (int i=64; i<=71; i++) {
HWND w=GetDlgItem(hMainWnd,i);
if (!w) continue;
if (w==GetFocus()) continue;
char s[33];
switch (i) {
case 64: bin2s(s,pmsg->relays,8); break;
case 65: bin2s(s,pmsg->inputs,8); break;
case 66: switch (raw) {
case 0: time2s(s,pmsg->runTime,reportk.tp_ms); break;
case 1: d2s(s,pmsg->runTime); break;
case 2: hex2s(s,pmsg->runTime,4); break;
}break;
case 67: switch (raw) {
case 0: dec2s(s,pmsg->heatPower,reportk.P_mW); break;
case 1: d2s(s,pmsg->heatPower); break;
case 2: hex2s(s,(WORD)pmsg->heatPower,4); break;
}break;
case 68:
case 69:
case 70:
case 71: switch (raw) {
case 0: dec2s(s,(&pmsg->tempSoll)[i-68],reportk.T_mK); break;
case 1: d2s(s,(&pmsg->tempSoll)[i-68]); break;
case 2: hex2s(s,((WORD*)&pmsg->tempSoll)[i-68],4); break;
}break;
}
SetWindowTextA(w,s); // generiert EN_CHANGE, das wiederum setzt den Timer
KillTimer(hMainWnd,i);
}
SendDlgItemMessage(hMainWnd,16,PM_ADDSAMPLES,0,(LPARAM)&pmsg->tempIst);
}
void REGLER::setValue(BYTE id) {
char s[32];
HWND w=GetDlgItem(hMainWnd,id);
GetWindowTextA(w,s,32);
byte raw=Config.rawview;
bool ok=false;
if (regler.hDev) {
union vptr{WORD w;short s;byte b;bool bo;}*p=(vptr*)(regler.report+1);
switch (id) {
case 56: // ein/aus
case 57: ok=true; p->bo=!!IsDlgButtonChecked(hMainWnd,id); break;
case 64: ok=s2bin(s,p->b); break; // Relais
case 66: switch (raw) {
case 0: ok=s2time(s,p->w,reportk.tp_ms); break; // Zeit
case 1: {double v; ok=s2d(s,v) && 0<=v && v<65536; p->w=(WORD)v;} break;
case 2: goto case2;
}break;
case 67: switch (raw) {
case 0: ok=s2dec(s,p->s,reportk.P_mW); break; // Heizleistung
case 1: goto case1;
case 2: goto case2;
}break;
case 68: switch (raw) {
case 0: ok=s2dec(s,p->s,reportk.T_mK); break; // Solltemperatur
case 1: case1: {double v; ok=s2d(s,v) && -32767<v && v<+32767; p->s=(short)v;} break;
case 2: case2: ok=s2hex(s,p->w);
}break;
}
if (ok) {
regler.report[0]=id;
if (!regler.setoutput()) MessageBeep(0);
return;
}
}
MessageBeep(0);
Edit_SetSel(w,0,-1);
SetFocus(w);
}
// Statisches Objekt (Singleton)
REGLER regler;
REGLER::reportK REGLER::reportk;
Detected encoding: UTF-8 | 0
|