Source file: /~heha/messtech/sensokom.zip/source/DIALOG.C

// Verschiedene kleine Dialoge:
// nichtmodal: Display - Tabelle - Schaltplan
// modal: Schnittstelle - Search - Transmitter - Intervall - Über
#include <windows.h>
#include <windowsx.h>	//message crackers
#ifndef GET_WM_COMMAND_CMD
# define GET_WM_COMMAND_CMD(wp,lp) HIWORD(lp)	//fehlt bei BC31 windowsx.h
#endif
#include <stdlib.h>	//atoi
#include <stdarg.h>	//va_list
#include <stdio.h>	//sprintf, sscanf
#include <string.h>	//memset
#include <math.h>	//floor
#include "driver.h"
#include "dialog.h"
#include "toolstat.h"	//HelpFileName
#include "sensokom.rh"	//Dialog-IDs für Hilfe

/*=========== Hilfsprogramme WUTILS ===================*/
#define nobreak

int Limit(int x, int u, int o) {
 return x<u?u:x>o?o:x;
}

UINT InitStruct(void*str,UINT len) {
 memset(str,0,len);
 *(UINT*)str=len;
 return 0;
}

int pascal vMBox(HWND Wnd, UINT id, UINT style, const void far*arglist) {
 char buf1[256],buf2[256];
 LoadString(hInstance,id,buf1,sizeof(buf1));
 wvsprintf(buf2,buf1,/*WIN32:(va_list)*/arglist);
 return MessageBox(Wnd,buf2,"Sensokom",style);
}

int cdecl MBox(HWND Wnd, UINT id, UINT style,...) {
 return vMBox(Wnd,id,style,&style+1);
}

void pascal SetEditFocus(HWND Wnd, UINT id) {
 Wnd=GetDlgItem(Wnd,id);
 Edit_SetSel(Wnd,0,(UINT)-1);
}

int pascal GetRadioCheck(HWND Wnd, UINT idStart,UINT idEnd) {
 int result=0;
 for (; idStart<=idEnd; idStart++,result++) {
  if (IsDlgButtonChecked(Wnd,idStart)==1) return result;
 }
 return -1;
}

void EnableDlgItem(HWND Wnd, UINT id, BOOL state) {
 Wnd=GetDlgItem(Wnd,id);
 if (Wnd) EnableWindow(Wnd,state);
}

static BOOL ShiftRect(LPINT r, const LPINT r2) {
// Hilfsfunktion, schiebt horizontal bzw. vertikal
 int ax,dx;		// jaja, Assembler
 ax=r2[0]-r[0];		// Differenz links bzw. oben
 if (!ax) return FALSE;
 if (ax<0) {
  dx=r2[2]-r[2];	// Differenz rechts bzw. unten
  if (dx>=0) return FALSE;
  if (ax<dx) ax=dx;	// die kleinere Zahl
 }
 r[0]+=ax;
 r[2]+=ax;
 return TRUE;
}

BOOL MoveRectIntoRect(LPRECT R, const LPRECT R2) {
// Falls R in R2 teilweise oder vollständig außerhalb liegt,
// wird R verschoben und TRUE zurückgeliefert, um maximale Sichtbarkeit
// zu realisieren.
// Dient zum Hineinholen von außerhalb liegenden Fenstern in den Desktop.
 return ShiftRect((LPINT)&R->left,(LPINT)&R2->left)
       +ShiftRect((LPINT)&R->top, (LPINT)&R2->top);
}

void GetFullScreenRect(LPRECT R) {
// Ermittelt das Rechteck für maximierte Fenster, d.h. die Startleiste
// von Win9x bereits abgezogen, ideal für R2 in MoveRectIntoRect
 R->left=R->top=0;
 R->right=GetSystemMetrics(SM_CXFULLSCREEN);
 R->bottom=GetSystemMetrics(SM_CYFULLSCREEN)+GetSystemMetrics(SM_CYCAPTION);
}

BOOL MoveRectIntoFullScreen(LPRECT R) {
// die logische Kombination beider o.g. Routinen
 RECT R2;
 GetFullScreenRect(&R2);
 return MoveRectIntoRect(R,&R2);
}

#ifdef __BORLANDC__
# pragma argsused
#endif
BOOL _stdcall Line(HDC dc, int x1, int y1, int x2, int y2) {
 return Polyline(dc, (LPPOINT)&x1,2);
}

