Source file: /~heha/messtech/ad_da.zip/PAS/DIAGRAMM.PAS

Unit Diagramm;{
ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
º T E C H N I S C H E   U N I V E R S I T Ž T   C H E M N I T Z          º
º                                                                        º
º Programm zur Ansteuerung des AD/DA-Wandlermoduls mit Einchip-          º
º rechner 68HC11                                                         º
º                                                                        º
º UNIT zur Kurvenausgabe                                                 º
º                                                                        º
º Programmierer:    Torsten Levin                                        º
º                   03 AET 89                                            º
º                   TU Chemnitz-Zwickau                                  º
º                                                                        º
º Chemnitz, Januar-April 1993                                            º
ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
Laderoutinen stark beschleunigt mit BlockRead/BlockWrite, h#s 11/02
}

INTERFACE

Uses Crt,Graph,windows,Konstant,maus;



Type
 ByteA = Array[0..3,1..10000] of Byte;
 String8=String[8];

Var
 XMasstab,
 YMasstab    : TReal;
 Kanal       : ByteA;
 DirektWert  : Byte;

Procedure MaleKurvenWin;
Procedure Beschriften;
function LoadDatei2(Name:String):Boolean;
Function ByteToBit(Wert:Integer):String8;
function SaveDatei(Name:String;Kurve:Integer):Boolean;
Procedure MaleKurve;
Procedure OutstatusFenster;
Procedure OutXAchse;
function FreiAuswahl(X,Y:Integer;const Titel:String;
  Was:Boolean; Var Wert:TReal):Boolean;
function KanalUsage:Integer;

IMPLEMENTATION
uses addamodul,strings;

Var Null        : Integer;

function KanalUsage:Integer;
{liefert die Anzahl der aktiven Kan„le}
 var i,j:Integer;
 begin
  j:=0;
  for i:=0 to 3 do if KanalUsed[i] then Inc(j);
  KanalUsage:=j;
 end;

{---Prozedur Malen der Kurven------------------------------}
Procedure MaleKurve;

  Var Max,Min,
      Maxi,Mini,
      j         : Byte;
      i,K,Merkk,
      MaxSS     : Word;
      Merk,
      Zahl      : Integer;
      Drin      : Boolean;
  Begin
    Max:=BipOffset;
    Min:=BipOffset;
    For j:=0 To 3 do
    If KanalUsed[j] then
    Begin
      Maxi:=Kanal[j,1];
      Mini:=Kanal[j,1];
      For i:=1 To KanalSS[j] do
      Begin
	If Maxi<Kanal[j,i] Then Maxi:=Kanal[j,i];
	If Mini>Kanal[j,i] Then Mini:=Kanal[j,i];
      End;
      If Maxi>Max Then Max:=Maxi;
      If Mini<Min Then Min:=Mini;
      KanalMax[j]:=Maxi;
      KanalMin[j]:=Mini;
    End;
    If Max<129 Then Max:=129;
    If Min>127 Then Min:=127;
    If (KanalUsage=0)
	and YAutomatik and XAutomatik Then Begin
      Xmin:=0;
      Xmax:=Daten.SStellen;
      Ymin:= DAQ*(0-BipOffset);
      Ymax:= DAQ*(255-BipOffset);
    End
    else Begin
      If XAutomatik Then
      Begin
	Xmin:=0;
	MaxSS:=0;
	For j:=0 To 3 Do
	If KanalUsed[j] Then
	  If KanalSS[j] > MaxSS Then MaxSS:=KanalSS[j];
	If MaxSS<10 Then MaxSS:=10;
	Xmax:=MaxSS;
      End;
      If YAutomatik and (KanalUsage<>0) Then Begin
	Ymin:=(Min-BipOffset)*DAQ;
	Ymax:=(Max-BipOffset)*DAQ;
      End;
    End;
    Beschriften;
    OutStatusFenster;
    For j:=0 To 3 do
    If KanalUsed[j] and (KanalSS[j]>Round(Xmin)) then
    Begin
      K:=0;
      setcolor(Daten.Color[9+j]);
      setfillstyle(1,Daten.Color[9+j]);
      MerkK:=0;
      i:=Round(xmin)+1;
      Merk:=Null-Round((Kanal[j,i]-BipOffset)*DAQ*YMasstab);
      If Merk <  80 Then Merk :=  80;
      If Merk > 380 Then Merk := 380;
      Repeat
	Zahl:=Null-Round((Kanal[j,i]-BipOffset)*DAQ*YMasstab);
	Drin:=True;
	If Zahl <  80 Then
	Begin
	  Drin := False;
	  Zahl := 80;
	End;
	If Zahl > 380 Then
	Begin
	  Drin := False;
	  Zahl := 380;
	End;
	If XMasstab<1 Then
	Begin
	  While (K*XMasstab+Round(Xmin)) < I do
	  Begin
	    Inc(k);
	  End;
	  Case Daten.BildDatenNr Of
	  1 : If Drin then Putpixel(41+K,Zahl,Daten.Color[9+j]);
	  2 : If Drin then Line(41+MerkK,Merk,41+K,Zahl);
	  3 : If Drin then Begin
		Line(41+MerkK,Zahl,41+K,Zahl);
		Line(41+MerkK,Merk,41+MerkK,Zahl);
	      End;
	  4 : Bar(41+MerkK,Zahl,41+K,Null);
	  End;
	  Merk:=Zahl;
	  MerkK:=K;
	End;
	If XMasstab>1 Then
	Begin
	  If K*XMasstab+Round(Xmin) < I Then
	  Begin
	    Case Daten.BildDatenNr Of
	    1   : If Drin Then Putpixel(41+K,Zahl,Daten.Color[9+j]);
	    2,3 : If Drin then Line(40+K,Merk,41+K,Zahl);
	    4   : Line(41+K,Zahl,41+K,Null);
	    End;
	    Inc(k);
	    Merk:=Zahl;
	  End;
	End;
	inc(i);
      Until (i=KanalSS[j]) or (i=Round(Xmax)+1);
    End;
    OutXAchse;
  End;

