Source file: /~heha/ewa/Ofen/prozess.zip/msvc/o1/hid.cpp

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