//Das, was Set{Window|Viewport}{Org|Ext} letztlich bewirkt:
int fitrafo(float x, float a, float e, int A, int E) {
//Transformation von FLOAT zu INT, kein Problem bei a=e
 e-=a;
 if (!e) return 0;
 return (int)floor(((x-a)*(E-A)/e)+A+0.5);
}

BOOL GetDlgItemFloat(HWND Wnd, UINT id, float*z) {
// Gleitkommazahl (auch mit Komma statt Punkt) vom Dialogelement holen
 char s[32],*sp;
 Wnd=GetDlgItem(Wnd,id);
 GetWindowText(Wnd,s,sizeof(s));
 sp=(char*)lstrchr(s,',');	// Ein Komma durch Punkt ersetzen
 if (sp) *sp='.';
 if (sscanf(s,"%f",z)==1) return TRUE;
 SetFocus(Wnd);
 Edit_SetSel(Wnd,0,(UINT)-1);	// Message Cracker macht den Rest
 return FALSE;
}

void SetDlgItemFloat(HWND Wnd, UINT id, int komma, float z) {
// Gleitkommazahl in Dialogelement setzen
 char buf[32];
 sprintf(buf,"%.*f",komma,z); SetDlgItemText(Wnd,id,buf);
}

HHOOK CallWndHook;

LRESULT CALLBACK CallWndProc(int code, WPARAM wParam, LPARAM lParam) {
#ifndef _WIN32
typedef struct{
 LPARAM lParam;
 WPARAM wParam;
 UINT message;
 HWND hwnd;
}CWPSTRUCT,*PCWPSTRUCT,near*NPCWPSTRUCT,far*LPCWPSTRUCT;
#endif
 switch (((LPCWPSTRUCT)lParam)->message) {
  case WM_SETCURSOR: {
//  case WM_NCMOUSEMOVE: {
//  MessageBeep((UINT)-1);
   SetCursor(LoadCursor(0,IDC_WAIT));
   ((LPCWPSTRUCT)lParam)->message=WM_NULL;	// verschlucken
  }
 }
 return CallNextHookEx(CallWndHook,code,wParam,lParam);
}

void SetWaitCursor(HWND Wnd, BOOL ShowWait) {
// Sanduhr ein/ausschalten, unbedingt paarweise rufen!
// Die Schwierigkeit des Anzeigens der Sanduhr besteht hier darin,
// dass die langwierigen DDE-Transfers auch per PeekMessage()
// Rechenzeit freigeben. So bekommt das Dialogfenster auch zwischendurch
// WM_MOUSEMOVE-Nachrichten, was die Sanduhr zu kurzlebig machen würde.
// Und dummerweise ist der Mauspfeil eine Klassen- und keine Fenster-
// Eigenschaft - wahrlich ein Konstruktionsfehler von Windows.
 EnableWindow(Wnd,!ShowWait);
 if (ShowWait) {
  CallWndHook=SetWindowsHookEx(WH_CALLWNDPROC,CallWndProc,hInstance,
#ifdef _WIN32
    GetCurrentThreadId());
#else
    GetCurrentTask());
#endif
 }else{
  UnhookWindowsHookEx(CallWndHook);
 }
 ShowCursor(ShowWait);
 SendMessage(Wnd,WM_SETCURSOR,(WPARAM)Wnd,HTCLIENT);
}

int iitrafo(int x, int a, int e, int A, int E) {
//Transformation von INT zu INT (mit Rundung), kein Problem bei a=e
 e-=a;
 if (!e) return 0;
 return MulDiv(x-a,E-A,e)+A;
}

long exp10(int e) {
 long ret=1;
 while (e--) ret*=10;
 return ret;
}

extern HWND MainWnd;	// eigentlich: toolstat.h

void PlaceDialog(HWND Wnd, PPOINT pt) {
 RECT r;
 GetWindowRect(Wnd,&r);
 r.right-=r.left; r.bottom-=r.top;	// Distanzen
 *(PPOINT)&r=*pt;			// links oben
 MapWindowPoints(MainWnd,0,(PPOINT)&r,1);	// umsetzen
 r.right+=r.left; r.bottom+=r.top;	// rechte Kanten
 MoveRectIntoFullScreen(&r);		// deshalb!
 SetWindowPos(Wnd,0,r.left,r.top,0,0,SWP_NOSIZE|SWP_NOZORDER);
}

