[english]

Quelltext /~heha/hs_freeware/Funkuhr.zip[Download]/src/DlgHardware.c

Zeilennummern anzeigen
/********************************
 * Projekt: Funkuhr DCF77	*
 * Eigenschaftsseite äHardwareô	*
 * Auswahl serielles oder	*
 * Parallelport + Leitung	*
 ********************************/

#include "Funkuhr.h"
#include <devguid.h>
#include <dbt.h>
#include <hidsdi.h>
#include <hidpi.h>

/*
// Eine Reihe aufeinanderfolgender Fenster ein- oder ausschalten
static void EnableWindows(HWND Wnd, UINT count, BOOL state) {
 for (; count; Wnd=GetNextSibling(Wnd),count--) {
  EnableWindow(Wnd,state);
 }
}
*/
// Je nach Config.Where Dialogelemente sichtbar machen
static void ShowWhere(HWND Wnd) {
 int i;
 for (i=0; i<6; i++) {
  int j=i*0x10+0x20;
  int k;
  HWND w;
  for (w=GetDlgItem(Wnd,j); w && ((k=(short)GetDlgCtrlID(w))==-1 || k<j+0x10); w=GetNextSibling(w)) {
   ShowWindow(w,Config.Where==i ? SW_SHOW : SW_HIDE);
  }
 }
}

#ifdef UNICODE
int ComboBox_AddStringA(HWND Wnd, const char*s) {
 TCHAR buf[64];
 MultiByteToWideChar(CP_ACP,0,s,-1,buf,elemof(buf));
 return ComboBox_AddString(Wnd,buf);
}
#else
# define ComboBox_AddStringA ComboBox_AddString
#endif

// Fⁿllt Combobox mit doppelnullterminierter Item-Liste
static void FillCombo(HWND Wnd,const char*Items,int CurSel) {
 for(;*Items;Items+=lstrlenA(Items)+1) ComboBox_AddStringA(Wnd,Items);
 ComboBox_SetCurSel(Wnd,CurSel);
}

static const WORD DefAddrs[]={0x378,0x278,0x3BC,0x201};

// Fⁿllt Combobox mit typischen Parallelportadressen
static void FillComboAddrs(HWND Wnd) {
 int i;
 bool set=false;
 TCHAR buf[20];
 for (i=0; i<elemof(DefAddrs); i++) {
  if (i<3) wnsprintf(buf,elemof(buf),T("%Xh (%u, LPT%u)"),DefAddrs[i],DefAddrs[i],i+1);
  else wnsprintf(buf,elemof(buf),T("%Xh (Joystick)"),DefAddrs[i]);
  ComboBox_AddString(Wnd,buf);
  if (Config.ParallelAddr==DefAddrs[i]) {
   ComboBox_SetCurSel(Wnd,i);
   set=true;
  }
 }
 if (!set) {
  wnsprintf(buf,elemof(buf),T("%03Xh"),Config.ParallelAddr);
  SetWindowText(Wnd,buf);
 }
}

static void FillComboBits(HWND Wnd, BYTE Current) {
 static const char ParallelLines[]=	// ab Bitadresse 0
  "D0 (2)\0D1 (3)\0D2 (4)\0D3 (5)\0D4 (6)\0D5 (7)\0D6 (8)\0D7 (9)\0"
  "ERR (15)\0ONL (13)\0PE (12)\0ACK (10)\0BSY (11)\0"
  "STB (1)\0AF (14)\0INI (16)\0SEL (17)\0";
 static const char JoystickLines[]=	// ab Bitadresse 4, nur EingΣnge
  "TA1 (2)\0TA2 (7)\0TB1 (10)\0TB2 (14)\0";
 int i,j;
 const char *p;
 ComboBox_ResetContent(Wnd);
 if (Current&0x80) {	// UsbPrn-Modus
  p=ParallelLines;
  for (i=0; i<11; i++) {
   if (i>=8) ComboBox_AddStringA(Wnd,p);
   p+=lstrlenA(p)+1;
  }
  ComboBox_SetCurSel(Wnd,Current-0x80-013);
 }else{			// InpOut32-Modus
  for (i=0; i<elemof(DefAddrs); i++) {
   if (Config.ParallelAddr==DefAddrs[i]) {
    i= i==3 ? 4 : 0;	// Start-Bitadresse
    p= i ? JoystickLines : ParallelLines;
    if (i && !Current) {	// Sonderfall Jostick-Stromversorgung
     ComboBox_AddStringA(Wnd,"Ucc (1,8,9,15)");
     ComboBox_SetCurSel(Wnd,0);
     return;
    }
    for(;*p;p+=lstrlenA(p)+1) {
     j=ComboBox_AddStringA(Wnd,p);
     ComboBox_SetItemData(Wnd,j,i);	// Bitnummer zuordnen
     if (i==Current) ComboBox_SetCurSel(Wnd,j);
     i++; if (i==8) i+=3;	// nΣchstes Bit, 3 fehlende IN-Leitungen ⁿberspringen
    }
    return;
   }
  }
  for (i=0; i<8; i++) {
   TCHAR buf[16];
   wnsprintf(buf,elemof(buf),T("Bit %u"),i);
   ComboBox_AddString(Wnd,buf);
   ComboBox_SetItemData(Wnd,i,i);
   if (i==Current) ComboBox_SetCurSel(Wnd,i);
  }
 }
}