{---Laden einer Datendatei---------------------------------}
type
 TWaveFileHeader=record
  riff: LongInt;	{="RIFF"}
  cks1: LongInt;
  wave: LongInt;	{="WAVE"}
  fmt:  LongInt;	{="fmt "}
  cks2: LongInt;
  wFormatTag: Word;	{=1}
  nChannels: Word;	{hier: =1}
  nSamplesPerSec: Longint;  {Sample-Rate}
  nAvgBytesPerSec: Longint; {hier: dito}
  nBlockAlign: Word;	{hier: =1}
  wBitsPerSample: Word;	{hier: =8}
  data: LongInt;	{="data"}
  datalen: LongInt;	{hier: Anzahl der Samples}
 end;

function LoadWAV(var f:File; KanalNum:Integer):Boolean;
 var
  wfh: TWaveFileHeader;
  K: Word;
 begin
  {$I-}
  LoadWAV:=false;
  BlockRead(f,wfh,sizeof(wfh));
  if InOutRes<>0 then exit;
  if wfh.riff<>$46464952 then exit;	{"RIFF"}
  if wfh.wave<>$45564157 then exit;	{"WAVE"}
  if wfh.fmt <>$20746D66 then exit;	{"fmt "}
  if wfh.wFormatTag<>1 then exit;	{PCM}
  if wfh.nChannels<>1 then exit;
  if wfh.nBlockAlign<>1 then exit;
  if wfh.wBitsPerSample<>8 then exit;
  if wfh.data<>$61746164 then exit;	{"data"}
  if wfh.datalen<10000 then K:=wfh.datalen else K:=10000;
  BlockRead(f,Kanal[KanalNum],K);
  if InOutRes<>0 then exit;
  KanalSS[KanalNum]:=K;
  KanalUsed[KanalNum]:=True;

  if KanalUsage=1 then begin	{Setzen der Samplerate ist hier angebracht}
   Daten.SStellen:=K; SStellenEinstellen(K);
   Daten.Urate:=1000/wfh.nSamplesPerSec; UrateEinstellen(Daten.Urate);
  end;
  LoadWAV:=true;
  {$I+}
 end;

