/********************************
* 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 |