// Wenn die Parallelport-Adresse verΣndert wurde,
// FALSE bei falscher Angabe
static bool OnParallelAddrChange(HWND Wnd) {
 TCHAR buf[16];
 int a;
 buf[0]='0';
 buf[1]='x';
 GetDlgItemText(Wnd,0x31,buf+2,elemof(buf)-2);
 if (!StrToIntEx(buf,STIF_SUPPORT_HEX,&a)) return false;
 if (HIWORD(a)) return false;	// >FFFFh
 if (!HIBYTE(a)) return false;	// <100h
 if (Config.ParallelAddr==(WORD)a) return true;	// unverΣndert
 Config.ParallelAddr=(WORD)a;	// zuweisen
 if (Config.ParallelAddr==DefAddrs[3]) {	// Sonderfall Joystick
  if (Config.ParallelLineIn<4) Config.ParallelLineIn=4;
  Config.ParallelLineOut=0;
 }
 FillComboBits(GetDlgItem(Wnd,0x32),Config.ParallelLineIn);
 FillComboBits(GetDlgItem(Wnd,0x33),Config.ParallelLineOut);
 RestartEmpfang();
 return true;
}

static void PrepareRedString(HWND Wnd) {
 TCHAR s[64],t[64];
 GetWindowText(Wnd,t,elemof(t));
 wnsprintf(s,elemof(s),t,INPOUTDLL);
 SetWindowText(Wnd,s);
 SendMessage(Wnd,WM_SETFONT,(WPARAM)GdiObj.fnFett,FALSE);
}

// Bei Auswahl einer Soundkarte à
static void FillSamplerates(HWND Wnd) {
 WAVEINCAPS wc;
 static const int PossibleRates[]={8000,11025,16000,22050,32000,44100,48000,96000,192000,200000};
 if (!waveInGetDevCaps(Config.iSoundCard,&wc,sizeof wc)) {
  HWND w=GetDlgItem(Wnd,0x42);
  WAVEFORMATEX wf;
  int j,r=Config.iSampleRate*1000;
  TCHAR s[32];
  ComboBox_ResetContent(w);
//  for (j=0; j<elemof(PossibleRates); j++) {
//   if (Config.iSampleRate==PossibleRates[j]/1000) r=PossibleRates[j];
//  }
  wnsprintf(s,elemof(s),T("%d"),r);
  SetWindowText(w,s);
  wf.wFormatTag=WAVE_FORMAT_PCM;
  wf.nChannels=1;
  wf.wBitsPerSample=16;
  wf.nBlockAlign=2;
  for (j=0; j<elemof(PossibleRates); j++) {
   wf.nSamplesPerSec=PossibleRates[j];
   wf.nAvgBytesPerSec=wf.nSamplesPerSec*wf.nBlockAlign;
   if (!waveInOpen(NULL,Config.iSoundCard,&wf,0,0,WAVE_FORMAT_QUERY)) {
    int idx;
    wnsprintf(s,elemof(s),T("%d"),wf.nSamplesPerSec);
    idx=ComboBox_AddString(w,s);
    if (Config.iSampleRate==wf.nSamplesPerSec/1000) ComboBox_SetCurSel(w,idx);
   }
  }
 }
}