function GetFileName(const s:String):String;
 var
  i: Integer;
  Datein  : String;
 begin
  Datein:=s;
  for i:=Length(Datein) downto 1 do
  if Datein[i]='\' then begin
   Delete(Datein,1,i);
   break;
  end;
  GetFileName:=Datein;
 end;

function DateiOK:Boolean;
 begin
  DateiOK:=Dateifehler(230,180,Ioresult);
 end;

function LoadDatei(Name:String; KanalNum:Integer):Boolean;
{Sollte mal auf .WAV umgestellt werden...}
 label
  exi0,exi1,exi2;
 type
  TBlock=array[0..10000] of Real;

 Var F       : File;
     i,K     : Word;
     Zahl    : Real;
     C       : String[1];
     block: ^TBlock;
 begin
  {$I-}
  LoadDatei:=false;
  str(KanalNum,C);
  status(200,150,'Einen Moment bitte!','Ich lade die Datei',
    GetFileName(Name),'als Kurve '+C+'.');
  Assign(F,Name);
  Reset(F,sizeof(real));
  if not DateiOK then goto exi0;
  BlockRead(F,Zahl,1);
  if not DateiOK then goto exi1;
  If (Round(Zahl*100)/100<>1234.56) Then begin
   Reset(F,1);
   if LoadWAV(f,KanalNum) then begin
    LoadDatei:=true;
    goto exi1;
   end;
   InOutRes:=1;
   DateiOK;
   goto exi1;
  end;
  blockread(F,Zahl,1);		{Welche Zahl?}
  if not DateiOK then goto exi1;
  GetMem(block,sizeof(TBlock));
  BlockRead(F,block^,10000,K);
  if not DateiOK then goto exi2;
  for i:=1 to K do begin
   Zahl:=block^[i-1];
   If Zahl>4.98 Then Zahl:=4.98
   else if Zahl<-5 Then Zahl:=-5;
   Kanal[KanalNum,i]:=Round(Zahl/DAQ)+BipOffset;
  End;
  KanalSS[KanalNum]:=i;
  KanalUsed[KanalNum]:=True;
  if KanalUsage=1 then begin
   Daten.SStellen:=K; SStellenEinstellen(K);
   {Daten.Urate:=???}
  end;
  LoadDatei:=true;
  exi2: FreeMem(block,sizeof(TBlock));
  exi1: Close(f);
  exi0: CloseStatus;
  {$I+}
 end;

function LoadDatei2(Name:String):Boolean;
 var
  KanalNum: Integer;
 Begin
  LoadDatei2:=false;
  KanalNum:=1;
  if not Auswahl(200,80,'Laden einer Kurve',Kanaldaten,KanalNum)
  then exit;
  LoadDatei2:=LoadDatei(Name,KanalNum-1);
 End;

{---Sichern einer Datendatei---------------------------------}
function SaveWAV(var f:File; KanalNum:Integer):Boolean;
 const wfh:TWaveFileHeader=(
  riff: $46464952;	{="RIFF"}
  cks1: 0;		{<=variabel}
  wave: $45564157;	{="WAVE"}
  fmt:  $20746D66;	{="fmt "}
  cks2: $10;
  wFormatTag: 1;
  nChannels: 1;
  nSamplesPerSec: 0;	{<=variabel}
  nAvgBytesPerSec: 0;	{<=variabel}
  nBlockAlign: 1;
  wBitsPerSample: 8;
  data: $61746164;	{="data"}
  datalen: 0);		{<=variabel}
 var
  K:Word;
 begin
  {$I-}
  K:=KanalSS[KanalNum];
  wfh.cks1:=K+sizeof(wfh)-8;	{=$24}
  wfh.nSamplesPerSec:=Round(1000/Daten.Urate);
  wfh.nAvgBytesPerSec:=wfh.nSamplesPerSec;
  wfh.datalen:=K;
  BlockWrite(f,wfh,sizeof(wfh));
  BlockWrite(f,Kanal[KanalNum],K);
  SaveWAV:=DateiOK;
  {$I+}
 end;

