unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, IdBaseComponent, IdComponent, IdTCPConnection, IdTCPClient, IdHTTP, StdCtrls, ExtCtrls, ShellApi, math; const WM_TASKABAREVENT = WM_USER+1; //Taskbar message type TMessgroesse = (mgTemperatur,mgLuftfeuchte,mgWindgeschwindigkeit,mgWindrichtung, mgNiederschlag,mgGlobalstrahlung,mgLuftdruck); TZeitgroesse = (zgJahr,zgMonat,zgTag,zgStunde,zgMin10); TPegelZeitgroesse = (pzgJahr,pzgMonat,pzgTag,pzgStunde,pzgMin15); TMesswerte = array[TMessgroesse] of extended; TZeit = array[TZeitgroesse] of integer; TMesspunkt = record Zeit: TZeit; MW: TMesswerte; end; TPegelZeit = array[TPegelZeitgroesse] of integer; TPegelStation = (psBlankenstein,psKaulsdorf,psSaalfeld,psRudolstadt, psRothenstein,psCamburg,psMoeschlitz,psProbstzella,psKaulsdorfEichicht, psKatzhuette,psSchwarzburg,psFreienorla); TPegel = record Zeit: TPegelZeit; Hoehe: longint; end; PTPegel = ^TPegel; TForm1 = class(TForm) IdHTTP1: TIdHTTP; Timer1: TTimer; Image1: TImage; SonneIco: TImage; WolkeIco: TImage; SturmIco: TImage; RegenIco: TImage; RegenSturmIco: TImage; OpenDialog1: TOpenDialog; IdHTTP2: TIdHTTP; procedure Timer1Timer(Sender: TObject); procedure FormCreate(Sender: TObject); procedure FormClose(Sender: TObject; var Action: TCloseAction); procedure Image1DblClick(Sender: TObject); procedure FormDestroy(Sender: TObject); private { Private declarations } procedure TaskbarEvent(var Msg: TMessage); Message WM_TASKABAREVENT; procedure MyWindowProc(var Message:TMessage); public { Public-Deklarationen } nZeit: TZeit; nPegel: TPegelstation; letzteZeile: string; alteDaten: array of TMesspunkt; pegelStaende: array[TPegelStation] of TList; Sonnigkeit: extended; // \in [0..1] procedure setzeZaehler(Datenrefresh: boolean); procedure Icon_einfuegen(complete, modify: boolean); procedure Icon_entfernen(complete: boolean); procedure Icon_Auffrischen; procedure attachData(MW: TMesspunkt); function PegelstaendeEinlesen(s: string): boolean; procedure PegeldumpLesen; procedure PegeldumpSchreiben; procedure Zeichnen; end; var Form1: TForm1; NewTaskBar: Cardinal; // wird gerade eine neue Taskbar generiert? IconHint: string[64]; NotifyIconData: TNotifyIconData; warStart: boolean; const Messnamen: array[TMessgroesse] of String = ('Temperatur','Luftfeuchte','Windgeschwindigkeit','Windrichtung', 'Niederschlag','Globalstrahlung','Luftdruck'); Pegelstationsnamen: array[TPegelstation] of array[0..1] of String = (('Blankenstein','Blankenstein-Ros.'), ('Kaulsdorf',''), ('Saalfeld-Remschütz',''), ('Rudolstadt',''), ('Rothenstein',''), ('Camburg-Stöben',''), ('Möschlitz',''), ('Probstzella',''), ('Kaulsdorf-Eichicht',''), ('Katzhütte',''), ('Schwarzburg',''), ('Freienorla','')); Pegelstationsnummern: array[TPegelstation] of Extended = (57021,57025,57026,57027,57028,57033,57170,57200,57201,57211,57211.5,57240); Pegelgrenzen: array[TPegelstation,0..3] of Longint = ((210,230,270,310),(195,210,225,240),(200,230,260,290),(150,180,210,240), (250,290,330,370),(280,330,380,430),(180,200,220,240),(0,0,0,0), (130,170,210,230),(200,230,260,290),(130,150,170,190),(0,0,0,0)); Masseinheit: array[TMessgroesse] of String = ('°C','%','m/s','°','mm','W/m²','mbar'); Monatsnamen: array[1..12] of String = ('Januar','Februar','März','April','Mai','Juni','Juli', 'August','September','Oktober','November','Dezember'); DateiName = 'letztes_Wetter.txt'; PegelDateiName = 'letzte_Pegel.txt'; anzDaten = 7*24*6*4; Farben: array[TMessgroesse] of TColor = ($0000DF,$CFAF7F,$007FFF,$FF00FF,$FFAF3F,$3FAFAF,$AFAFAF); PFarben: array[TPegelstation] of TColor = ($000000,$000000,$000000,$FF0000,$7F0000,$000000,$000000,$000000,$000000,$000000,$000000,$000000); function separateValue(var S: String): string; function Zeit2Datetime(Z: TZeit): extended; function PegelstaendeVergleichen(P1,P2: Pointer): integer; function PegelzeitVergleichen(P1,P2: TPegelzeit): integer; function findePegelZeit(PS: TList; PZ: TPegelzeit): extended; function strToPegelZeit(s: string): TPegelzeit; function Pegelzeit2Datetime(Z: TPegelzeit): extended; function letzterMonat(t: TDateTime): TPoint; // x=Monat, y=Jahr function MyIntToStr(I,Ziff: longint): string; implementation {$R *.dfm} procedure TForm1.Icon_einfuegen(complete,modify: boolean); begin // das Icon in die Taskbar if complete then Fillchar(NotifyIconData,Sizeof(NotifyIconData),0); NotifyIconData.cbSize := Sizeof(NotifyIconData); NotifyIconData.Wnd := Handle; NotifyIconData.uFlags := NIF_MESSAGE or NIF_ICON or NIF_TIP; NotifyIconData.uCallbackMessage := WM_TASKABAREVENT; NotifyIconData.hIcon := Application.Icon.Handle; move(IconHint[1],NotifyIconData.szTip[0],64); if modify then Shell_NotifyIcon(NIM_MODIFY, @NotifyIconData) else Shell_NotifyIcon(NIM_ADD, @NotifyIconData); end; procedure TForm1.Icon_entfernen(complete: boolean); begin try if complete then FillChar(NotifyIconData,Sizeof(NotifyIconData),0); NotifyIconData.cbSize := Sizeof(NotifyIconData); NotifyIconData.Wnd := Self.Handle; NotifyIconData.uFlags := NIF_MESSAGE or NIF_ICON or NIF_TIP; NotifyIconData.uCallbackMessage := WM_TASKABAREVENT; NotifyIconData.hIcon := Application.Icon.Handle; NotifyIconData.szTip := 'Punkt'; Shell_NotifyIcon(NIM_DELETE, @NotifyIconData); except end; end; procedure TFOrm1.Icon_Auffrischen; var i,j: integer; zeige: word; tmp,a,e: extended; FA: TZeit; begin zeige:=0; // Regen?; Wind?; Sonne? if length(alteDaten)>0 then FA:=alteDaten[0].Zeit else begin FA[zgJahr]:=2000; FA[zgStunde]:=0; FA[zgMin10]:=0; end; for i:=1 to length(alteDaten)-1 do if Zeit2Datetime(alteDaten[i].Zeit)>Zeit2Datetime(FA) then FA:=alteDaten[i].Zeit; FA[zgTag]:=21; FA[zgMonat]:=3; // der Frühlingsanfang tmp:=0; // Sonne j:=0; for i:=0 to length(alteDaten)-1 do if Zeit2Datetime(alteDaten[i].Zeit)>now-1 then begin tmp:=tmp+alteDaten[i].MW[mgGlobalstrahlung]; inc(j); end; j:=j+Byte(j=0); tmp:=tmp/j; a:=50/180*pi; // Breitengrad e:=23.15/180*pi*sin((now-Zeit2Datetime(FA))*2*pi/365); // eff. Neigung tmp:=tmp/(1367/pi*(sin(a)*sin(e)*arccos(-tan(a)*tan(e))+cos(a)*cos(e)*sqrt(1-sqr(tan(a)*tan(e))))); // tmp:=tmp/(1367*sin((50+23.15*sin((now-Zeit2Datetime(FA))*2*pi/365))/180*pi)); zeige:=zeige or Byte(tmp > 0.25); Sonnigkeit:=tmp; tmp:=0; // Wind for i:=0 to length(alteDaten)-1 do if Zeit2Datetime(alteDaten[i].Zeit)>now-1/24 then tmp:=max(tmp,alteDaten[i].MW[mgWindgeschwindigkeit]); zeige:=zeige or (Byte(tmp > 2.5) shl 1); tmp:=0; // Regen for i:=0 to length(alteDaten)-1 do if Zeit2Datetime(alteDaten[i].Zeit)>now-1/24*14 then tmp:=tmp+alteDaten[i].MW[mgNiederschlag]; zeige:=zeige or (Byte(tmp > 0) shl 2); case zeige of $00: Application.Icon:=WolkeIco.Picture.Icon; $01: Application.Icon:=SonneIco.Picture.Icon; $02,$03: Application.Icon:=SturmIco.Picture.Icon; $04,$05: Application.Icon:=RegenIco.Picture.Icon; $06,$07: Application.Icon:=RegenSturmIco.Picture.Icon; end{of Case}; Icon_einfuegen(false,true); end; procedure TForm1.MyWindowProc(var Message:TMessage); begin if Message.Msg=NewTaskBar then begin Icon_einfuegen(true,false); end else WndProc(Message); end; procedure TForm1.TaskbarEvent(var Msg: TMessage); // was passiert, wenn auf unser Icon in der Taskleiste geklickt wird begin case Msg.LParam of WM_LBUTTONDBLCLK: if Messagedlg('Beenden?',mtConfirmation,[mbYes,mbNo],0) = mrYes then Form1.close; WM_LBUTTONDOWN: ; WM_LBUTTONUP: if Left>0 then begin Left:=-5000; Form1.Hide; ShowWindowAsync(Application.handle, SW_HIDE); end else begin Zeichnen; Form1.Width:=Image1.Width; Form1.Height:=Image1.Height; Left:=Screen.Width-Form1.Width; Top:=Screen.Height-Form1.Height-28; Form1.Show; end; WM_MBUTTONDBLCLK: ; WM_MBUTTONDOWN: ; WM_MBUTTONUP: ; WM_MOUSEACTIVATE: ; WM_MOUSEMOVE: ; WM_MOUSEWHEEL: ; WM_NCHITTEST: ; WM_NCLBUTTONDBLCLK: ; WM_NCLBUTTONDOWN: ; WM_NCLBUTTONUP: ; WM_NCMBUTTONDBLCLK: ; WM_NCMBUTTONDOWN: ; WM_NCMBUTTONUP: ; WM_NCMOUSEMOVE: ; WM_NCRBUTTONDBLCLK: ; WM_NCRBUTTONDOWN: ; WM_NCRBUTTONUP: ; WM_RBUTTONDBLCLK: Form1.close; WM_RBUTTONDOWN: ; WM_RBUTTONUP: ; end{of Case}; end; procedure TForm1.setzeZaehler(Datenrefresh: boolean); var F: Textfile; S: String; MP: TMessPunkt; MG: TMessgroesse; I: Longint; ZG: TZeitgroesse; begin setlength(alteDaten,anzDaten); if Datenrefresh then for I:=0 to length(alteDaten)-1 do begin for ZG:=low(ZG) to high(ZG) do alteDaten[I].Zeit[ZG]:=1; for MG:=low(MG) to high(MG) do alteDaten[I].MW[MG]:=1; end; nZeit[zgJahr]:=1999; nZeit[zgMonat]:=6; nZeit[zgTag]:=31; nZeit[zgStunde]:=0; nZeit[zgMin10]:=-1; assignfile(F,extractfilepath(Application.exename)+DateiName); if fileexists(extractfilepath(Application.exename)+DateiName) then begin reset(F); I:=-anzDaten; while not eof(F) do begin readln(F,S); inc(I); end; closefile(F); reset(F); while not eof(F) do begin readln(F,S); MP.Zeit[zgJahr]:=strtoint(separateValue(S)); if MP.Zeit[zgJahr]0 then begin dec(I); continue; end; for MG:=high(MG) downto low(MG) do MP.MW[MG]:=strtofloat(separateValue(S)); attachData(MP); end; end else Rewrite(F); closefile(F); if Form1.Visible then Zeichnen; Timer1.Enabled:=true; end; procedure TForm1.Timer1Timer(Sender: TObject); var Input: TStringlist; S,T: String; MG: TMessgroesse; MP: TMesspunkt; F: Textfile; istZahl: boolean; i: longint; begin Timer1.Enabled:=false; assignfile(F,extractfilepath(application.exename)+'pid'); rewrite(F); writeln(F,inttostr(application.Handle)); writeln(F,floattostr(now)); closefile(F); inc(nZeit[zgMin10]); if nZeit[zgMin10]>5 then begin nZeit[zgMin10]:=0; inc(nZeit[zgStunde]); if nZeit[zgStunde]>24 then begin nZeit[zgStunde]:=0; inc(nZeit[zgTag]); if nZeit[zgTag]>30+byte(nZeit[zgMonat] in [1,3,5,7,8,10,12])-(2-byte(nZeit[zgJahr] mod 4 = 0))*byte(nZeit[zgMonat]=2) then begin nZeit[zgTag]:=1; inc(nZeit[zgMonat]); if nZeit[zgMonat]>12 then begin nZeit[zgMonat]:=1; inc(nZeit[zgJahr]); end; end; end; end; if Zeit2DateTime(nZeit)>now then begin S:='http://www.tlug-jena.de/hw.inc/txt/'; // 57028.0_w_28.txt S:=S+inttostr(floor(Pegelstationsnummern[nPegel]))+'.'+ inttostr(round(10*(Pegelstationsnummern[nPegel]-floor(Pegelstationsnummern[nPegel])))); S:=S+'_w_28.txt'; if PegelstaendeEinlesen(IdHTTP2.Get(S)) then PegeldumpSchreiben; if nPegel=high(TPegelStation) then begin nPegel:=low(TPegelStation); Timer1.Interval:=120000; SetzeZaehler(false); if warStart then begin warStart:=false; Zeichnen; Form1.Width:=Image1.Width; Form1.Height:=Image1.Height; Left:=Screen.Width-Form1.Width; Top:=Screen.Height-Form1.Height-28; Form1.Show; Icon_auffrischen; end; end else begin inc(nPegel); Timer1.Interval:=50; end; Timer1.Enabled:=true; exit; end else Timer1.Interval:=50; Input:=TStringlist.Create; Input.Add('tag='+inttostr(nZeit[zgTag])); Input.Add('monat='+Monatsnamen[nZeit[zgMonat]]); Input.Add('jahr='+inttostr(nZeit[zgJahr])); Input.Add('stunde='+inttostr(nZeit[zgStunde])); Input.Add('minute='+inttostr(nZeit[zgMin10])+'0'); Input.Add('submit=Abfrage starten'); try S:=IdHTTP1.Post('http://wetter.mb.fh-jena.de/station/datenbank/php_alt/abfrage1.php',Input); except inc(nZeit[zgJahr]); Input.Free; Application.ProcessMessages; Timer1.Enabled:=true; exit; end; delete(S,1,pos('',uppercase(S))); while pos('.',S)>0 do S[pos('.',S)]:=','; for MG:=low(TMessgroesse) to high(TMessgroesse) do begin delete(S,1,pos(uppercase(Messnamen[MG]),uppercase(S))); delete(S,1,pos('>',S)); T:=trim(copy(S,1,pos('<',S)-1)); istzahl:=T<>''; for i:=1 to length(T) do istzahl:=istzahl and (T[i] in ['0'..'9','.',',','-']); if not istzahl then break; MP.MW[MG]:=strtofloat(T); end; MP.Zeit:=nZeit; if istzahl then begin S:=''; for MG:=low(TMessgroesse) to high(TMessgroesse) do S:=#9+floattostr(MP.MW[MG])+S; S:=inttostr(nZeit[zgJahr])+#9+inttostr(nZeit[zgMonat])+#9+inttostr(nZeit[zgTag])+#9+ inttostr(nZeit[zgStunde])+#9+inttostr(nZeit[zgMin10])+S; Assignfile(F,extractfilepath(Application.exename)+DateiName); if letzteZeile='' then begin Reset(F); while not eof(F) do Readln(F,letzteZeile); Closefile(F); end; if S<>letzteZeile then begin attachData(MP); if Form1.Visible then Zeichnen; Append(F); writeln(F,S); Closefile(F); letzteZeile:=S; end; Icon_Auffrischen; end; Input.Free; Application.ProcessMessages; Timer1.Enabled:=true; end; procedure TForm1.FormCreate(Sender: TObject); var PS: TPegelstation; F: Textfile; B: Boolean; S: String; begin if fileexists(extractfilepath(application.exename)+'pid') then begin assignfile(F,extractfilepath(application.exename)+'pid'); reset(F); readln(F,S); B:=S<>inttostr(application.Handle); if B then begin readln(F,S); B:=strtofloat(S)>now-1/24/60*5; end; closefile(F); if B then begin Application.Terminate; Form1.Close; halt; end; end; nPegel:=low(TPegelstation); for PS:=low(TPegelstation) to high(TPegelstation) do Pegelstaende[PS]:=TList.Create; warStart:=true; Sonnigkeit:=0; letzteZeile:=''; // Image1.Width:=Screen.Width; IconHint:='FH-Wetter'#0; // Message-ID generieren, die an uns gesendet wird, wenn eine neue // Taskbar generiert wird NewTaskBar:=RegisterWindowMessage('TaskbarCreated'); // Damit wir diese Message auch abfangen können, leiten wir die Botschaften // an unseren eigen Messagehandler weiter WindowProc:=MyWindowProc; Icon_einfuegen(true,false); Icon_Auffrischen; // Programm verstecken und Überwachung starten {$IFNDEF debug} Left:=-5000; Form1.Hide; ShowWindowAsync(Application.handle, SW_HIDE); {$ENDIF} PegeldumpLesen; setzeZaehler(true); end; procedure TForm1.attachData(MW: TMesspunkt); var i: integer; begin if length(alteDaten)alteDaten[I].MW[MG] then yMi[MG]:=alteDaten[I].MW[MG]; if yMa[MG]PTPegel(Pegelstaende[PS][I])^.Hoehe then pyMi[PS]:=PTPegel(Pegelstaende[PS][I])^.Hoehe; if pyMa[PS]1e-9 do begin while xA/(exp(xA)-1)<1/7 do xA:=xA-tmp; while xA/(exp(xA)-1)>1/7 do xA:=xA+tmp; tmp:=tmp*0.2; end; for MG:=low(MG) to high(MG) do begin dAchsen[MG]:=power(10,ceil(ln(max(1e-9,yMa[MG]-yMi[MG]))/ln(10))); yMi[MG]:=(Image1.Height-2)/max(1e-9,yMa[MG]-yMi[MG]); repeat if (Image1.Height-2)/yMi[MG]/dAchsen[MG]>=3 then continue; dAchsen[MG]:=dAchsen[MG]/10*3; if (Image1.Height-2)/yMi[MG]/dAchsen[MG]>=3 then continue; dAchsen[MG]:=dAchsen[MG]/3; until (Image1.Height-2)/yMi[MG]/dAchsen[MG]>=3; end; for PS:=low(PS) to high(PS) do pyMi[PS]:=(Image1.Height-2)/max(1e-9,pyMa[PS]-pyMi[PS]); Image1.Canvas.Rectangle(-10,-10,Image1.Width+10,Image1.Height+10); Iconhint:=inttostr(alteDaten[length(alteDaten)-1].Zeit[zgStunde])+':'+ inttostr(alteDaten[length(alteDaten)-1].Zeit[zgMin10])+'0 '+ inttostr(alteDaten[length(alteDaten)-1].Zeit[zgTag])+'.'+ inttostr(alteDaten[length(alteDaten)-1].Zeit[zgMonat])+'.'+ inttostr(alteDaten[length(alteDaten)-1].Zeit[zgJahr])+' '+ inttostr(floor(Sonnigkeit*100))+','+ char(ord('0')+(floor(Sonnigkeit*1000) mod 10))+ char(ord('0')+(round(Sonnigkeit*10000) mod 10))+'% '+ inttostr(PTPegel(Pegelstaende[psRothenstein].Last)^.Hoehe)+'cm'; Image1.Canvas.Font.Color:=$000000; Image1.Canvas.Pen.Color:=$000000; tmp:=floor(xMi/dxAchse)*dxAchse; while timetox((tmp-xMi)*xMa,xA,Image1.Width-3)0 then begin result:=copy(S,1,pos(#9,S)-1); delete(S,1,pos(#9,S)); end else begin result:=S; S:=''; end; end; function Zeit2Datetime(Z: TZeit): extended; //var I,Y: Word; begin // DecodeDate(now,Y,I,I); if Z[zgStunde]=24 then begin Z[zgStunde]:=0; inc(Z[zgTag]); if Z[zgTag]>30+byte(Z[zgMonat] in [1,3,5,7,8,10,12])-(2-byte(Z[zgJahr] mod 4 = 0))*byte(Z[zgMonat]=2) then begin Z[zgTag]:=1; inc(Z[zgMonat]); if Z[zgMonat]>12 then begin Z[zgMonat]:=1; inc(Z[zgJahr]); end; end; end; result:= // EncodeDate(Y,Z[zgMonat],Z[zgTag])+ EncodeDate(Z[zgJahr],Z[zgMonat],Z[zgTag])+ EncodeTime(Z[zgStunde],Z[zgMin10]*10,0,0) end; procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction); begin Icon_entfernen(true); end; procedure TForm1.Image1DblClick(Sender: TObject); var i: Longint; f: File; s: string; begin OpenDialog1.InitialDir:=extractfilepath(application.exename); if OpenDialog1.Execute then for i:=0 to OpenDialog1.Files.Count-1 do begin assignfile(f,OpenDialog1.Files[i]); reset(f,1); setlength(s,filesize(f)); blockread(f,s[1],length(s)); if not eof(f) then case messagedlg('Fehler beim Lesen von Datei '''+OpenDialog1.Files[i]+'''! Weiter probieren?',mterror,[mbYes,mbNo],0) of mryes: begin closefile(f); continue; end; mrno: begin closefile(f); exit; end; end{of Case}; PegelstaendeEinlesen(s); end; end; function TForm1.PegelstaendeEinlesen(s: string): boolean; var t: string; PS: TPegelstation; psda,wsda,gefunden: boolean; PZ: TPegelZeit; posi: extended; nps: PTPegel; PZG: TPegelZeitGroesse; i: longint; begin s:=s+#10; result:=false; psda:=false; wsda:=false; PS:=low(TPegelstation); while pos(#13,s)>0 do begin t:=copy(s,1,pos(#10,s)-1); delete(s,1,pos(#10,s)); while pos(#13,t)>0 do delete(t,pos(#13,t),1); if length(t)=0 then continue; if pos('Pegelname: ',t)=1 then begin delete(t,1,pos(' ',t)); PS:=low(TPegelstation); gefunden:=false; while PS<=high(TPegelstation) do begin for i:=0 to length(Pegelstationsnamen[psBlankenstein])-1 do gefunden:=gefunden or ((Pegelstationsnamen[PS,i]<>'') and (Pegelstationsnamen[PS,i]=t)); if gefunden then break; inc(PS); end; if not gefunden then begin Messagedlg('Unbekannter Pegelname: '''+t+'''!',mterror,[mbOk],0); exit; end; psda:=true; continue; end; if t='Durchfluss [m3/s]' then begin wsda:=false; continue; end; if t='Wasserstand [cm]' then begin wsda:=true; continue; end; if not (wsda and psda) then continue; if pos('Fluss: ',t)=1 then continue; if pos('Flusseinzugsgebiet: ',t)=1 then continue; if pos('Stationsnummer: ',t)=1 then begin delete(t,1,pos(' ',t)); while pos(' ',t)=1 do delete(t,1,1); while pos('.',t)>0 do t[pos('.',t)]:=','; if round(10*strtofloat(t))<>round(10*Pegelstationsnummern[PS]) then begin Messagedlg('erwartete Pegelstationsnummer ('+floattostr(Pegelstationsnummern[PS])+ ') für '+Pegelstationsnamen[PS,0]+' ist verschieden von der angegebenen Nummer ('+t+')!',mtError,[mbOk],0); exit; end; continue; end; if pos('Hinweise: ',t)=1 then continue; if pos('keine Werte',t)>0 then continue; PZ:=strToPegelZeit(t); posi:=findePegelZeit(Pegelstaende[PS],PZ); if odd(round(2*posi)) then begin result:=true; getmem(nps,sizeof(TPegel)); for PZG:=low(TPegelZeitGroesse) to high(TPegelZeitGroesse) do nps^.Zeit[PZG]:=PZ[PZG]; delete(t,1,pos(',',t)+1); nps^.Hoehe:=strtoint(t); Pegelstaende[PS].Insert(round(posi+0.5),nps); end; end; Zeichnen; end; procedure TForm1.FormDestroy(Sender: TObject); var PS: TPegelstation; i: longint; begin pegeldumpSchreiben; for PS:=low(TPegelstation) to high(TPegelstation) do begin for i:=0 to Pegelstaende[PS].count-1 do Freemem(Pegelstaende[PS][i],sizeof(TPegel)); Pegelstaende[PS].Free; end; if fileexists(extractfilepath(application.exename)+'pid') then deleteFile(extractfilepath(application.exename)+'pid'); end; function PegelstaendeVergleichen(P1,P2: Pointer): integer; begin result:=PegelzeitVergleichen(PTPegel(P1)^.Zeit,PTPegel(P2)^.Zeit); end; function PegelzeitVergleichen(P1,P2: TPegelZeit): integer; var PZG: TPegelZeitgroesse; begin result:=0; for PZG:=low(TPegelZeitgroesse) to high(TPegelZeitgroesse) do begin if P1[PZG]>P2[PZG] then begin result:=1; exit; end; if P1[PZG]og then begin result:=-0.5; exit; end; case Pegelzeitvergleichen(PTPegel(PS[ug])^.Zeit,PZ) of 0: begin result:=0; exit; end; 1: begin result:=-0.5; exit; end; end{of case}; case Pegelzeitvergleichen(PZ,PTPegel(PS[og])^.Zeit) of 0: begin result:=0; exit; end; 1: begin result:=og+0.5; exit; end; end{of case}; while ug'') and (Pegelstationsnamen[ps,i]=s)); if gefunden then break; inc(ps); end; if not gefunden then begin messagedlg('Pegelstation '''+s+''' nicht gefunden!',mterror,[mbOk],0); closefile(f); exit; end; psda:=true; continue; end; if not psda then begin messagedlg('Es wurde noch keine Pegelstation erwähnt!',mterror,[mbOk],0); exit; end; getmem(np,sizeof(TPegel)); Pegelstaende[ps].Add(np); for pzg:=low(TPegelzeitgroesse) to high(TPegelzeitgroesse) do begin np^.Zeit[pzg]:=strtoint(copy(s,1,pos(' ',s)-1)); delete(s,1,pos(' ',s)); end; np^.Hoehe:=strtoint(s); end; closefile(f); end; procedure TForm1.PegeldumpSchreiben; var dateischonda: boolean; f: textfile; ps: TPegelstation; pzg: TPegelzeitgroesse; i: longint; s: string; begin dateischonda:=fileexists(extractfilepath(Application.exename)+PegelDateiName); if dateischonda then begin i:=0; while fileexists(extractfilepath(Application.exename)+'temp'+inttostr(i)+'.txt') do inc(i); assignfile(f,extractfilepath(Application.exename)+'temp'+inttostr(i)+'.txt'); end else assignfile(f,extractfilepath(Application.exename)+PegelDateiName); rewrite(f); for ps:=low(TPegelstation) to high(TPegelstation) do begin writeln(f,'Station: '+Pegelstationsnamen[ps,0]); for i:=0 to Pegelstaende[ps].Count-1 do begin s:=''; for pzg:=low(TPegelzeitgroesse) to high(TPegelzeitgroesse) do s:=s+inttostr(PTPegel(Pegelstaende[ps][i])^.Zeit[pzg])+' '; writeln(f,s+inttostr(PTPegel(Pegelstaende[ps][i])^.Hoehe)); end; end; closefile(f); if dateischonda then begin deletefile(extractfilepath(Application.exename)+PegelDateiName); rename(f,extractfilepath(Application.exename)+PegelDateiName); end; end; function Pegelzeit2Datetime(Z: TPegelzeit): extended; begin if Z[pzgStunde]=24 then begin Z[pzgStunde]:=0; inc(Z[pzgTag]); if Z[pzgTag]>30+byte(Z[pzgMonat] in [1,3,5,7,8,10,12])-(2-byte(Z[pzgJahr] mod 4 = 0))*byte(Z[pzgMonat]=2) then begin Z[pzgTag]:=1; inc(Z[pzgMonat]); if Z[pzgMonat]>12 then begin Z[pzgMonat]:=1; inc(Z[pzgJahr]); end; end; end; result:= // EncodeDate(Y,Z[zgMonat],Z[zgTag])+ EncodeDate(Z[pzgJahr],Z[pzgMonat],Z[pzgTag])+ EncodeTime(Z[pzgStunde],Z[pzgMin15]*15,0,0) end; function LetzterMonat(t: TDatetime): TPoint; var dummy,m,y: Word; begin DecodeDate(t,y,m,dummy); dec(m); if m=0 then begin m:=12; dec(y); end; result.x:=m; result.y:=y; end; function MyIntToStr(I,Ziff: longint): string; begin result:=inttostr(I); while length(result)