123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555 |
- unit Main;
- interface
- uses
- Qt, QExtCtrls, QDialogs, QMenus, QTypes, QGraphics, QControls, QForms,
- SysUtils, Classes, QStdCtrls, IdGlobal,
- 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 : 1.0.5 - 09/21/2002 - G.Juyn *}
- {* - modified for Kylix use *}
- {* *}
- {****************************************************************************}
- type
- TMainForm = class(TForm)
- OFMainMenu: TMainMenu;
- OFMenuFile: TMenuItem;
- OFMenuFileOpen: TMenuItem;
- OFMenuFileN1: TMenuItem;
- OFMenuFileExit: TMenuItem;
- OFTimer: TTimer;
- OFOpenDialog: TOpenDialog;
- OFPanel: TPanel;
- 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 OFMenuFileExitClick(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 }
- procedure MNGerror (SHMsg : string);
- public
- { Public declarations }
- end;
- var
- MainForm: TMainForm;
- {****************************************************************************}
- implementation
- {$R *.dfm}
- {****************************************************************************}
- {$F+}
- function Memalloc (iLen : mng_uint32) : mng_ptr; cdecl;
- {$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); cdecl;
- {$F-}
- begin
- freemem (iPtr, iLen); { free the memory }
- end;
- {****************************************************************************}
- {$F+}
- function Openstream (hHandle : mng_handle) : mng_bool; cdecl;
- {$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; cdecl;
- {$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; cdecl;
- {$F-}
- var OHForm : TMainForm;
- 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
- { read the requested data }
- pRead := OFFile.Read (pBuf^, iBuflen);
- end;
- end;
- Result := MNG_TRUE;
- end;
- {****************************************************************************}
- {$F+}
- function ProcessHeader (hHandle : mng_handle;
- iWidth : mng_uint32;
- iHeight : mng_uint32) : mng_bool; cdecl;
- {$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;
- OFBitmap.PixelFormat := pf32bit;
- 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);
- 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; cdecl;
- {$F-}
- var OHForm : TMainForm;
- begin { get a fix on our form }
- OHForm := TMainForm (mng_get_userdata (hHandle));
- { easy with these bitmap objects ! }
- Result := TBitmap(OHForm.OFImage.Picture.Graphic).ScanLine [iLinenr];
- end;
- {****************************************************************************}
- {$F+}
- function ImageRefresh (hHandle : mng_handle;
- iX : mng_uint32;
- iY : mng_uint32;
- iWidth : mng_uint32;
- iHeight : mng_uint32) : mng_bool; cdecl;
- {$F-}
- var OHForm : TMainForm;
- begin { get a fix on our form }
- OHForm := TMainForm (mng_get_userdata (hHandle));
- { force redraw }
- OHForm.OFImage.Refresh;
- Result := MNG_TRUE;
- end;
- {****************************************************************************}
- {$F+}
- function MyGetTickCount (hHandle : mng_handle) : mng_uint32; cdecl;
- {$F-}
- begin
- Result := GetTickCount; { the system knows that }
- end;
- {****************************************************************************}
- {$F+}
- function SetTimer (hHandle : mng_handle;
- iMsecs : mng_uint32) : mng_bool; cdecl;
- {$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;
- BFHasMouse := false;
- OFFile := nil;
- OFOpenDialog.Initialdir := '';
- { 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');
- Application.Terminate;
- 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, MyGetTickCount ) <> 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');
- Application.Terminate;
- 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
- BFCancelled := true;
- if OFTimer.Enabled then { if we're still animating then stop it }
- begin
- OFTimer.Enabled := false;
- Application.ProcessMessages;
- if mng_reset (IFHandle) <> MNG_NOERROR then
- MNGerror ('libmng reported an error during reset!');
- end;
- 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 = Key_Escape then { pressing <esc> will freeze an animation }
- begin
- if OFTimer.Enabled then
- if mng_display_freeze (IFHandle) <> MNG_NOERROR then
- MNGerror ('libmng reported an error during display_freeze!');
- OFTimer.Enabled := false; { don't let that timer go off then ! }
- BFCancelled := true;
- 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_reset (IFHandle) <> MNG_NOERROR then
- MNGerror ('libmng reported an error during reset!');
- end;
- { save interesting fields }
- SFFileName := OFOpenDialog.FileName;
- BFCancelled := false;
-
- OFImage.Picture.Graphic := nil; { clear the output-canvas }
- OFImage.Refresh;
- { 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.OFMenuFileExitClick(Sender: TObject);
- begin
- if mng_cleanup (IFHandle) <> MNG_NOERROR then
- MNGerror ('libmng cleanup error');
- Close;
- 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);
- Application.Terminate;
- end;
- {****************************************************************************}
- end.
|