function SaveDatei(Name:String;Kurve:Integer):Boolean;
{Es ist wesentlich cleverer, .WAV-Dateien zu speichern}
 type
  TBlock=array[0..10000] of Real;

 Var F       : File;
      I       : Word;
      Zahl    : Real;
      C       : String[1];
      block: ^TBlock;

  Begin
   Str(Kurve,C);
   status(200,150,'Einen Moment bitte!','Ich sichere die',
     'Kurve '+C+' in der','Datei '+GetFileName(Name)+'.');
   Assign(F,Name);
   {$I-}
   rewrite(F,1);
   {$I+}
   if DateiOK then begin	{true wenn OK!!}
    SaveWAV(f,Kurve);
(*
    Zahl:=1234.56;		{Aua!}
    {$I-} blockwrite(F,Zahl,1); {$I+}
    if DateiOK then begin
     Zahl:=KanalSS[Kurve];
     {$I-} blockwrite(F,Zahl,1); {$I+}
     DateiOK;
     GetMem(block,sizeof(TBlock));
     for i:=1 to KanalSS[Kurve] do begin
      block^[i-1]:=(Kanal[Kurve,i]-BipOffset)*DAQ;
     end;
     {$I-} blockwrite(f,block^,KanalSS[Kurve]); {$I+}
     FreeMem(block,sizeof(TBlock));
     DateiOK;
     i:=1;
    End;
*)
    Close(f);
   End;
   CloseStatus;
  End;
{---Zeichnen des Kurvenfensters----------------------------}
  Procedure MaleKurvenWin;
  Begin
    Pressknopf(3,50,636,459{397});
{    Pressknopf(3,400,636,459);}
    OutStatusFenster;
  End;
{---Ausgabe des Statusfensters-----------------------------}
  Procedure Outstatusfenster;

  Var i,k : Byte;
      C   : String;
  Begin
    setfillstyle(1,Daten.Color[1]);
    Bar(4,401,635,458);
    Setcolor(Daten.Color[3]);
    line(6,416,331,416);
    Backknopf(6,403,331,456);
    For I:=1 To 4 Do line(6+i*65,404,6+i*65,455);
    Backknopf(490,403,633,456);
    settextstyle(0,0,0);
    K:=0;
    For I:=0 To 3 Do Begin
      Setcolor(Daten.Color[9+i]);
      pOuttextxy(77+i*65,407,Kanaldaten[i]);
      pOuttextxy(574,406+13*i,KanalDaten[i]);
      Setcolor(Daten.Color[3]);
      while k<8 do begin
       if Daten.Kanalnr[k] then break;
       Inc(k);
      end;
      If k<8 Then Outtextxy(494,406+13*i,'Kanal '+Chr(K+48)+' '+Chr(26))
      else Outtextxy(521,406+13*i,'-');
      inc(k);
    End;
    Backknopf(334,403,487,433);
    Backknopf(334,436,487,456);
    Pressknopf(339,419,482,430);
    Pressknopf(439,441,482,452);
    Setcolor(Daten.Color[3]);
    Str(Daten.Urate:2:2,C);
    Outtextxy(370,408,'Umsetzrate');
    Outtextxy(343,421,C+' ms,');
    if Daten.Urate<0.11 Then Str(1/Daten.Urate:2:2,C) else Str(1/Daten.Urate:1:3,C);
    RightTextXY(481,421,C+' kHz');
    Str(Daten.SStellen:5:0,C);
    Outtextxy(338,443,'St�tzstellen');
    RightTextXY(481,443,C);
    Outtextxy(10,420,'St�tzst');
    Outtextxy(63,420,'.');
    Outtextxy(10,433,'Umax');
    Outtextxy(10,446,'Umin');
    Outtextxy(45,433,'[V]');
    Outtextxy(45,446,'[V]');
    For i:=0 To 3 Do
    Begin
      If not(KanalUsed[i]) Then
      Begin
	Outtextxy(100+65*i,420,'-');
	Outtextxy(100+65*i,433,'-');
	Outtextxy(100+65*i,446,'-');
      End
      Else Begin
	Str(KanalSS[i],C);
	RightTextXY(132+65*i,420,C);
	Str((KanalMax[i]-BipOffset)*DAQ:1:4,C);
	RightTextXY(132+65*i,433,C);
	Str((KanalMin[i]-BipOffset)*DAQ:1:4,C);
	RightTextXY(132+65*i,446,C);
      End;
    End;
  End;