// Bei Auswahl eines Joysticks à
static void FillButtons(HWND Wnd) {
 JOYCAPS jc;
 if (!joyGetDevCaps(Config.iJoystick,&jc,sizeof jc)) {
  TCHAR s[64],*p=s;
  HWND w=GetDlgItem(Wnd,0x52);
  int j;
  ComboBox_ResetContent(w);
  for (j=0; j<(int)jc.wNumButtons; j++) {
   wnsprintf(s,elemof(s),T("%d"),j+1);	// sind unter Windows 1-basiert
   ComboBox_AddString(w,s);
  }
  ComboBox_SetCurSel(w,Config.iJoyButton&0x1F);
//verwirrt!  EnableWindow(w,jc.wNumButtons>1);
  LoadString(ghInstance,21,s,elemof(s));
  w=GetDlgItem(Wnd,0x53);
  ComboBox_ResetContent(w);
  for (j=0; j<8; j++) {
   if (j<3 && j<=(int)jc.wNumAxes || j>=3 && jc.wCaps&1<<(j-3)) {	// ab JOYCAPS_HASZ
    int idx=ComboBox_AddString(w,p);
    ComboBox_SetItemData(w,idx,j);
    if (j==Config.iJoyButton>>5) ComboBox_SetCurSel(w,idx);
   }
   p+=lstrlen(p)+1;
  }
  EnableWindow(w,jc.wNumAxes);
 }
}

static void FillComboFromStringId(HWND Wnd, UINT id) {
 TCHAR buf[256], *p=buf;
 buf[LoadString(ghInstance,id,buf,elemof(buf)-1)+1]=0;	// doppelnullterminiert
 for(;*p;p+=lstrlen(p)+1) ComboBox_AddString(Wnd,p);
}

static void SetValue3Decimals(HWND Wnd, UINT id, long v) {
 int i,k;
 TCHAR s[16];
 i=wnsprintf(s,elemof(s)-1,T("%04d"),v);
 for (k=i; k>i-3; k--) s[k+1]=s[k]; s[k]=sDecimal[0];	// 3 Nachkommastellen generieren
 SetDlgItemText(Wnd,id,s);
}

// ersetzt HidD_GetInputReport(), mit TimeOut bei FILE_FLAG_OVERLAPPED
static BOOL GetInputReport(HANDLE hDev, void*buf, int len) {
 BOOL ret=FALSE;
 OVERLAPPED o;
 DWORD br;
 __stosd(&o,0,sizeof o/4);
 o.hEvent=CreateEvent(NULL,FALSE,FALSE,NULL);
 if (ReadFile(hDev,buf,len,&br,&o)
 || GetLastError()==ERROR_IO_PENDING
 && !WaitForSingleObject(o.hEvent,100)
 && GetOverlappedResult(hDev,&o,&br,FALSE)
 && br) ret=TRUE;
 CloseHandle(o.hEvent);
 return ret;
}

static HANDLE HidDev;	// zyklisch ben÷tigt

// HID-Feature-Reports abfragen und einsetzen, wird vom Timer und bei Selektion aufgerufen.
// Vom Timer ist hDev=0, sonst das (neue) HidDev.
static void FillHidInfos(HWND Wnd, HANDLE hDev) {
 PHIDP_PREPARSED_DATA pd;
 if (hDev && hDev!=HidDev) {
  if (HidDev) CloseHandle(HidDev);
  HidDev=hDev;
 }
 if (HidD_GetPreparsedData(HidDev,&pd)) {
  HIDP_CAPS hidcaps;
  if (HidP_GetCaps(pd,&hidcaps)) {
   PUCHAR report;
   int maxreport=hidcaps.InputReportByteLength;
// if (maxreport<hidcaps.OutputReportByteLength) maxreport=hidcaps.OutputReportByteLength;
   if (maxreport<hidcaps.FeatureReportByteLength) maxreport=hidcaps.FeatureReportByteLength;
   report=LocalAlloc(LPTR,maxreport);
   if (report) {
    long v;
    TCHAR s[32];
    SYSTEMTIME st;
    HidP_InitializeReportForID(HidP_Input,4,pd,report,hidcaps.InputReportByteLength);
    GetInputReport(HidDev,report,hidcaps.InputReportByteLength);
    HidP_GetScaledUsageValue(HidP_Input,0x84,0,0x30,&v,pd,report,hidcaps.InputReportByteLength);
    SetValue3Decimals(Wnd,0x76,v);
    HidP_GetScaledUsageValue(HidP_Input,0x84,0,0x36,&v,pd,report,hidcaps.InputReportByteLength);
    SetDlgItemInt(Wnd,0x77,v,TRUE);
    HidP_InitializeReportForID(HidP_Feature,2,pd,report,hidcaps.FeatureReportByteLength);
    HidD_GetFeature(HidDev,report,hidcaps.FeatureReportByteLength);	// Uhrzeit
    st.wSecond=report[2]; st.wMinute=report[3]; st.wHour=report[4];
    st.wDay=report[5]; st.wDayOfWeek=report[6]; st.wMonth=report[7]; st.wYear=report[8]+2000;
    SystemTimeToString(&st,DATE_SHORTDATE,0,s,elemof(s));
    SetDlgItemText(Wnd,0x75,s);
    if (hDev) {
     HidP_InitializeReportForID(HidP_Feature,3,pd,report,hidcaps.FeatureReportByteLength);
     HidD_GetFeature(HidDev,report,hidcaps.FeatureReportByteLength);	// Setup-Sachen
     HidP_GetUsageValue(HidP_Feature,0xFF00,0,0x35,&v,pd,report,hidcaps.FeatureReportByteLength);
     SendDlgItemMessage(Wnd,0x72,CB_SETCURSEL,v,0);	// Akkutyp
     HidP_GetScaledUsageValue(HidP_Feature,0xFF00,0,0x36,&v,pd,report,hidcaps.FeatureReportByteLength);
     SetValue3Decimals(Wnd,0x73,v);		// Ladeschluss
     HidP_GetScaledUsageValue(HidP_Feature,0xFF00,0,0x37,&v,pd,report,hidcaps.FeatureReportByteLength);
     SetValue3Decimals(Wnd,0x74,v);		// Entladeschluss
    }
    LocalFree(report);
   }
  }
  HidD_FreePreparsedData(pd);
 }
}