void OnMoveDialog(HWND Wnd, PPOINT pt) {
 RECT r;
 GetWindowRect(Wnd,&r);
 MapWindowPoints(0,MainWnd,(PPOINT)&r,1);	// nur links oben interessant
 *pt=*(PPOINT)&r;
}

/*=====================================================*/
HWND DisplayDlg;
POINT DisplayDlgPos;	// letzte Platzierung relativ zum Hauptfenster

BOOL CALLBACK DisplayDlgProc(HWND Wnd, UINT Msg, WPARAM wParam, LPARAM lParam){
 switch (Msg) {
  case WM_INITDIALOG: {
   PlaceDialog(Wnd,&DisplayDlgPos);
  }return TRUE;
  case WM_USER: {
   if (lParam) SetDlgItemText(Wnd,2001,Get_Messwert((LPSTR)lParam));
  }break;
  case WM_MOVE: {
   OnMoveDialog(Wnd,&DisplayDlgPos);
  }break;
  case WM_COMMAND: if (LOWORD(wParam)==2) DestroyWindow(Wnd);
  case WM_DESTROY: DisplayDlg=0; break;
 }/*switch*/
 return FALSE;
}
/*=====================================================*/
HWND TabelleDlg;
POINT TabelleDlgPos;

BOOL CALLBACK TabelleDlgProc(HWND Wnd, UINT Msg, WPARAM wParam, LPARAM lParam){
 switch (Msg) {
  case WM_INITDIALOG: {
   int i;
   char AntwortString[32];
   SetDlgItemInt(Wnd,3001,(UINT)lParam,FALSE);	// Adresse setzen
   PlaceDialog(Wnd,&TabelleDlgPos);
   i=3; do{		// 3 Versuche
    if (ISM_Info((BYTE)lParam,AntwortString,sizeof(AntwortString))) break;
   }while (--i);
   SetDlgItemText(Wnd,3002,Get_Number(AntwortString));
   SetDlgItemText(Wnd,3003,Get_File(AntwortString));
  }return TRUE;
  case WM_MOVE: {
   OnMoveDialog(Wnd,&TabelleDlgPos);
  }break;
  case WM_USER: if (lParam) {
   SetDlgItemText(Wnd,3004,Get_Messwert((LPSTR)lParam));
   SetDlgItemInt(Wnd,3005,GetInp((LPSTR)lParam),FALSE);
   SetDlgItemInt(Wnd,3006,Get_IO((LPSTR)lParam),FALSE);
   SetDlgItemInt(Wnd,3007,GetOut((LPSTR)lParam),FALSE);
  }break;
  case WM_COMMAND: if (LOWORD(wParam)==2) DestroyWindow(Wnd);
  case WM_DESTROY: TabelleDlg=0; break;
 }/*switch*/
 return FALSE;
}
/*=====================================================*/
HWND SchaltplanDlg;
POINT SchaltplanDlgPos;