{---Umwandlung eines Bytes in den bin„ren Code-------------}
Function ByteToBit(Wert:Integer):String8;
 Var
  Bin: String8;
  m,i: Integer;
 Begin
  Bin[0]:=#8;
  If Wert>255 Then Wert:=255;
  If Wert<0 Then Wert:=0;
  m:=128;
  for i:=1 to 8 do begin
   if wert and m <>0 then Bin[i]:='1' else Bin[i]:='0';
   m:=m shr 1;
  end;
  ByteToBit:=Bin;
 End;

{---Zeichnen und Beschriften eines Diagramms---------------}
Procedure Beschriften;

 Var XStep,
      YStep    : TReal;
      Zahl     : TReal;
      i,j,k    : Byte;
      Zahlstr  : String[6];
      Einheit  : String[2];

  Begin
    setfillstyle(1,Daten.Color[1]);
    bar(4,51,635,396);
    setcolor(Daten.Color[3]);
    line(40,55,40,385);
    line(40,55,42,65);
    line(40,55,38,65);
    YStep:=Ymax-Ymin;
    i:=0;
    While YStep<1 do
    Begin
      Inc(i);
      YStep:=YStep*10;
    End;
    Ystep:=Round(YStep)/10;
    While i>0 do
    Begin
      Dec(i);
      YStep:=YStep/10;
    End;

    XStep:=Xmax-Xmin;
    i:=0;
    While XStep>100 do
    Begin
      Inc(i);
      XStep:=XStep/10;
    End;
    Xstep:=Round(XStep);
    While i>0 do
    Begin
      Dec(i);
      XStep:=XStep*10;
    End;
    XMasstab:=XStep/550;
    Zahl:=0;
    i:=0;
    While Zahl<Ymax do
    Begin
      Zahl:=Zahl+YStep;
      Inc(i);
    End;
    Zahl:=0;
    j:=0;
    While Zahl>Ymin do
    Begin
      Zahl:=Zahl-YStep;
      Inc(j);
    End;
    Zahl:=300/(i+j);
    YMasstab:=Zahl/YStep;
    setcolor(Daten.Color[3]);
    For k:=0 To i do line(36,80+Round(k*Zahl),39,80+Round(k*Zahl));
    Null:=80+Round(i*Zahl);
    For k:=0 To j do line(36,80+Round((i+k)*Zahl),39,80+Round((i+k)*Zahl));
    if (Ymax-Ymin) < 1 Then Einheit:='mV' else Einheit:='V';
    settextstyle(2,0,4);
    For k:=0 To i Do
    Begin
      If Einheit='V' Then str(k*YStep:2:1,Zahlstr)
      else str(k*YStep*1000:3:0,Zahlstr);
      RightTextXY(35,74+Round((i-k)*Zahl),Zahlstr);
    End;
    For k:=1 To j Do
    Begin
      If Einheit='V' Then str(k*YStep*(-1):2:1,Zahlstr)
      else str(k*YStep*(-1)*1000:3:0,Zahlstr);
      RightTextXY(35,74+Round((i+k)*Zahl),Zahlstr);
    End;
    settextstyle(2,0,2);
    For k:=0 To i Do Outtextxy(7,83+Round((i-k)*Zahl),ByteToBit(Round((k*YStep/DAQ)+BipOffset)));
    For k:=1 To j Do Outtextxy(7,83+Round((i+k)*Zahl),ByteToBit(Round((k*(-1)*YStep/DAQ)+BipOffset)));
    settextstyle(2,0,4);
    Outtextxy(7,52,'U ['+Einheit+']');
    settextstyle(0,0,0);
  End;