// Hilfsfunktion fⁿr die Eingabefehlerprⁿfung
static int cbGetCurSel(HWND Wnd, UINT id, HWND *w) {
 return ComboBox_GetCurSel(*w=GetDlgItem(Wnd,id));
}
// Hilfsfunktion, bei Selektionswechsel
static INT_PTR cbGetCurItemData(HWND cb) {
 return ComboBox_GetItemData(cb,ComboBox_GetCurSel(cb));
}

// Dialogfensterprozedur fⁿr Eigenschaftsseite
INT_PTR CALLBACK HardwareDlgProc(HWND Wnd,UINT Msg,WPARAM wParam,LPARAM lParam) {
 DefHelpProc(Wnd,Msg,lParam,101);
 switch (Msg) {
  case WM_INITDIALOG: {
// Eingabeleitungen in der Bit-Reihenfolge von 3F6h, Pin-Nummern: 9pol. SubD
   static const char SerialInLines[]=
    "CTS(8)\0DSR(6)\0RI(9)\0DCD(1)\0RxD(2)\0";
// Ausgabeleitungen in der Bit-Reihenfolge von 3F4h
   static const char SerialOutLines[]=
    "DTR(4)\0RTS(7)\0TxD(3)\0";
   CheckDlgButton(Wnd,0x10+Config.Where,TRUE);
   AttachUpDown(Wnd,0x43,0x44,10,Config.iSampleRate*500,FiltFreqHz(NULL));
   KillTimer(Wnd,0x43);
   ShowWhere(Wnd);
   SendMessage(Wnd,WM_DEVICECHANGE,0,0);
   FillCombo(GetDlgItem(Wnd,0x22),SerialInLines,Config.SerialLineIn);
   FillCombo(GetDlgItem(Wnd,0x23),SerialOutLines,Config.SerialLineOut);
   SendDlgItemMessage(Wnd,0x24,WM_SETFONT,(WPARAM)GdiObj.fnKursiv,FALSE);
   FillComboAddrs(GetDlgItem(Wnd,0x31));
   FillComboBits(GetDlgItem(Wnd,0x32),Config.ParallelLineIn);
   FillComboBits(GetDlgItem(Wnd,0x33),Config.ParallelLineOut);
   SendDlgItemMessage(Wnd,0x34,WM_SETFONT,(WPARAM)GdiObj.fnKursiv,FALSE);
   PrepareRedString(GetDlgItem(Wnd,0x35));
   SendDlgItemMessage(Wnd,0x45,WM_SETFONT,(WPARAM)GdiObj.fnKursiv,FALSE);
   FillComboBits(GetDlgItem(Wnd,0x62),(BYTE)(Config.iUsbInput|0x80));
   FillComboFromStringId(GetDlgItem(Wnd,0x72),22);	// Akkutyp
  }return TRUE;

  case WM_DEVICECHANGE: {
   HWND hCombo;
   bool one;
   UINT i,k;
   HDEVINFO devs;
   DEV_BROADCAST_DEVICEINTERFACE *bc=(void*)lParam;
   DbgPrintf(("WM_DEVICECHANGE(wParam=%d,devicetype=%d)\n",wParam,bc?bc->dbcc_devicetype:0));
// serielle Schnittstellen listen (bei jedem WM_DEVICECHANGE bspw. fⁿr USB)
// Die SetupDi-Methode ist viel schneller als alle (256?) COM-Ports auszuprobieren,
// geht aber erst ab Win98 und Win2k. Win95 und NT4 bleiben au▀en vor.
// Es gibt GUID_DEVCLASS_PORTS -> listet serielle und parallele Schnittstellen, OHNE DIGCF_DEVICEINTERFACE
// und GUID_CLASS_COMPORT == GUID_DEVINTERFACE_COMPORT, nur serielle, MIT DIGCF_DEVICEINTERFACE
// ▄berraschung: Letzteres funktioniert nicht unter Win98SE! Was fⁿr ein heilloses Chaos.
// CM_Open_DevNode_Key() ist ersetzt durch SetupDiOpenDevRegKey().

// if (!bc || bc->dbcc_devicetype==DBT_DEVTYP_DEVICEINTERFACE && !CompareGuid(&bc->dbcc_classguid,&GUID_DEVINTERFACE_COMPORT)
   {
    hCombo=GetDlgItem(Wnd,0x21);
    ComboBox_ResetContent(hCombo);
    one=false;
    devs=SetupDiGetClassDevs(&GUID_DEVCLASS_PORTS,NULL,0,DIGCF_PRESENT);
    if (devs!=INVALID_HANDLE_VALUE) {
     SP_DEVINFO_DATA devInfo;
     devInfo.cbSize=sizeof devInfo;
     for (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') {	// FehlschlΣge und LPTx ausfiltern
       int idx=ComboBox_AddString(hCombo,s);
       int num=StrToInt(s+3)-1;	// nullbasiert
       ComboBox_SetItemData(hCombo,idx,num);
       if (num==Config.SerialNo) ComboBox_SetCurSel(hCombo,idx);
       one=true;
      }
     }
     SetupDiDestroyDeviceInfoList(devs);
    }
    EnableDlgItem(Wnd,0x10,one);
   }
// Soundkarten (nur bei ─nderung der Anzahl auffrischen)
   hCombo=GetDlgItem(Wnd,0x41);
   k=waveInGetNumDevs();
   if (ComboBox_GetCount(hCombo)!=k) {
    ComboBox_ResetContent(hCombo);
    one=false;
    for (i=WAVE_MAPPER; (int)i<(int)k; i++) {
     WAVEINCAPS wc;
     if (!waveInGetDevCaps(i,&wc,sizeof wc)) {
      int idx=ComboBox_AddString(hCombo,wc.szPname);
      ComboBox_SetItemData(hCombo,idx,i);
      one=true;
      if ((int)i==Config.iSoundCard) {
       ComboBox_SetCurSel(hCombo,idx);
       FillSamplerates(Wnd);		// Sampleraten auffⁿllen lassen
      }
     }
    }
    EnableDlgItem(Wnd,0x12,one);
   }
// Joysticks (nur bei ─nderung der Anzahl auffrischen)
   hCombo=GetDlgItem(Wnd,0x51);
   k=joyGetNumDevs();
   if (ComboBox_GetCount(hCombo)!=k) {
    ComboBox_ResetContent(hCombo);
    one=false;
    for (i=0; i<k; i++) {
     JOYCAPS jc;
     if (!joyGetDevCaps(i,&jc,sizeof jc)) {
      int idx;
      TCHAR s[40];
      wnsprintf(s,elemof(s),T("%d: %s"),i,jc.szPname);
      idx=ComboBox_AddString(hCombo,s);
      ComboBox_SetItemData(hCombo,idx,i);
      one=true;
      if (i==Config.iJoystick) {
       ComboBox_SetCurSel(hCombo,idx);
       FillButtons(Wnd);
      }
     }
    }
    EnableDlgItem(Wnd,0x13,one);
   }
// UsbPrn
   {
    hCombo=GetDlgItem(Wnd,0x61);
    ComboBox_ResetContent(hCombo);
    one=false;
    devs=SetupDiGetClassDevs(&GUID_DEVINTERFACE_USBPRINT,0,0,DIGCF_PRESENT|DIGCF_DEVICEINTERFACE);
    if (devs!=INVALID_HANDLE_VALUE) {
     SP_DEVICE_INTERFACE_DATA devinterface;
     devinterface.cbSize=sizeof devinterface;
     for (i=0; SetupDiEnumDeviceInterfaces(devs,NULL,&GUID_DEVINTERFACE_USBPRINT,i,&devinterface); i++) {
      TCHAR s[16];
      wnsprintf(s,elemof(s),T("%d"),i);
      ComboBox_AddString(hCombo,s);
      one=true;
      if (i==Config.iUsbPrn) ComboBox_SetCurSel(hCombo,i);
     }
     SetupDiDestroyDeviceInfoList(devs);
    }
    EnableDlgItem(Wnd,0x14,one);
   }
// VorlaufempfΣnger
   {GUID hidGuid;
    hCombo=GetDlgItem(Wnd,0x71);
    ComboBox_ResetContent(hCombo);
    one=false;
    HidD_GetHidGuid(&hidGuid);
    devs=SetupDiGetClassDevs(&hidGuid,0,0,DIGCF_PRESENT|DIGCF_DEVICEINTERFACE);
    if (devs!=INVALID_HANDLE_VALUE) {
     SP_DEVICE_INTERFACE_DATA devinterface;
     devinterface.cbSize=sizeof devinterface;
     for (i=0; SetupDiEnumDeviceInterfaces(devs,NULL,&hidGuid,i,&devinterface); i++) {
      HANDLE hDev;
      union{
       SP_DEVICE_INTERFACE_DETAIL_DATA detail;
       TCHAR space[MAX_PATH+4];
       WCHAR pid[128];
       HIDD_ATTRIBUTES a;
      }u;
      u.detail.cbSize=sizeof u.detail;
      if (!SetupDiGetDeviceInterfaceDetail(devs,&devinterface,&u.detail,sizeof u,NULL,NULL)) continue;
      hDev=CreateFile(u.detail.DevicePath,GENERIC_READ|GENERIC_WRITE,
        FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,OPEN_EXISTING,FILE_FLAG_OVERLAPPED,NULL);
      if (hDev!=INVALID_HANDLE_VALUE) {
       HidD_GetAttributes(hDev,&u.a);
       if (*(DWORD*)&u.a.VendorID==0x27D916C0		// VOTI->V-USB->HID mit Seriennummer muss es sein
       && HidD_GetProductString(hDev,u.pid,elemof(u.pid))
       && StrStrW(u.pid,L"FunkUsb")) {			// Der Produktname muss "FunkUsb" enthalten
        wnsprintf(u.space,elemof(u.space),T("%d"),i);
        ComboBox_AddString(hCombo,u.space);
        one=true;
        if (i==Config.iUsbHid) {
         ComboBox_SetCurSel(hCombo,i);
	 FillHidInfos(Wnd,hDev);
	}
       }
       CloseHandle(hDev);
      }
     }
     SetupDiDestroyDeviceInfoList(devs);
    }
    EnableDlgItem(Wnd,0x15,one);
   }
  }break;

  case WM_COMMAND: switch ((BYTE)wParam) {
   case 0x10:
   case 0x11:
   case 0x12:
   case 0x13:
   case 0x14:
   case 0x15: {
    BYTE o=Config.Where;
    bool scc,piep;
    Config.Where=(BYTE)wParam-0x10;
    scc=(o==2)!=(Config.Where==2);	// Soundkarten-Wechsel?
    piep=scc && Config.Piep && (Empfang.Ein==3 || Empfang.DauerPiep);	// Piep-Wechsel?
    ShowWhere(Wnd);
// Der Piep kann (auf manchen Soundkarten?) nicht gleichzeitg mit dem Empfang
// via Soundkarte laufen. Daher muss dieser entsprechend aktiviert/deaktiviert werden.
    if (Config.Where==2 && piep) DoneBeep();
// Ggf. Demodulator-Eigenschaftsseite hinzufⁿgen oder entfernen.
    if (scc && Config.Where==2) PropInsDelSheet(8,8);
    RestartEmpfang();
    if (scc && Config.Where!=2) PropInsDelSheet(-1,Decrypt?8:7);
    if (o==2 && piep) {
     InitBeep((BYTE)(10-Config.Piep));
     if (Empfang.Signal || Empfang.DauerPiep) StartBeep();
    }
   }break;

   case 0x21: if (LOBYTE(HIWORD(wParam))==CBN_SELCHANGE) {
    BYTE b=(BYTE)cbGetCurItemData((HWND)lParam);
    if (Config.SerialNo!=b) {
     Config.SerialNo=b;
     RestartEmpfang();
    }
   }break;
   case 0x22: if (LOBYTE(HIWORD(wParam))==CBN_SELCHANGE) {
    BYTE b=(BYTE)ComboBox_GetCurSel((HWND)lParam);
    if (Config.SerialLineIn!=b) {
     Config.SerialLineIn=b;
     RestartEmpfang();	// wirklich n÷tig?
    }
   }break;
   case 0x23: if (LOBYTE(HIWORD(wParam))==CBN_SELCHANGE) {
    BYTE b=(BYTE)ComboBox_GetCurSel((HWND)lParam);
    if (Config.SerialLineOut!=b) {
     Config.SerialLineOut=b;
     RestartEmpfang();	// wirklich n÷tig?
    }
   }break;

   case 0x31: switch (LOBYTE(HIWORD(wParam))) {
    case CBN_SELCHANGE:// OnParallelAddrChange(Wnd); break;	// sofort
    case CBN_EDITCHANGE: {	// verz÷gert
     if (!SetTimer(Wnd,31,200,NULL)) PostMessage(Wnd,WM_TIMER,31,0);
    }break;
   }break;
   case 0x32: if (LOBYTE(HIWORD(wParam))==CBN_SELCHANGE) {
    BYTE b=(BYTE)cbGetCurItemData((HWND)lParam);
    if (Config.ParallelLineIn!=b) {
     Config.ParallelLineIn=b;
     RestartEmpfang();
    }
   }break; 
   case 0x33: if (LOBYTE(HIWORD(wParam))==CBN_SELCHANGE) {
    BYTE b=(BYTE)cbGetCurItemData((HWND)lParam);
    if (Config.ParallelLineOut!=b) {
     Config.ParallelLineOut=b;
     RestartEmpfang();
    }
   }break;

   case 0x41: if (LOBYTE(HIWORD(wParam))==CBN_SELCHANGE) {
    int b=(int)cbGetCurItemData((HWND)lParam);
    if (Config.iSoundCard!=(char)b) {
     Config.iSoundCard=(char)b;
     FillSamplerates(Wnd);
     RestartEmpfang();
    }
   }break;
   case 0x42: switch (LOBYTE(HIWORD(wParam))) {
    case CBN_SELCHANGE:
    case CBN_EDITCHANGE: {
     if (!SetTimer(Wnd,0x42,200,NULL)) PostMessage(Wnd,WM_TIMER,0x42,0);
    }break;
   }break;
   case 0x43: if (HIWORD(wParam)==EN_CHANGE) {
    if (!SetTimer(Wnd,0x43,200,NULL)) PostMessage(Wnd,WM_TIMER,0x43,0);
   }break;

   case 0x51: if (LOBYTE(HIWORD(wParam))==CBN_SELCHANGE) {
    int b=(int)cbGetCurItemData((HWND)lParam);
    if (Config.iJoystick!=(BYTE)b) {
     Config.iJoystick=(BYTE)b;
     FillButtons(Wnd);
     RestartEmpfang();
    }
   }break;
   case 0x52: if (LOBYTE(HIWORD(wParam))==CBN_SELCHANGE) {
    Config.iJoyButton=(BYTE)(Config.iJoyButton&0xE0|ComboBox_GetCurSel((HWND)lParam));	// wirkt sofort
   }break;
   case 0x53: if (LOBYTE(HIWORD(wParam))==CBN_SELCHANGE) {
    Config.iJoyButton=(BYTE)(Config.iJoyButton&0x1F|ComboBox_GetCurSel((HWND)lParam)<<5);
   }break;

   case 0x61: if (LOBYTE(HIWORD(wParam))==CBN_SELCHANGE) {
    BYTE b=(BYTE)ComboBox_GetCurSel((HWND)lParam);
    if (Config.iUsbPrn!=b) {
     Config.iUsbPrn=b;
     RestartEmpfang();
    }
   }break;
   case 0x62: if (LOBYTE(HIWORD(wParam))==CBN_SELCHANGE) {
    Config.iUsbInput=(BYTE)(ComboBox_GetCurSel((HWND)lParam)+013);	// oktal; wirkt sofort
   }break;

   case 0x71: if (LOBYTE(HIWORD(wParam))==CBN_SELCHANGE) {
    BYTE b=(BYTE)ComboBox_GetCurSel((HWND)lParam);
    if (Config.iUsbHid!=b) {
     Config.iUsbHid=b;
     RestartEmpfang();
    }
   }break;

  }break;

  case WM_TIMER: if (wParam!=0x71) KillTimer(Wnd,wParam); switch (wParam) {
   case 0x31: OnParallelAddrChange(Wnd); break;
   case 0x42: {	// Abtastrate in Sa/s
    int i=GetDlgItemInt(Wnd,0x42,NULL,FALSE)/1000;
    if (i>=8 && i<256) {
     Config.iSampleRate=(BYTE)i;	// abspeichern in kSa/s
     SendDlgItemMessage(Wnd,0x44,UDM_SETRANGE32,10,i*500);
     RestartEmpfang();
    }
   }break;
   case 0x43: {
    BOOL err;
    int f=(int)SendDlgItemMessage(Wnd,0x44,UDM_GETPOS32,0,(LPARAM)&err);
    if (!err) SetFiltFreq(f*100);		// Demodulatoroszillator äziehenô, AFC-Wert l÷schen
   }break;
   case 0x71: FillHidInfos(Wnd,0); break;
  }break;

  case WM_CTLCOLORSTATIC: if (GetDlgCtrlID((HWND)lParam)==0x35) {
   LRESULT br=DefWindowProc(Wnd,Msg,wParam,lParam);
   SetTextColor((HDC)wParam,RGB(192,0,0));		// dunkelrot
   SetBkMode((HDC)wParam,TRANSPARENT);
   return (BOOL)br;	// nicht "return (BOOL)GetSysColorBrush(COLOR_3DFACE);"	// Unter Win7 falsche Hintergrundfarbe
  }break;

  case WM_NOTIFY: {
   LPPSHNOTIFY psn=(LPPSHNOTIFY)lParam;
   UINT i,Problem=0;	// Problem = String-ID, die bei festgestelltem Problem angezeigt wird
   HWND w;		// Fehler-Dialogelement, wird anschlie▀end fokussiert und ggf. Text markiert
   switch (psn->hdr.code) {
    case PSN_SETACTIVE: {
     SendDlgItemMessage(Wnd,0x44,UDM_SETPOS32,0,Config.iFiltFreq<<1);
    }break;
    case PSN_KILLACTIVE: {
     switch (Config.Where) {
      case 0: {	// seriell
       if (cbGetCurSel(Wnd,0x21,&w)<0) {Problem=17; break;}
       if (cbGetCurSel(Wnd,0x22,&w)<0) {Problem=17; break;}
       if (cbGetCurSel(Wnd,0x23,&w)<0) {Problem=17; break;}
      }break;
      case 1: {	// parallel
       if (!OnParallelAddrChange(Wnd)) {
        Problem=18;
	w=GetDlgItem(Wnd,0x31);
	break;
       }
       if (cbGetCurSel(Wnd,0x32,&w)<0) {Problem=17; break;}
       if (cbGetCurSel(Wnd,0x33,&w)<0) {Problem=17; break;}
      }break;
      case 2: { // Soundkarte
       BOOL err;
       if (cbGetCurSel(Wnd,0x41,&w)<0) {Problem=17; break;}
       i=GetDlgItemInt(Wnd,0x42,NULL,FALSE)/1000u;	// Abtastrate
       if (i<8 || i>255) {w=GetDlgItem(Wnd,0x42); Problem=46; break;}
       SendDlgItemMessage(Wnd,0x44,UDM_GETPOS32,0,(LPARAM)&err);	// Filterfrequenz
       if (err) {
        Edit_SetSel(w=GetDlgItem(Wnd,0x43),0,-1);
        Problem=46;
        break;
       }
      }break;
      case 3: { // Joystick
       if (cbGetCurSel(Wnd,0x51,&w)<0) {Problem=17; break;}
       if (cbGetCurSel(Wnd,0x52,&w)<0) {Problem=17; break;}
      }break;
      case 4: { // UsbPrn
       if (cbGetCurSel(Wnd,0x61,&w)<0) {Problem=17; break;}
       if (cbGetCurSel(Wnd,0x62,&w)<0) {Problem=17; break;}
      }break;
      case 5: { // VorlaufempfΣnger
      }break;
      default: Problem=16; w=GetDlgItem(Wnd,0x10);
     }
    }break;
   }
   if (Problem) {
    SetFocus(w);
    MBox(Wnd,Problem,MB_OK);
    return SetDlgMsgResult(Wnd,WM_NOTIFY,TRUE);
   }
  }break;

 }
 return FALSE;
}
Vorgefundene Kodierung: OEM (CP437)1
Umlaute falsch? - Datei sei ANSI-kodiert (CP1252)
Datei sei OEM-kodiert (CP437)