411 lines
13 KiB
ObjectPascal
411 lines
13 KiB
ObjectPascal
|
|
{-----------------------------------------------------------------------------
|
|||
|
|
The contents of this file are subject to the Mozilla Public License
|
|||
|
|
Version 1.1 (the "License"); you may not use this file except in compliance
|
|||
|
|
with the License. You may obtain a copy of the License at
|
|||
|
|
http://www.mozilla.org/MPL/MPL-1.1.html
|
|||
|
|
|
|||
|
|
Software distributed under the License is distributed on an "AS IS" basis,
|
|||
|
|
WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See the License for
|
|||
|
|
the specific language governing rights and limitations under the License.
|
|||
|
|
|
|||
|
|
The Original Code is: JvgExceptionHandler.PAS, released on 2003-01-15.
|
|||
|
|
|
|||
|
|
The Initial Developer of the Original Code is Andrey V. Chudin, [chudin att yandex dott ru]
|
|||
|
|
Portions created by Andrey V. Chudin are Copyright (C) 2003 Andrey V. Chudin.
|
|||
|
|
All Rights Reserved.
|
|||
|
|
|
|||
|
|
Contributor(s):
|
|||
|
|
Michael Beck [mbeck att bigfoot dott com].
|
|||
|
|
Burov Dmitry, translation of russian text.
|
|||
|
|
|
|||
|
|
You may retrieve the latest version of this file at the Project JEDI's JVCL home page,
|
|||
|
|
located at http://jvcl.sourceforge.net
|
|||
|
|
|
|||
|
|
Known Issues:
|
|||
|
|
-----------------------------------------------------------------------------}
|
|||
|
|
// $Id: JvgExceptionHandler.pas,v 1.22 2005/09/15 07:22:55 marquardt Exp $
|
|||
|
|
|
|||
|
|
unit JvgExceptionHandler;
|
|||
|
|
|
|||
|
|
{$I jvcl.inc}
|
|||
|
|
{$I windowsonly.inc}
|
|||
|
|
|
|||
|
|
interface
|
|||
|
|
|
|||
|
|
uses
|
|||
|
|
{$IFDEF USEJVCL}
|
|||
|
|
{$IFDEF UNITVERSIONING}
|
|||
|
|
JclUnitVersioning,
|
|||
|
|
{$ENDIF UNITVERSIONING}
|
|||
|
|
{$ENDIF USEJVCL}
|
|||
|
|
Windows, Messages, SysUtils, Classes, Graphics, Controls,
|
|||
|
|
Forms, Dialogs, jpeg,
|
|||
|
|
{$IFDEF USEJVCL}
|
|||
|
|
JvTypes, JvComponentBase,
|
|||
|
|
{$ENDIF USEJVCL}
|
|||
|
|
JvgMailSlots;
|
|||
|
|
|
|||
|
|
type
|
|||
|
|
TExceptionHandlerOption = (fehActiveDesignTime, fehActiveRunTime,
|
|||
|
|
fehFileLogging, fehSupressExceptions, feScreenShots);
|
|||
|
|
TExceptionHandlerOptions = set of TExceptionHandlerOption;
|
|||
|
|
|
|||
|
|
{$IFDEF USEJVCL}
|
|||
|
|
EJvgHandlerException = class(EJVCLException);
|
|||
|
|
{$ELSE}
|
|||
|
|
EJvgHandlerException = class(Exception);
|
|||
|
|
{$ENDIF USEJVCL}
|
|||
|
|
|
|||
|
|
{$IFDEF USEJVCL}
|
|||
|
|
TJvgExceptionHandler = class(TJvComponent)
|
|||
|
|
{$ELSE}
|
|||
|
|
TJvgExceptionHandler = class(TComponent)
|
|||
|
|
{$ENDIF USEJVCL}
|
|||
|
|
private
|
|||
|
|
FActive: Boolean;
|
|||
|
|
FLogFileName: string;
|
|||
|
|
FEMail: string;
|
|||
|
|
FMailSlot: TJvgMailSlotClient;
|
|||
|
|
FOptions: TExceptionHandlerOptions;
|
|||
|
|
FScreenShotList: TList;
|
|||
|
|
procedure MakeScreenShot(const ID: string);
|
|||
|
|
procedure ShowMessage(E: Exception; const Msg: string);
|
|||
|
|
protected
|
|||
|
|
procedure OnException(Sender: TObject; E: Exception); virtual;
|
|||
|
|
procedure Loaded; override;
|
|||
|
|
procedure Notification(AComponent: TComponent; Operation: TOperation); override;
|
|||
|
|
public
|
|||
|
|
constructor Create(AOwner: TComponent); override;
|
|||
|
|
destructor Destroy; override;
|
|||
|
|
procedure Refresh;
|
|||
|
|
procedure ProcessMessage(const ExceptionMessage, Msg, ID: string);
|
|||
|
|
procedure Log_(const ID: string); overload;
|
|||
|
|
procedure Log_(E: Exception); overload;
|
|||
|
|
procedure Log_(E: Exception; const ID: string); overload;
|
|||
|
|
procedure Raise_(const ID: string); overload;
|
|||
|
|
procedure Raise_(E: Exception); overload;
|
|||
|
|
procedure Raise_(E: Exception; const ID: string); overload;
|
|||
|
|
procedure Raise_(E: Exception; const Msg, ID: string); overload;
|
|||
|
|
procedure RaiseMessage(const Msg: string);
|
|||
|
|
published
|
|||
|
|
property Active: Boolean read FActive write FActive default True;
|
|||
|
|
property EMail: string read FEMail write FEMail;
|
|||
|
|
property LogFileName: string read FLogFileName write FLogFileName;
|
|||
|
|
property MailSlot: TJvgMailSlotClient read FMailSlot write FMailSlot;
|
|||
|
|
property Options: TExceptionHandlerOptions read FOptions write FOptions
|
|||
|
|
default [fehActiveRunTime, fehFileLogging];
|
|||
|
|
end;
|
|||
|
|
|
|||
|
|
{$IFDEF USEJVCL}
|
|||
|
|
{$IFDEF UNITVERSIONING}
|
|||
|
|
const
|
|||
|
|
UnitVersioning: TUnitVersionInfo = (
|
|||
|
|
RCSfile: '$RCSfile: JvgExceptionHandler.pas,v $';
|
|||
|
|
Revision: '$Revision: 1.22 $';
|
|||
|
|
Date: '$Date: 2005/09/15 07:22:55 $';
|
|||
|
|
LogPath: 'JVCL\run'
|
|||
|
|
);
|
|||
|
|
{$ENDIF UNITVERSIONING}
|
|||
|
|
{$ENDIF USEJVCL}
|
|||
|
|
|
|||
|
|
implementation
|
|||
|
|
|
|||
|
|
uses
|
|||
|
|
FileCtrl,
|
|||
|
|
JclSysInfo,
|
|||
|
|
{$IFDEF USEJVCL}
|
|||
|
|
JvConsts,
|
|||
|
|
{$ENDIF USEJVCL}
|
|||
|
|
JvgUtils;
|
|||
|
|
|
|||
|
|
var
|
|||
|
|
ExceptionHandler: TJvgExceptionHandler = nil;
|
|||
|
|
|
|||
|
|
procedure AssertErrorHandler_gl(const Msg, FileName: string;
|
|||
|
|
LineNumber: Integer; ErrorAddr: Pointer);
|
|||
|
|
begin
|
|||
|
|
if Assigned(ExceptionHandler) then
|
|||
|
|
ExceptionHandler.ProcessMessage(
|
|||
|
|
'ExceptAddr=' + Format('%p', [ErrorAddr]) + sLineBreak +
|
|||
|
|
'LineNumber=' + IntToStr(LineNumber) + sLineBreak +
|
|||
|
|
'FileName=' + FileName
|
|||
|
|
, 'internal JvgExceptionHandler message', '');
|
|||
|
|
ExceptionClass := EAssertionFailed;
|
|||
|
|
// E := CreateAssertException(Msg, FileName, LineNumber);
|
|||
|
|
// RaiseAssertException(E, ErrorAddr, PChar(@ErrorAddr)+4);
|
|||
|
|
end;
|
|||
|
|
|
|||
|
|
function DeleteFileExt(const FileName: string): string;
|
|||
|
|
begin
|
|||
|
|
Result := ChangeFileExt(Trim(FileName), '');
|
|||
|
|
end;
|
|||
|
|
|
|||
|
|
//=== { TJvgExceptionHandler } ===============================================
|
|||
|
|
|
|||
|
|
constructor TJvgExceptionHandler.Create(AOwner: TComponent);
|
|||
|
|
begin
|
|||
|
|
inherited Create(AOwner);
|
|||
|
|
FActive := True;
|
|||
|
|
FOptions := [fehActiveRunTime, fehFileLogging];
|
|||
|
|
FLogFileName := '_errors_log.txt';
|
|||
|
|
FScreenShotList := TList.Create;
|
|||
|
|
end;
|
|||
|
|
|
|||
|
|
destructor TJvgExceptionHandler.Destroy;
|
|||
|
|
begin
|
|||
|
|
FScreenShotList.Free;
|
|||
|
|
Application.OnException := nil;
|
|||
|
|
inherited Destroy;
|
|||
|
|
end;
|
|||
|
|
|
|||
|
|
procedure TJvgExceptionHandler.OnException(Sender: TObject; E: Exception);
|
|||
|
|
begin
|
|||
|
|
if E is EJvgHandlerException then
|
|||
|
|
Exit;
|
|||
|
|
|
|||
|
|
ProcessMessage(E.Message, '', '');
|
|||
|
|
if not (fehSupressExceptions in Options) then
|
|||
|
|
Application.MessageBox(PChar(E.Message),
|
|||
|
|
PChar('Something has occured - ' + Application.Title),
|
|||
|
|
MB_OK + MB_ICONSTOP);
|
|||
|
|
end;
|
|||
|
|
|
|||
|
|
procedure TJvgExceptionHandler.Loaded;
|
|||
|
|
begin
|
|||
|
|
inherited Loaded;
|
|||
|
|
if Active then
|
|||
|
|
if ((csDesigning in ComponentState) and (fehActiveDesignTime in Options)) or
|
|||
|
|
(not (csDesigning in ComponentState) and (fehActiveRunTime in Options)) then
|
|||
|
|
begin
|
|||
|
|
Application.OnException := OnException;
|
|||
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Assert
|
|||
|
|
{ Setting up link to global Assert handler [translated] }
|
|||
|
|
AssertErrorProc := @AssertErrorHandler_gl;
|
|||
|
|
ExceptionHandler := Self;
|
|||
|
|
end;
|
|||
|
|
end;
|
|||
|
|
|
|||
|
|
procedure TJvgExceptionHandler.ProcessMessage(const ExceptionMessage, Msg, ID: string);
|
|||
|
|
var
|
|||
|
|
fs: TFileStream;
|
|||
|
|
FileName, Mesg: string;
|
|||
|
|
CpuInfo: TCpuInfo;
|
|||
|
|
DC: HDC;
|
|||
|
|
begin
|
|||
|
|
FileName := IIF((Pos('//', LogFileName) = 0) and (Pos(':', LogFileName) = 0),
|
|||
|
|
ExtractFilePath(ParamStr(0)) + LogFileName, LogFileName);
|
|||
|
|
|
|||
|
|
Mesg := '';
|
|||
|
|
try
|
|||
|
|
if not FileExists(FileName) then
|
|||
|
|
// { <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> }
|
|||
|
|
{ 1st creation of log }
|
|||
|
|
try
|
|||
|
|
GetCpuInfo(CpuInfo);
|
|||
|
|
Mesg := '##################### exception log header';
|
|||
|
|
Mesg := Mesg + sLineBreak + 'ExeModule= ' + ParamStr(0);
|
|||
|
|
Mesg := Mesg + sLineBreak + 'OSPlatform= ' + GetWindowsVersionString;
|
|||
|
|
Mesg := Mesg + sLineBreak + 'CPUKind= ' + IntToStr(CpuInfo.Family);
|
|||
|
|
Mesg := Mesg + sLineBreak + 'CPUName= ' + CpuInfo.CpuName;
|
|||
|
|
Mesg := Mesg + sLineBreak + 'TotalPhys= ' + IntToStr(GetTotalPhysicalMemory);
|
|||
|
|
Mesg := Mesg + sLineBreak + 'AvailPhys= ' + IntToStr(GetFreePhysicalMemory);
|
|||
|
|
Mesg := Mesg + sLineBreak + 'TotalPageFile= ' + IntToStr(GetTotalPageFileMemory);
|
|||
|
|
Mesg := Mesg + sLineBreak + 'AvailPageFile= ' + IntToStr(GetFreePageFileMemory);
|
|||
|
|
Mesg := Mesg + sLineBreak + 'TotalVirtual= ' + IntToStr(GetTotalVirtualMemory);
|
|||
|
|
Mesg := Mesg + sLineBreak + 'AvailVirtual= ' + IntToStr(GetFreeVirtualMemory);
|
|||
|
|
DC := GetDC(HWND_DESKTOP);
|
|||
|
|
Mesg := Mesg + sLineBreak + 'ColorDepth= ' + IntToStr(GetDeviceCaps(DC, BITSPIXEL));
|
|||
|
|
if GetDeviceCaps(DC, LOGPIXELSX) = 96 then
|
|||
|
|
Mesg := Mesg + sLineBreak + 'SystemFont=SmallFont'
|
|||
|
|
else
|
|||
|
|
if GetDeviceCaps(DC, LOGPIXELSX) = 120 then
|
|||
|
|
Mesg := Mesg + sLineBreak + 'SystemFont=BigFont';
|
|||
|
|
Mesg := Mesg + sLineBreak + 'VRefreshRate= ' + IntToStr(GetDeviceCaps(DC, VREFRESH));
|
|||
|
|
Mesg := Mesg + sLineBreak + 'GraphicResolution= ' +
|
|||
|
|
Format('%dx%d', [GetDeviceCaps(DC, HORZRES), GetDeviceCaps(DC, VERTRES)]);
|
|||
|
|
Mesg := Mesg + sLineBreak +
|
|||
|
|
'##################### exception log header end' + sLineBreak;
|
|||
|
|
ReleaseDC(HWND_DESKTOP, DC);
|
|||
|
|
except
|
|||
|
|
// { <20><><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> TJvgSysInfo <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> }
|
|||
|
|
{ Handler should not to suffer from errors in TJvgSysInfo's working }
|
|||
|
|
end;
|
|||
|
|
|
|||
|
|
if ExceptObject <> nil then
|
|||
|
|
begin
|
|||
|
|
Mesg := Mesg + sLineBreak + 'Exception class= ' + ExceptObject.ClassName;
|
|||
|
|
Mesg := Mesg + sLineBreak + 'ExceptAddr= ' + Format('%p', [ExceptAddr]);
|
|||
|
|
end;
|
|||
|
|
Mesg := Mesg + sLineBreak + 'Computer= ' + ComputerName;
|
|||
|
|
Mesg := Mesg + sLineBreak + 'User= ' + UserName;
|
|||
|
|
Mesg := Mesg + sLineBreak + 'Datetime= ' + DateToStr(Date) + ' ' +
|
|||
|
|
TimeToStr(Time);
|
|||
|
|
|
|||
|
|
if ID <> '' then
|
|||
|
|
Mesg := Mesg + sLineBreak + 'ID= ' + ID;
|
|||
|
|
if ExceptionMessage <> '' then
|
|||
|
|
Mesg := Mesg + sLineBreak + 'ExceptionMessage= ' + ExceptionMessage;
|
|||
|
|
if Msg <> '' then
|
|||
|
|
Mesg := Mesg + sLineBreak + 'Message= ' + Msg;
|
|||
|
|
Mesg := Mesg + sLineBreak;
|
|||
|
|
|
|||
|
|
if Assigned(MailSlot) then
|
|||
|
|
MailSlot.Send(Mesg);
|
|||
|
|
if (fehFileLogging in Options) and (Trim(LogFileName) <> '') then
|
|||
|
|
begin
|
|||
|
|
if FileExists(FileName) then
|
|||
|
|
fs := TFileStream.Create(FileName, fmOpenReadWrite or fmShareDenyNone)
|
|||
|
|
else
|
|||
|
|
fs := TFileStream.Create(FileName, fmCreate or fmShareDenyNone);
|
|||
|
|
try
|
|||
|
|
fs.Seek(0, soFromEnd);
|
|||
|
|
fs.Write(PChar(Mesg)^, Length(Mesg));
|
|||
|
|
finally
|
|||
|
|
fs.Free;
|
|||
|
|
end;
|
|||
|
|
end;
|
|||
|
|
except
|
|||
|
|
on E: Exception do
|
|||
|
|
ShowMessage(E, 'An error occured while saving the log' + sLineBreak + sLineBreak + E.Message);
|
|||
|
|
end;
|
|||
|
|
|
|||
|
|
if feScreenShots in Options then
|
|||
|
|
MakeScreenShot(ID);
|
|||
|
|
end;
|
|||
|
|
|
|||
|
|
procedure TJvgExceptionHandler.MakeScreenShot(const ID: string);
|
|||
|
|
var
|
|||
|
|
JpegImage: TJpegImage;
|
|||
|
|
BackImage: TBitmap;
|
|||
|
|
LogPath, ScreenShotName: string;
|
|||
|
|
SysTime: TSystemTime;
|
|||
|
|
DC: HDC;
|
|||
|
|
begin
|
|||
|
|
GetLocalTime(SysTime);
|
|||
|
|
|
|||
|
|
if FScreenShotList.IndexOf(ExceptAddr) <> -1 then
|
|||
|
|
Exit; //already done
|
|||
|
|
|
|||
|
|
FScreenShotList.Add(ExceptAddr);
|
|||
|
|
|
|||
|
|
JpegImage := TJpegImage.Create;
|
|||
|
|
BackImage := TBitmap.Create;
|
|||
|
|
try
|
|||
|
|
DC := GetDC(HWND_DESKTOP);
|
|||
|
|
BackImage.Width := Screen.Width;
|
|||
|
|
BackImage.Height := Screen.Height;
|
|||
|
|
BitBlt(BackImage.Canvas.Handle, 0, 0, BackImage.Width, BackImage.Height,
|
|||
|
|
DC, 0, 0, SRCCOPY);
|
|||
|
|
ReleaseDC(HWND_DESKTOP, DC);
|
|||
|
|
JpegImage.CompressionQuality := 50;
|
|||
|
|
JpegImage.Assign(BackImage);
|
|||
|
|
|
|||
|
|
LogPath := ExtractFilePath(ParamStr(0)) +
|
|||
|
|
DeleteFileExt(ExtractFileName(ParamStr(0))) + '\';
|
|||
|
|
ScreenShotName := DeleteFileExt(ExtractFileName(ParamStr(0)) + ' ' +
|
|||
|
|
StringReplace(StringReplace(ID, '{', '', [rfReplaceAll]), '}', '', [rfReplaceAll])) +
|
|||
|
|
Format(' %2d-%2d-%4d %2d-%2d-%2d', [SysTime.wDay, SysTime.wMonth,
|
|||
|
|
SysTime.wYear, SysTime.wHour, SysTime.wMinute, SysTime.wSecond]);
|
|||
|
|
|
|||
|
|
ForceDirectories(LogPath);
|
|||
|
|
|
|||
|
|
JpegImage.SaveToFile(LogPath + ScreenShotName + '.jpg');
|
|||
|
|
finally
|
|||
|
|
JpegImage.Free;
|
|||
|
|
BackImage.Free;
|
|||
|
|
end;
|
|||
|
|
end;
|
|||
|
|
|
|||
|
|
procedure TJvgExceptionHandler.Notification(AComponent: TComponent;
|
|||
|
|
Operation: TOperation);
|
|||
|
|
begin
|
|||
|
|
inherited Notification(AComponent, Operation);
|
|||
|
|
if (AComponent = MailSlot) and (Operation = opRemove) then
|
|||
|
|
FMailSlot := nil;
|
|||
|
|
end;
|
|||
|
|
|
|||
|
|
procedure TJvgExceptionHandler.Raise_(const ID: string);
|
|||
|
|
begin
|
|||
|
|
Log_(ID);
|
|||
|
|
if ID <> '' then
|
|||
|
|
ShowMessage(nil, ID);
|
|||
|
|
raise EJvgHandlerException.Create('');
|
|||
|
|
end;
|
|||
|
|
|
|||
|
|
procedure TJvgExceptionHandler.Raise_(E: Exception);
|
|||
|
|
begin
|
|||
|
|
Log_(E);
|
|||
|
|
if E.Message <> '' then
|
|||
|
|
ShowMessage(E, E.Message);
|
|||
|
|
raise EJvgHandlerException.Create('');
|
|||
|
|
end;
|
|||
|
|
|
|||
|
|
procedure TJvgExceptionHandler.Raise_(E: Exception; const ID: string);
|
|||
|
|
begin
|
|||
|
|
Log_(E, ID);
|
|||
|
|
if E.Message <> '' then
|
|||
|
|
ShowMessage(E, E.Message + sLineBreak + sLineBreak + ID);
|
|||
|
|
raise EJvgHandlerException.Create('');
|
|||
|
|
end;
|
|||
|
|
|
|||
|
|
procedure TJvgExceptionHandler.Raise_(E: Exception; const Msg, ID: string);
|
|||
|
|
begin
|
|||
|
|
ProcessMessage(E.Message, Msg, ID);
|
|||
|
|
ShowMessage(E, Msg);
|
|||
|
|
raise EJvgHandlerException.Create('');
|
|||
|
|
end;
|
|||
|
|
|
|||
|
|
procedure TJvgExceptionHandler.Log_(const ID: string);
|
|||
|
|
begin
|
|||
|
|
ProcessMessage('', '', ID);
|
|||
|
|
end;
|
|||
|
|
|
|||
|
|
procedure TJvgExceptionHandler.Log_(E: Exception);
|
|||
|
|
begin
|
|||
|
|
ProcessMessage(E.Message, '', '');
|
|||
|
|
end;
|
|||
|
|
|
|||
|
|
procedure TJvgExceptionHandler.Log_(E: Exception; const ID: string);
|
|||
|
|
begin
|
|||
|
|
ProcessMessage(E.Message, '', ID);
|
|||
|
|
end;
|
|||
|
|
|
|||
|
|
//{ <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> - EJvgHandlerException }
|
|||
|
|
{ Shows message, if the Exception is not internal one. - EJvgHandlerException }
|
|||
|
|
|
|||
|
|
procedure TJvgExceptionHandler.ShowMessage(E: Exception; const Msg: string);
|
|||
|
|
begin
|
|||
|
|
if not (E is EJvgHandlerException) and not (fehSupressExceptions in Options) then
|
|||
|
|
if Msg <> '' then
|
|||
|
|
Dialogs.ShowMessage(Msg)
|
|||
|
|
else
|
|||
|
|
Application.ShowException(E);
|
|||
|
|
end;
|
|||
|
|
|
|||
|
|
procedure TJvgExceptionHandler.Refresh;
|
|||
|
|
begin
|
|||
|
|
Application.OnException := OnException;
|
|||
|
|
end;
|
|||
|
|
|
|||
|
|
//{ <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> }
|
|||
|
|
{ Fires exception with given message without logging it. }
|
|||
|
|
|
|||
|
|
procedure TJvgExceptionHandler.RaiseMessage(const Msg: string);
|
|||
|
|
begin
|
|||
|
|
Dialogs.ShowMessage(Msg);
|
|||
|
|
raise EJvgHandlerException.Create('');
|
|||
|
|
end;
|
|||
|
|
|
|||
|
|
{$IFDEF USEJVCL}
|
|||
|
|
{$IFDEF UNITVERSIONING}
|
|||
|
|
initialization
|
|||
|
|
RegisterUnitVersion(HInstance, UnitVersioning);
|
|||
|
|
|
|||
|
|
finalization
|
|||
|
|
UnregisterUnitVersion(HInstance);
|
|||
|
|
{$ENDIF UNITVERSIONING}
|
|||
|
|
{$ENDIF USEJVCL}
|
|||
|
|
|
|||
|
|
end.
|
|||
|
|
|