{---Ausgabe der X-Achse------------------------------------}
Procedure OutXAchse;

 Var i : Byte;
      Zahlstr : String[6];
      Einheit : String[6];
 Begin
    setcolor(Daten.Color[3]);
{    For i:=1 To 10 Do line(40+i*55,Null-2,40+i*55,Null+2);}
    line(41,Null,630,Null);
    line(630,Null,620,Null+2);
    line(630,Null,620,Null-2);
    settextstyle(2,0,4);
    For i:=1 To 10 Do
    Begin
      line(40+i*55,Null-2,40+i*55,Null+2);
      if Abs(Round(Xmasstab*i*55)-Xmasstab*i*55)<0.001 Then
	str(i*XMasstab*55+Xmin:4:0,Zahlstr)
      else str(i*XMasstab*55+Xmin:2:1,Zahlstr);
      CenterTextXY(38+i*55,Null-14,Zahlstr);
      If XMax*Daten.Urate>=0.01 then
      Begin
        Einheit:='[æs]';
        str((i*XMasstab*55+Xmin)*Daten.Urate*1000:2:2,Zahlstr);
      End;
      If XMax*Daten.Urate>=0.1 then str((i*XMasstab*55+Xmin)*Daten.Urate*1000:3:1,Zahlstr);
      If XMax*Daten.Urate>=1 then
      Begin
	Einheit:='[ms]';
        str((i*XMasstab*55+Xmin)*Daten.Urate:1:3,Zahlstr);
      End;
      If XMax*Daten.Urate>=10 then str((i*XMasstab*55+Xmin)*Daten.Urate:2:2,Zahlstr);
      If XMax*Daten.Urate>=100 then str((i*XMasstab*55+Xmin)*Daten.Urate:3:1,Zahlstr);
      If XMax*Daten.Urate>=1000 then
      Begin
	Einheit:='[s]';
	str((i*XMasstab*55+Xmin)*Daten.Urate/1000:1:3,Zahlstr);
      End;
      If XMax*Daten.Urate>=10000 then str((i*XMasstab*55+Xmin)*Daten.Urate/1000:2:2,Zahlstr);
      CenterTextXY(40+i*55,Null+3,Zahlstr);
    End;
    Outtextxy(614,Null+2,'t');
    Outtextxy(610,Null+11,Einheit);
    Outtextxy(610,Null-15,'St�.');
    settextstyle(0,0,0);
 End;

