123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692 |
- unit Main;
- interface
- uses
- Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
- Menus, StdCtrls, ExtCtrls, Buttons,
- libmng;
- {****************************************************************************}
- {* For conditions of distribution and use, *}
- {* see copyright notice in libmng.pas *}
- {****************************************************************************}
- {* *}
- {* project : libmng *}
- {* file : main.pas copyright (c) 2000-2002 G.Juyn *}
- {* version : 1.0.5 *}
- {* *}
- {* purpose : Main form for mngview application *}
- {* *}
- {* author : G.Juyn *}
- {* web : http://www.3-t.com *}
- {* email : mailto:[email protected] *}
- {* *}
- {* comment : this is the heart of the mngview applciation *}
- {* *}
- {* changes : 0.5.1 - 05/02/2000 - G.Juyn *}
- {* - added this version block *}
- {* - made the initialization part more robust *}
- {* eg. program aborts on initialization errors *}
- {* - B002(105797) - added check for existence of default sRGB *}
- {* profile (now included in distribution) *}
- {* - added mng_cleanup to program exit *}
- {* 0.5.1 - 05/08/2000 - G.Juyn *}
- {* - changed to stdcall convention *}
- {* 0.5.1 - 05/11/2000 - G.Juyn *}
- {* - changed callback function declarations *}
- {* *}
- {* 0.5.3 - 06/16/2000 - G.Juyn *}
- {* - removed processmessages call from refresh callback *}
- {* 0.5.3 - 06/17/2000 - G.Juyn *}
- {* - switched "storechunks" off *}
- {* 0.5.3 - 06/26/2000 - G.Juyn *}
- {* - changed definition of userdata to mng_ptr *}
- {* 0.5.3 - 06/28/2000 - G.Juyn *}
- {* - changed the default icon to something more appropriate *}
- {* - changed definition of memory alloc size to mng_size_t *}
- {* 0.5.3 - 06/29/2000 - G.Juyn *}
- {* - changed order of refresh parameters *}
- {* *}
- {* 0.9.0 - 06/30/2000 - G.Juyn *}
- {* - changed refresh parameters to 'x,y,width,height' *}
- {* *}
- {* 0.9.1 - 07/08/2000 - G.Juyn *}
- {* - fixed to use returncode constants *}
- {* - changed to accomodate MNG_NEEDTIMERWAIT returncode *}
- {* 0.9.1 - 07/10/2000 - G.Juyn *}
- {* - changed to use suspension-mode *}
- {* *}
- {* 0.9.3 - 09/11/2000 - G.Juyn *}
- {* - removed some tesst-stuff *}
- {* *}
- {* 1.0.1 - 05/02/2000 - G.Juyn *}
- {* - removed loading default sRGB profile (auto in libmng) *}
- {* *}
- {* 1.0.5 - 09/16/2002 - G.Juyn *}
- {* - added dynamic MNG features *}
- {* 1.0.5 - 11/27/2002 - G.Juyn *}
- {* - fixed freeze during read-cycle *}
- {* *}
- {****************************************************************************}
- type
- TMainForm = class(TForm)
- OFMainMenu: TMainMenu;
- OFMenuFile: TMenuItem;
- OFMenuFileOpen: TMenuItem;
- OFMenuFileProfile: TMenuItem;
- OFMenuFileN1: TMenuItem;
- OFMenuFileExit: TMenuItem;
- OFMenuOptions: TMenuItem;
- OFMenuOptionsModemSpeed: TMenuItem;
- OFMenuOptionsModem28k8: TMenuItem;
- OFMenuOptionsModem33k6: TMenuItem;
- OFMenuOptionsModem56k: TMenuItem;
- OFMenuOptionsModemISDN64: TMenuItem;
- OFMenuOptionsModemISDN128: TMenuItem;
- OFMenuOptionsModemCable512: TMenuItem;
- OFMenuOptionsModemUnlimited: TMenuItem;
- OFTimer: TTimer;
- OFOpenDialog: TOpenDialog;
- OFOpenDialogProfile: TOpenDialog;
- OFImage: TImage;
- procedure FormCreate(Sender: TObject);
- procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
- procedure FormShow(Sender: TObject);
- procedure FormResize(Sender: TObject);
- procedure FormKeyDown(Sender: TObject; var Key: Word;
- Shift: TShiftState);
- procedure FormMouseMove(Sender: TObject; Shift: TShiftState; X,
- Y: Integer);
- procedure OFImageMouseMove(Sender: TObject; Shift: TShiftState; X,
- Y: Integer);
- procedure OFImageMouseDown(Sender: TObject; Button: TMouseButton;
- Shift: TShiftState; X, Y: Integer);
- procedure OFImageMouseUp(Sender: TObject; Button: TMouseButton;
- Shift: TShiftState; X, Y: Integer);
- procedure OFTimerTimer(Sender: TObject);
- procedure OFMenuFileOpenClick(Sender: TObject);
- procedure OFMenuFileProfileClick(Sender: TObject);
- procedure OFMenuFileExitClick(Sender: TObject);
- procedure OFMenuOptionsModemSpeedClick(Sender: TObject);
- procedure OFMenuOptionsModemXClick(Sender: TObject);
- private
- { Private declarations }
- SFFileName : string; { filename of the input stream }
- OFFile : TFileStream; { input stream }
- IFHandle : mng_handle; { the libray handle }
- OFBitmap : TBitmap; { drawing canvas }
- BFCancelled : boolean; { <esc> or app-exit }
- BFHasMouse : boolean; { mouse is/was over image }
- IFTicks : cardinal; { used to fake slow connections }
- IFBytes : cardinal;
- IFBytesPerSec : integer;
- procedure MNGerror (SHMsg : string);
- public
- { Public declarations }
- end;
- var
- MainForm: TMainForm;
- {****************************************************************************}
- implementation
- {$R *.DFM}
- {****************************************************************************}
- {$F+}
- function Memalloc (iLen : mng_uint32) : mng_ptr; stdcall;
- {$F-}
- begin
- getmem (Result, iLen); { get memory from the heap }
- fillchar (Result^, iLen, 0); { and initialize it }
- end;
- {****************************************************************************}
- {$F+}
- procedure Memfree (iPtr : mng_ptr;
- iLen : mng_size_t); stdcall;
- {$F-}
- begin
- freemem (iPtr, iLen); { free the memory }
- end;
- {****************************************************************************}
- {$F+}
- function Openstream (hHandle : mng_handle) : mng_bool; stdcall;
- {$F-}
- var OHForm : TMainForm;
- begin { get a fix on our form }
- OHForm := TMainForm (mng_get_userdata (hHandle));
- with OHFORM do
- begin
- if OFFile <> nil then { free previous stream (if any) }
- OFFile.Free;
- { open a new stream }
- OFFile := TFileStream.Create (SFFileName, fmOpenRead or fmShareDenyWrite);
- end;
- Result := MNG_TRUE;
- end;
- {****************************************************************************}
- {$F+}
- function Closestream (hHandle : mng_handle) : mng_bool; stdcall;
- {$F-}
- var OHForm : TMainForm;
- begin { get a fix on our form }
- OHForm := TMainForm (mng_get_userdata (hHandle));
- with OHFORM do
- begin
- OFFile.Free; { cleanup the stream }
- OFFile := nil; { don't use it again ! }
- end;
- Result := MNG_TRUE;
- end;
- {****************************************************************************}
- {$F+}
- function Readdata ( hHandle : mng_handle;
- pBuf : mng_ptr;
- iBuflen : mng_uint32;
- var pRead : mng_uint32) : mng_bool; stdcall;
- {$F-}
- var OHForm : TMainForm;
- IHTicks : cardinal;
- IHByte1 : cardinal;
- IHByte2 : cardinal;
- IHBytesPerSec : cardinal;
- begin
- { get a fix on our form }
- OHForm := TMainForm (mng_get_userdata (hHandle));
- with OHForm do
- begin { are we at EOF ? }
- if OFFile.Position >= OFFile.Size then
- begin
- pRead := 0; { indicate so }
- end
- else
- begin
- IHBytesPerSec := IFBytesPerSec; { fake a slow connection }
- if IHBytesPerSec > 0 then
- begin
- IHTicks := Windows.GetTickCount;
- IHByte1 := round (((IHTicks - IFTicks) / 1000) * IHBytesPerSec);
- IHByte2 := (IFBytes + iBuflen);
- if ((IHByte2 - IHByte1) div IHBytesPerSec) > 10 then
- Windows.Sleep ((IHByte2 - IHByte1) div IHBytesPerSec);
- end;
- { read the requested data }
- pRead := OFFile.Read (pBuf^, iBuflen);
- IFBytes := IFBytes + pRead;
- end;
- end;
- Result := MNG_TRUE;
- end;
- {****************************************************************************}
- {$F+}
- function ProcessHeader (hHandle : mng_handle;
- iWidth : mng_uint32;
- iHeight : mng_uint32) : mng_bool; stdcall;
- {$F-}
- var OHForm : TMainForm;
- begin { get a fix on our form }
- OHForm := TMainForm (mng_get_userdata (hHandle));
- with OHForm do
- begin
- OFBitmap.Width := iWidth; { store the new dimensions }
- OFBitmap.Height := iHeight;
- OFImage.Left := 0; { adjust the visible component }
- OFImage.Top := 0;
- OFImage.Width := iWidth;
- OFImage.Height := iHeight;
- FormResize (OHForm); { force re-centering the image}
- { clear the canvas & draw an outline }
- OFBitmap.Canvas.Brush.Color := clGray;
- OFBitmap.Canvas.Brush.Style := bsSolid;
- OFBitmap.Canvas.FillRect (OFBitmap.Canvas.ClipRect);
- OFBitmap.Canvas.Brush.Color := clRed;
- OFBitmap.Canvas.Brush.Style := bsSolid;
- OFBitmap.Canvas.Pen.Color := clRed;
- OFBitmap.Canvas.Pen.Style := psSolid;
- OFBitmap.Canvas.FrameRect (OFBitmap.Canvas.ClipRect);
- OFImage.Picture.Assign (OFBitmap); { make sure it gets out there }
- { tell the library we want funny windows-bgr}
- if mng_set_canvasstyle (hHandle, MNG_CANVAS_BGRX8) <> 0 then
- MNGerror ('libmng reported an error setting the canvas style');
- end;
- Result := MNG_TRUE;
- end;
- {****************************************************************************}
- {$F+}
- function GetCanvasLine (hHandle : mng_handle;
- iLinenr : mng_uint32) : mng_ptr; stdcall;
- {$F-}
- var OHForm : TMainForm;
- begin { get a fix on our form }
- OHForm := TMainForm (mng_get_userdata (hHandle));
- { easy with these bitmap objects ! }
- Result := OHForm.OFBitmap.ScanLine [iLinenr];
- end;
- {****************************************************************************}
- {$F+}
- function ImageRefresh (hHandle : mng_handle;
- iX : mng_uint32;
- iY : mng_uint32;
- iWidth : mng_uint32;
- iHeight : mng_uint32) : mng_bool; stdcall;
- {$F-}
- var OHForm : TMainForm;
- begin { get a fix on our form }
- OHForm := TMainForm (mng_get_userdata (hHandle));
- { force redraw }
- OHForm.OFImage.Picture.Assign (OHForm.OFBitmap);
- Result := MNG_TRUE;
- end;
- {****************************************************************************}
- {$F+}
- function GetTickCount (hHandle : mng_handle) : mng_uint32; stdcall;
- {$F-}
- begin
- Result := Windows.GetTickCount; { windows knows that }
- end;
- {****************************************************************************}
- {$F+}
- function SetTimer (hHandle : mng_handle;
- iMsecs : mng_uint32) : mng_bool; stdcall;
- {$F-}
- var OHForm : TMainForm;
- begin { get a fix on our form }
- OHForm := TMainForm (mng_get_userdata (hHandle));
- OHForm.OFTimer.Interval := iMsecs; { and set the timer }
- OHForm.OFTimer.Enabled := true;
- Result := MNG_TRUE;
- end;
- {****************************************************************************}
- procedure TMainForm.FormCreate(Sender: TObject);
- var IHRed, IHGreen, IHBlue : word;
- begin { initialize }
- OFBitmap := TBitmap.Create;
- IFBytesPerSec := 10000000;
- BFHasMouse := false;
- OFFile := nil;
- OFOpenDialog.Initialdir := '';
- OFBitmap.HandleType := bmDIB; { make it a 24-bit DIB }
- OFBitmap.PixelFormat := pf32bit;
- { now initialize the library }
- IFHandle := mng_initialize (mng_ptr(self), Memalloc, Memfree, nil);
- if IFHandle = NIL then
- begin
- MNGerror ('libmng initialization error' + #13#10 +
- 'Program aborted');
- Windows.Postmessage (handle, WM_Close, 0, 0);
- Exit;
- end;
- { no need to store chunk-info ! }
- mng_set_storechunks (IFHandle, MNG_FALSE);
- { do not use suspension-buffer }
- mng_set_suspensionmode (IFHandle, MNG_FALSE);
- { set all the callbacks }
- if (mng_setcb_openstream (IFHandle, Openstream ) <> MNG_NOERROR) or
- (mng_setcb_closestream (IFHandle, Closestream ) <> MNG_NOERROR) or
- (mng_setcb_readdata (IFHandle, Readdata ) <> MNG_NOERROR) or
- (mng_setcb_processheader (IFHandle, ProcessHeader) <> MNG_NOERROR) or
- (mng_setcb_getcanvasline (IFHandle, GetCanvasLine) <> MNG_NOERROR) or
- (mng_setcb_refresh (IFHandle, ImageRefresh ) <> MNG_NOERROR) or
- (mng_setcb_gettickcount (IFHandle, GetTickCount ) <> MNG_NOERROR) or
- (mng_setcb_settimer (IFHandle, SetTimer ) <> MNG_NOERROR) then
- begin
- MNGerror ('libmng reported an error setting a callback function!' + #13#10 +
- 'Program aborted');
- Windows.Postmessage (handle, WM_Close, 0, 0);
- Exit;
- end;
- IHRed := (Color ) and $FF; { supply our own bg-color }
- IHGreen := (Color shr 8) and $FF;
- IHBlue := (Color shr 16) and $FF;
- IHRed := (IHRed shl 8) + IHRed;
- IHGreen := (IHGreen shl 8) + IHGreen;
- IHBlue := (IHBlue shl 8) + IHBlue;
- if mng_set_bgcolor (IFHandle, IHRed, IHGreen, IHBlue) <> MNG_NOERROR then
- MNGerror ('libmng reported an error setting the background color!');
- end;
- {****************************************************************************}
- procedure TMainForm.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
- begin
- OFTimer.Enabled := false;
- BFCancelled := true;
- { if we're still animating then stop it }
- if mng_status_running (IFHandle) and not mng_status_reading (IFHandle) then
- if mng_display_freeze (IFHandle) <> MNG_NOERROR then
- MNGerror ('libmng reported an error during display_freeze!');
- mng_cleanup (IFHandle);
- end;
- {****************************************************************************}
- procedure TMainForm.FormShow(Sender: TObject);
- begin
- FormResize (self);
- end;
- {****************************************************************************}
- procedure TMainForm.FormResize(Sender: TObject);
- begin { center the image in the window }
- if ClientWidth < OFImage.Width then
- OFImage.Left := 0
- else
- OFImage.Left := (ClientWidth - OFImage.Width ) div 2;
- if ClientHeight < OFImage.Height then
- OFImage.Top := 0
- else
- OFImage.Top := (ClientHeight - OFImage.Height) div 2;
- end;
- {****************************************************************************}
- procedure TMainForm.FormKeyDown(Sender: TObject; var Key: Word;
- Shift: TShiftState);
- begin
- if Key = vk_Escape then { pressing <esc> will freeze an animation }
- begin
- OFTimer.Enabled := false; { don't let that timer go off then ! }
- BFCancelled := true;
- if mng_status_running (IFHandle) and not mng_status_reading (IFHandle) then
- if mng_display_freeze (IFHandle) <> MNG_NOERROR then
- MNGerror ('libmng reported an error during display_freeze!');
- end;
- end;
- {****************************************************************************}
- procedure TMainForm.FormMouseMove(Sender: TObject; Shift: TShiftState; X,
- Y: Integer);
- begin
- if mng_status_dynamic (IFHandle) then
- begin
- if BFHasMouse then { if we had the mouse, it's left ! }
- begin
- if mng_trapevent (IFHandle, 3, 0, 0) <> MNG_NOERROR then
- MNGerror ('libmng reported an error during trapevent!');
- BFHasMouse := false;
- end;
- end;
- end;
- {****************************************************************************}
- procedure TMainForm.OFImageMouseMove(Sender: TObject; Shift: TShiftState;
- X, Y: Integer);
- begin
- if mng_status_dynamic (IFHandle) then
- begin
- if BFHasMouse then { did we have the mouse already ? }
- begin
- if mng_trapevent (IFHandle, 2, X, Y) <> MNG_NOERROR then
- MNGerror ('libmng reported an error during trapevent!');
- end
- else
- begin { if not, it has entered ! }
- if mng_trapevent (IFHandle, 1, X, Y) <> MNG_NOERROR then
- MNGerror ('libmng reported an error during trapevent!');
- BFHasMouse := true;
- end;
- end;
- end;
- {****************************************************************************}
- procedure TMainForm.OFImageMouseDown(Sender: TObject; Button: TMouseButton;
- Shift: TShiftState; X, Y: Integer);
- begin
- if mng_status_dynamic (IFHandle) then
- if mng_trapevent (IFHandle, 4, X, Y) <> MNG_NOERROR then
- MNGerror ('libmng reported an error during trapevent!');
- end;
- {****************************************************************************}
- procedure TMainForm.OFImageMouseUp(Sender: TObject; Button: TMouseButton;
- Shift: TShiftState; X, Y: Integer);
- begin
- if mng_status_dynamic (IFHandle) then
- if mng_trapevent (IFHandle, 5, X, Y) <> MNG_NOERROR then
- MNGerror ('libmng reported an error during trapevent!');
- end;
- {****************************************************************************}
- procedure TMainForm.OFTimerTimer(Sender: TObject);
- var IHRslt : mng_retcode;
- begin
- OFTimer.Enabled := false; { only once ! }
- if not BFCancelled then
- begin { and inform the library }
- IHRslt := mng_display_resume (IFHandle);
- if (IHRslt <> MNG_NOERROR) and (IHRslt <> MNG_NEEDTIMERWAIT) then
- MNGerror ('libmng reported an error during display_resume!');
- end;
- end;
- {****************************************************************************}
- procedure TMainForm.OFMenuFileOpenClick(Sender: TObject);
- var IHRslt : mng_retcode;
- begin
- OFOpenDialog.InitialDir := '';
- OFOpenDialog.FileName := SFFileName;
- if OFOpenDialog.Execute then { get the filename }
- begin
- if OFTimer.Enabled then { if the lib was active; stop it }
- begin
- OFTimer.Enabled := false;
- Application.ProcessMessages; { process any timer requests (for safety) }
- { now freeze the animation }
- if mng_display_freeze (IFHandle) <> MNG_NOERROR then
- MNGerror ('libmng reported an error during display_freeze!');
- end;
- { save interesting fields }
- SFFileName := OFOpenDialog.FileName;
- IFTicks := Windows.GetTickCount;
- IFBytes := 0;
- BFCancelled := false;
- { always reset (just in case) }
- if mng_reset (IFHandle) <> MNG_NOERROR then
- MNGerror ('libmng reported an error during reset!')
- else
- begin { and let the lib do it's job ! }
- IHRslt := mng_readdisplay (IFHandle);
- if (IHRslt <> MNG_NOERROR) and (IHRSLT <> MNG_NEEDTIMERWAIT) then
- MNGerror ('libmng reported an error reading the input file!');
- end;
- end;
- end;
- {****************************************************************************}
- procedure TMainForm.OFMenuFileProfileClick(Sender: TObject);
- var SHProfileDir : array [0 .. MAX_PATH + 20] of char;
- begin
- GetSystemDirectory (@SHProfileDir, MAX_PATH);
- strcat (@SHProfileDir, '\Color');
- OFOpenDialogProfile.InitialDir := strpas (@SHProfileDir);
- if OFOpenDialogProfile.Execute then
- if mng_set_outputprofile (IFHandle, pchar (OFOpenDialogProfile.FileName)) <> 0 then
- MNGerror ('libmng reported an error setting the output-profile!');
- end;
- {****************************************************************************}
- procedure TMainForm.OFMenuFileExitClick(Sender: TObject);
- begin
- if mng_cleanup (IFHandle) <> MNG_NOERROR then
- MNGerror ('libmng cleanup error');
- Close;
- end;
- {****************************************************************************}
- procedure TMainForm.OFMenuOptionsModemSpeedClick(Sender: TObject);
- begin
- OFMenuOptionsModem28k8.Checked := false;
- OFMenuOptionsModem33k6.Checked := false;
- OFMenuOptionsModem56k.Checked := false;
- OFMenuOptionsModemISDN64.Checked := false;
- OFMenuOptionsModemISDN128.Checked := false;
- OFMenuOptionsModemCable512.Checked := false;
- OFMenuOptionsModemUnlimited.Checked := false;
- if IFBytesPerSec = OFMenuOptionsModem28k8.Tag div 10 then
- OFMenuOptionsModem28k8.Checked := true
- else
- if IFBytesPerSec = OFMenuOptionsModem33k6.Tag div 10 then
- OFMenuOptionsModem33k6.Checked := true
- else
- if IFBytesPerSec = OFMenuOptionsModem56k.Tag div 10 then
- OFMenuOptionsModem56k.Checked := true
- else
- if IFBytesPerSec = OFMenuOptionsModemISDN64.Tag div 10 then
- OFMenuOptionsModemISDN64.Checked := true
- else
- if IFBytesPerSec = OFMenuOptionsModemISDN128.Tag div 10 then
- OFMenuOptionsModemISDN128.Checked := true
- else
- if IFBytesPerSec = OFMenuOptionsModemUnlimited.Tag div 10 then
- OFMenuOptionsModemCable512.Checked := true
- else
- OFMenuOptionsModemUnlimited.Checked := true;
- end;
- {****************************************************************************}
- procedure TMainForm.OFMenuOptionsModemXClick(Sender: TObject);
- begin
- IFBytesPerSec := TMenuItem (Sender).Tag div 10;
- end;
- {****************************************************************************}
- procedure TMainForm.MNGerror;
- var iErrorcode : mng_uint32;
- iSeverity : mng_uint8;
- iChunkname : mng_chunkid;
- iChunkseq : mng_uint32;
- iExtra1 : mng_int32;
- iExtra2 : mng_int32;
- zErrortext : mng_pchar;
- begin { get extended info }
- iErrorcode := mng_getlasterror (IFHandle, iSeverity, iChunkname, iChunkseq,
- iExtra1, iExtra2, zErrortext);
- MessageDlg (SHMsg + #13#10#13#10 + strpas (zErrortext) + #13#10#13#10 +
- Format ('Error = %d; Severity = %d; Chunknr = %d; Extra1 = %d',
- [iErrorcode, iSeverity, iChunkseq, iExtra1]),
- mtError, [mbOK], 0);
- end;
- {****************************************************************************}
- end.
|