BOOL CALLBACK SchaltplanDlgProc(HWND Wnd, UINT Msg, WPARAM wParam, LPARAM lParam){
 switch (Msg) {
  case WM_INITDIALOG: {		//lParam=Messart
   PlaceDialog(Wnd,&SchaltplanDlgPos);
   SetWindowLong(Wnd,DWL_USER,
     (LONG)LoadBitmap(hInstance,MAKEINTRESOURCE(lParam+10)));
  }return TRUE;
  case WM_MOVE: {
   OnMoveDialog(Wnd,&SchaltplanDlgPos);
  }break;
  case WM_SET_MESSART: {		//lParam=neue Messart
   DeleteObject((HBITMAP)SetWindowLong(Wnd,DWL_USER,
     (LONG)LoadBitmap(hInstance,MAKEINTRESOURCE(lParam+10))));
   InvalidateRect(GetDlgItem(Wnd,101),NULL,TRUE);
  }break;
  case WM_DRAWITEM: {
#define DIS ((LPDRAWITEMSTRUCT)lParam)
   BITMAP bm;
   HDC MemDC=CreateCompatibleDC(DIS->hDC);
   HBITMAP hbm=(HBITMAP)GetWindowLong(Wnd,DWL_USER);
   HBITMAP obm=(HBITMAP)SelectObject(MemDC,hbm);
   GetObject(hbm,sizeof(bm),&bm);	// Größe zum Zentrieren ermitteln
   BitBlt(DIS->hDC,
     (DIS->rcItem.left+DIS->rcItem.right-bm.bmWidth)/2,
     (DIS->rcItem.top+DIS->rcItem.bottom-bm.bmHeight)/2,
     bm.bmWidth,bm.bmHeight,MemDC,0,0,SRCCOPY);
   SelectObject(MemDC,obm);
   DeleteDC(MemDC);
#undef DIS
  }break;
  case WM_COMMAND: if (LOWORD(wParam)==2) DestroyWindow(Wnd); break;
  case WM_DESTROY: {
   DeleteObject((HBITMAP)GetWindowLong(Wnd,DWL_USER));
   SchaltplanDlg=0;
  }break;
 }/*switch*/
 return FALSE;
}
/*=====================================================*/
BOOL CALLBACK SchnittstelleDlgProc(HWND Wnd, UINT Msg, WPARAM wParam, LPARAM lParam) {
 switch (Msg) {
  case WM_INITDIALOG: {
   SetWindowLong(Wnd,DWL_USER,lParam);
   CheckDlgButton(Wnd,102,TRUE);
   CheckDlgButton(Wnd,1010,TRUE);
   if (*(LPSTR)lParam) {
    CheckDlgButton(Wnd,105,TRUE);
    SetDlgItemText(Wnd,104,(LPSTR)lParam);
    SendMessage(Wnd,WM_COMMAND,105,0);
   }				// sonst "Amarillo" stehen lassen
  }return TRUE;
  case WM_COMMAND: {
   switch (LOWORD(wParam)) {
    case 105: {
     int i;
     BOOL Enab=IsDlgButtonChecked(Wnd,105);
     EnableDlgItem(Wnd,104,Enab);
     Enab=!Enab;
     for (i=1005; i<=1012; i++) EnableDlgItem(Wnd,i,Enab);
    }break;
    case 9: {
     WinHelp(Wnd,HelpFileName,HELP_CONTEXT,CM_KONFIGURATION_SCHNITTSTELLE);
    }break;
    case 1: {
     lParam=GetWindowLong(Wnd,DWL_USER);
     SetWaitCursor(Wnd,TRUE);
#define DdeServer ((LPSTR)lParam)
     if (IsDlgButtonChecked(Wnd,105)) GetDlgItemText(Wnd,104,DdeServer,32);
     else *DdeServer='\0';	// rückschreiben
     Com_Init(*DdeServer?DdeServer:NULL,
       (WORD)(GetRadioCheck(Wnd,101,103)+1),
       (WORD)GetDlgItemInt(Wnd,1005+GetRadioCheck(Wnd,1005,1012),NULL,FALSE));
#undef DdeServer
     SetWaitCursor(Wnd,FALSE);
    }nobreak;
    case 2: EndDialog(Wnd,wParam);
   }/*switch*/
  }return FALSE;
 }/*switch*/
 return FALSE;
}
/*=====================================================*/
BOOL CALLBACK SearchDlgProc(HWND Wnd, UINT Msg, WPARAM wParam, LPARAM lParam) {
 static BYTE SuchAdr;
 switch (Msg) {
  case WM_INITDIALOG: {
   SuchAdr=0;
  }return TRUE;
  case WM_COMMAND: {
#define wNotifyCode GET_WM_COMMAND_CMD(wParam,lParam)
   switch (LOWORD(wParam)) {
    case 102: {		//Listbox
     if (wNotifyCode==LBN_SELCHANGE) EnableDlgItem(Wnd,1,TRUE);
    }break;
    case 103: {		//Knopf "Suchen"
     if (SuchAdr) {	// Sucht noch?
      KillTimer(Wnd,1);
      SuchAdr=0;
     }else{
      SendDlgItemMessage(Wnd,102,LB_RESETCONTENT,0,0);
      SuchAdr++;
      SetTimer(Wnd,1,0,NULL);
     }
     InvalidateRect(GetDlgItem(Wnd,101),NULL,TRUE);
    }break;
    case 9: {
     WinHelp(Wnd,HelpFileName,HELP_CONTEXT,CM_KONFIGURATION_ADRESSENSELEKTION);
    }break;
    case 1: {		// OK-Knopf
     char buf[4];
     HWND w=GetDlgItem(Wnd,102);	//Listbox
     SendMessage(w,LB_GETTEXT,(WPARAM)SendMessage(w,LB_GETCURSEL,0,0),
       (LPARAM)(LPSTR)buf);
     EndDialog(Wnd,atoi(buf));
    }break;
    case 2: {
     EndDialog(Wnd,0);
    }break;
   }/*switch*/
#undef wNotifyCode
  }break;
  case WM_TIMER: {
   char buf[4];
   KillTimer(Wnd,1);	// Nicht verschachteln lassen
   if (ISM_Abfrage(SuchAdr,NULL,0)) {
    wsprintf(buf,"%u",SuchAdr);
    SendDlgItemMessage(Wnd,102,LB_ADDSTRING,0,(LPARAM)(LPSTR)buf);
   }
   if (SuchAdr) {	// wurde nicht zwischendurch gestoppt?
    SuchAdr++;
    InvalidateRect(GetDlgItem(Wnd,101),NULL,!SuchAdr);
    if (SuchAdr) SetTimer(Wnd,1,0,NULL);
   }
  }break;
  case WM_DRAWITEM: {
#define DIS ((LPDRAWITEMSTRUCT)lParam)
   char buf[4];
   HBRUSH br;
   int r=DIS->rcItem.right;
   DIS->rcItem.right=MulDiv(DIS->rcItem.right-DIS->rcItem.left,SuchAdr,255);
   br=CreateSolidBrush(0xFF0000L);
   FillRect(DIS->hDC,&DIS->rcItem,br);
   DeleteObject(br);
   DIS->rcItem.right=r;
   if (SuchAdr) {
    wsprintf(buf,"%u",SuchAdr);
    DrawText(DIS->hDC,buf,-1,&DIS->rcItem,
      DT_CENTER|DT_VCENTER|DT_NOPREFIX|DT_SINGLELINE);
   }
#undef DIS
  }return TRUE;
 }/*switch*/
 return FALSE;
}
/*=====================================================*/
BOOL CALLBACK TransmitterDlgProc(HWND Wnd, UINT Msg, WPARAM wParam, LPARAM lParam) {
 switch (Msg) {
  case WM_INITDIALOG: {
   WORD Baudrate;
   UINT i;
   SetWindowLong(Wnd,DWL_USER,lParam);
   SetDlgItemInt(Wnd,1003,Get_ModulAdresse((BYTE)lParam),FALSE);
   Baudrate=Get_Baudrate((BYTE)lParam);
   for (i=1005; i<=1012; i++,Baudrate>>=1) {
    if (Baudrate==300U) {
     CheckDlgButton(Wnd,i,TRUE);
     break;
    }
   }
  }return TRUE;
  case WM_COMMAND: {
   switch (LOWORD(wParam)) {
    case 9: {
     WinHelp(Wnd,HelpFileName,HELP_CONTEXT,CM_KONFIGURATION_TRANSMITTER);
    }break;
    case 1: {
     int br;
     UINT a=GetDlgItemInt(Wnd,1003,NULL,FALSE);
     if (!a || a>255) {
      MBox(Wnd,0xA1A,MB_OK);
      SetEditFocus(Wnd,1003);
      return TRUE;
     }
     br=GetRadioCheck(Wnd,1005,1012);
     if (br<0) {
      MBox(Wnd,0xA1B,MB_OK);
      return TRUE;
     }
     SetWaitCursor(Wnd,TRUE);
     Set_ModulAdresse((BYTE)GetWindowLong(Wnd,DWL_USER),(BYTE)a);
     Set_Baudrate((BYTE)a,(WORD)(300U<<br));
     SetWaitCursor(Wnd,FALSE);
    }nobreak;
    case 2: EndDialog(Wnd,(int)(LOWORD(wParam)));
   }/*switch*/
  }break;
 }/*switch*/
 return FALSE;
}
/*=====================================================*/
BOOL CALLBACK IntervallDlgProc(HWND Wnd,UINT Msg,WPARAM wParam,LPARAM lParam){
 static const BYTE elapses[]={1,2,5,10,20,30,60,120,180};	//Sekunden
 switch (Msg) {		// Dieses Array entspricht String-Resource ab 0xA10!
  case WM_INITDIALOG: {
#define IV ((LPINTERVALL)lParam)
   UINT i;
   char buf[32];
   HWND w=GetDlgItem(Wnd,101);	// List-Box füllen (aus String-Ressource)
   SetDlgItemInt(Wnd,102,IV->count,FALSE);
   for (i=0; i<elemof(elapses); i++) {
    LoadString(hInstance,i+0xA10,buf,sizeof(buf));
    SendMessage(w,LB_ADDSTRING,0,(LPARAM)(LPSTR)buf);
    if (IV->elaps==elapses[i]) SendMessage(w,LB_SETCURSEL,i,0);
   }
   SetWindowLong(Wnd,DWL_USER,lParam);	// Zeiger retten
#undef IV
  }return TRUE;
  case WM_COMMAND: {
   switch (LOWORD(wParam)) {
    case 9: {
     WinHelp(Wnd,HelpFileName,HELP_CONTEXT,8000);
    }break;
    case 1: {
     lParam=GetWindowLong(Wnd,DWL_USER);
#define IV ((LPINTERVALL)lParam)
     IV->count=GetDlgItemInt(Wnd,102,NULL,FALSE);
     if (IV->count<2 || IV->count>1500) {
      MBox(Wnd,0xA19,MB_OK);
      SetEditFocus(Wnd,102);
      return TRUE;
     }
     IV->elaps=elapses[(int)SendDlgItemMessage(Wnd,101,LB_GETCURSEL,0,0)];
#undef IV
    }nobreak;
    case 2: EndDialog(Wnd,(int)(LOWORD(wParam)));
   }/*switch*/
  }break;
 }/*switch*/
 return FALSE;
}
/*=====================================================*/
BOOL CALLBACK PairInputDlgProc(HWND Wnd, UINT Msg, WPARAM wParam, LPARAM lParam) {
#define PI ((LPPAIRINPUT)lParam)
 switch (Msg) {
  case WM_INITDIALOG: {
   char s[64];
   SetWindowLong(Wnd,DWL_USER,lParam);	// Zeiger retten
   if (HIWORD(PI->title)) lstrcpyn(s,PI->title,sizeof(s));
   else LoadString(hInstance,LOWORD(PI->title),s,sizeof(s));
   SetWindowText(Wnd,s);
   if (PI->v1) {
    if (HIWORD(PI->v1)) lstrcpyn(s,PI->v1,sizeof(s));
    else LoadString(hInstance,LOWORD(PI->v1),s,sizeof(s));
    SetDlgItemText(Wnd,9001,s);
   }
   if (PI->v2) {
    if (HIWORD(PI->v2)) lstrcpyn(s,PI->v2,sizeof(s));
    else LoadString(hInstance,LOWORD(PI->v2),s,sizeof(s));
    SetDlgItemText(Wnd,9002,s);
   }
   if (PI->komma>=0) {
    SetDlgItemFloat(Wnd,9003,PI->komma,*PI->z1);
    SetDlgItemFloat(Wnd,9004,PI->komma,*PI->z2);
   }
  }return TRUE;
  case WM_COMMAND: {
   switch (LOWORD(wParam)) {
    case 9: {
     WinHelp(Wnd,HelpFileName,HELP_CONTEXT,3000);
    }break;
    case 1: {
     float z;
     lParam=GetWindowLong(Wnd,DWL_USER);
     if (!GetDlgItemFloat(Wnd,9003,&z)) return FALSE;
     if (!GetDlgItemFloat(Wnd,9004,PI->z2)) return FALSE;
     *PI->z1=z;				// beide Zahlen zugleich verändern!
     if (PI->sort && z>*PI->z2) {	// Umsortierung! z ist noch PI->z1
      *PI->z1=*PI->z2;
      *PI->z2=z;
     }
    }nobreak;
    case 2: EndDialog(Wnd,(int)(LOWORD(wParam)));
   }/*switch*/
  }break;
 }/*switch*/
 return FALSE;
#undef PI
}

#ifdef __BORLANDC__
# pragma argsused
#endif
int _stdcall PairInput(HWND Wnd,LPCSTR pi,LPCSTR p1,LPCSTR p2,
  float* p3,float* p4,BOOL p5,int p6) {
 return DialogBoxParam(hInstance,MAKEINTRESOURCE(3000),Wnd,PairInputDlgProc,
   (LPARAM)&pi);
}
/*=====================================================*/
#ifdef __BORLANDC__
# pragma argsused
#endif
BOOL CALLBACK AboutDlgProc(HWND Wnd, UINT Msg, WPARAM wParam, LPARAM lParam) {
 switch (Msg) {
  case WM_INITDIALOG: return TRUE;
  case WM_COMMAND: EndDialog(Wnd,(int)(LOWORD(wParam)));
 }
 return FALSE;
}

Detected encoding: ANSI (CP1252)4
Wrong umlauts? - Assume file is ANSI (CP1252) encoded