{---Prozedur Auswahl von Men�punkten mit freier Wahl-------}
function FreiAuswahl(X,Y:Integer;const Titel:String;
  Was:Boolean; Var Wert:TReal):Boolean;
 Const
  SStellen: array[0..6] of Single=(128,256,512,1024,2048,4096,8192);
  Urate: array[0..5] of Single=(0.5,1.0,5.0,10.0,20.0,50.0);

  Hauptfenster='Bitte w„hlen Sie!   '+Chr(24)+Chr(25)+' Auswahl   >F< Freie Wahl   >Return< OK   >ESC< Abbruch';
  FreieWahl   ='Der Wert muss in den angegebenen Grenzen liegen!   >Return< OK   >ESC< Abbruch';
 Var
  i: Integer;
  Ende,INF   : Boolean;
  Merk  : TReal;
  Letzt: Integer;
  Pos   : Integer;
  TestR : TReal;
  TestI : Integer;
  C     : String;

 procedure SetFreiFeld;
  begin
   if was Then Begin
    Str(Merk:1:0,C);
   end else begin
    Str(Merk:1:3,C);
   end;
   setfillstyle(1,Daten.Color[1]);
   bar(x+22,y+71+25*Letzt,x+98,y+84+25*Letzt);
   setcolor(Daten.Color[3]);
   RightTextXY(x+97,y+74+25*Letzt,C);
  end;

 Begin
  FreiAuswahl:=False;
  Ende:=False;
  Merk:=Wert;
  if not Was then Merk:=Round(1000/Merk)/1000;	{in kSamples}
  If Was Then Letzt:=HIGH(SStellen) else Letzt:=HIGH(Urate);
  pos:=-1;
  For i:=0 to Letzt do Begin
   If Was Then Begin
    if SStellen[i]=Merk Then Pos:=i
   end else Begin
    If Urate[i]=Merk Then Pos:=i;
   end;
  End;
  Openwindow2(x,y,210,130+25*Letzt,2,4,Titel,true);
  pressknopf2(x+9,y+39+25*(Letzt+1),102,57,true);
  pressknopf2(x+10,y+40+25*(Letzt+1),100,55,true);
  knopf2(x+15, y+95+25*Letzt,90,20,'&Freie Wahl',1,3);
  knopf2(x+120,y+65+25*Letzt,80,20,'OK',1,3);
  knopf2(x+120,y+95+25*Letzt,80,20,'Abbruch',1,3);
  pressknopf2(x+21,y+45+25*(Letzt+1),78,15,true);
  StatusZeile(Hauptfenster);
  setcolor(Daten.Color[3]);
  SetFreiFeld;
  For i:=0 To Letzt do Begin
   schalter(x+50,y+35+25*i,i=pos);
   setcolor(Daten.Color[3]);
   if was Then Str(SStellen[i]:1:0,C)
   else begin Str(Urate[i]:1:1,C); C:=C+' kSa/s'; end;
   RightTextXY(x+145,y+38+25*i,C);
{   outtextxy(x+_115_-pTextWidth(Urate[i-1]),y+13+25*(i+1)i,StrPas(Urate[i-1])+' kHz');}
   Pressknopf2(x+40,y+31+25*i,130,20,true);
  End;
  {HIER WEITERMACHEN!}
  repeat
   eingabe2;
   if Hit(#13,x+120,y+65+25*Letzt,80,20) then begin
    ende:=true;
    if was then Wert:=Merk
    else Wert:=1/Merk;
    FreiAuswahl:=True;
   end;
   if Hit(#27,x+120,y+95+25*Letzt,80,20) then begin
    ende:=true;
   end;
   If (ta=#0) and (tahi in [72,80]) then begin
    if tahi=72 then if pos>0 then dec(pos) else pos:=Letzt
    else if pos<Letzt then inc(pos) else pos:=0;
    pressknopf2(x+50,y+10+25*(pos+1),12,12,true);
    delay(100);
    for i:=0 to Letzt do schalter(x+50,y+35+25*i,i=pos);
    if Was then Merk:=SStellen[pos] else Merk:=Urate[pos];
    SetFreiFeld;
   end;
   for i:=0 to letzt do if Hit(#0,x+50,y+35+25*i,12,12) then begin
    if pos>=0 then schalter(x+50,y+35+25*pos,false);
    pos:=i;
    schalter(x+50,y+35+25*pos,true);
    if was Then Merk:=SStellen[pos] else Merk:=Urate[pos];
    SetFreiFeld;
   End;
   if Hit('F',x+15,y+95+25*Letzt,90,20) then begin
    StatusZeile(FreieWahl);
    If Was Then Begin
     str(Round(Merk),C);
     INF:=edit(x+100,y+25*(Letzt+1),'Freie Eingabe',5,0,
       'Bitte geben Sie die','St�tzstellen ein','[ 20..10000 ]',C);
     If INF Then begin
      Val(C,Merk,Testi);
      If Merk<20 Then Merk:=20;
      If Merk>10000 Then Merk:=10000;
      SetFreiFeld;
      Pos:=-1;
      For i:=0 to Letzt do Begin
       If SStellen[i]=Merk Then Pos:=i
      End;
      For i:=0 To Letzt do schalter(x+50,y+35+25*i,i=pos);
     End;
    End else Begin
     str(Merk:1:3,C);
     INF:=edit(x+100,y+25*(Letzt+1),'Freie Eingabe',6,3,
       'Umsetzrate','in kSamples/s','[0.5..50 kSa/s]',C);
     If INF Then begin
      Val(C,Merk,Testi);
      If Merk>50 Then Merk:=50;
      If Merk<0.5 Then Merk:=0.5;
{       Merk:=Round(Merk*100)/100;}
      SetFreiFeld;
{      if Merk<0.11 Then Str(1/Merk:2:2,C) else Str(1/Merk:1:3,C);}
      Pos:=-1;
      For i:=0 to Letzt do Begin
       If Urate[i]=Merk Then Pos:=i;
      End;
      For i:=0 To Letzt do schalter(x+50,y+35+25*i,i=pos);
     End;
    End;
    StatusZeile(HauptFenster);
   end;
  Until ende;
  closewindow;
 End;

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