exceptdlg.delphi32.pas
来自「最新版 JCL+JVCL控件!非常不错的控件资源。包含了所能用到的大部分功能!」· PAS 代码 · 共 729 行 · 第 1/2 页
PAS
729 行
if sse in CpuInfo.SSE then
ProcessorDetails := ProcessorDetails + ' SSE';
if sse2 in CpuInfo.SSE then
ProcessorDetails := ProcessorDetails + ' SSE2';
if sse3 in CpuInfo.SSE then
ProcessorDetails := ProcessorDetails + ' SSE3';
if ssse3 in CpuInfo.SSE then
ProcessorDetails := ProcessorDetails + ' SSSE3';
if sse4A in CpuInfo.SSE then
ProcessorDetails := ProcessorDetails + ' SSE4A';
if sse4B in CpuInfo.SSE then
ProcessorDetails := ProcessorDetails + ' SSE4B';
if sse5 in CpuInfo.SSE then
ProcessorDetails := ProcessorDetails + ' SSE';
if CpuInfo.Ex3DNow then
ProcessorDetails := ProcessorDetails + ' 3DNow!ex';
if CpuInfo._3DNow then
ProcessorDetails := ProcessorDetails + ' 3DNow!';
if CpuInfo.Is64Bits then
ProcessorDetails := ProcessorDetails + ' 64 bits';
if CpuInfo.DEPCapable then
ProcessorDetails := ProcessorDetails + ' DEP';
DetailsMemo.Lines.Add(ProcessorDetails);
DetailsMemo.Lines.Add(Format(RsMemory, [GetTotalPhysicalMemory div 1024 div 1024,
GetFreePhysicalMemory div 1024 div 1024]));
DetailsMemo.Lines.Add(Format(RsScreenRes, [Screen.Width, Screen.Height, GetBPP]));
NextDetailBlock;
%endif
%if ModuleList // Modules list
if LoadedModulesList(SL, GetCurrentProcessId) then
begin
DetailsMemo.Lines.Add(RsModulesList);
SL.CustomSort(SortModulesListByAddressCompare);
for I := 0 to SL.Count - 1 do
begin
ModuleName := SL[I];
ModuleBase := Cardinal(SL.Objects[I]);
DetailsMemo.Lines.Add(Format('[%.8x] %s', [ModuleBase, ModuleName]));
PETarget := PeMapImgTarget(Pointer(ModuleBase));
NtHeaders32 := nil;
NtHeaders64 := nil;
if PETarget = taWin32 then
NtHeaders32 := PeMapImgNtHeaders32(Pointer(ModuleBase))
else
if PETarget = taWin64 then
NtHeaders64 := PeMapImgNtHeaders64(Pointer(ModuleBase));
if (NtHeaders32 <> nil) and (NtHeaders32^.OptionalHeader.ImageBase <> ModuleBase) then
ImageBaseStr := Format('<%.8x> ', [NtHeaders32^.OptionalHeader.ImageBase])
else
if (NtHeaders64 <> nil) and (NtHeaders64^.OptionalHeader.ImageBase <> ModuleBase) then
ImageBaseStr := Format('<%.8x> ', [NtHeaders64^.OptionalHeader.ImageBase])
else
ImageBaseStr := StrRepeat(' ', 11);
if VersionResourceAvailable(ModuleName) then
with TJclFileVersionInfo.Create(ModuleName) do
try
DetailsMemo.Lines.Add(ImageBaseStr + BinFileVersion + ' - ' + FileVersion);
if FileDescription <> '' then
DetailsMemo.Lines.Add(StrRepeat(' ', 11) + FileDescription);
finally
Free;
end
else
DetailsMemo.Lines.Add(ImageBaseStr + RsMissingVersionInfo);
end;
NextDetailBlock;
end;
%endif
%if ActiveControls // Active controls
if (FLastActiveControl <> nil) then
begin
DetailsMemo.Lines.Add(RsActiveControl);
C := FLastActiveControl;
while C <> nil do
begin
DetailsMemo.Lines.Add(Format('%s "%s"', [C.ClassName, C.Name]));
C := C.Parent;
end;
NextDetailBlock;
end;
%endif
finally
SL.Free;
end;
end;
//--------------------------------------------------------------------------------------------------
procedure T%FORMNAME%.DetailsBtnClick(Sender: TObject);
begin
DetailsVisible := not DetailsVisible;
end;
//--------------------------------------------------------------------------------------------------
class procedure T%FORMNAME%.ExceptionHandler(Sender: TObject; E: Exception);
begin
if Assigned(E) then
if ExceptionShowing then
Application.ShowException(E)
else
begin
ExceptionShowing := True;
try
if IsIgnoredException(E.ClassType) then
Application.ShowException(E)
else
ShowException(E, nil);
finally
ExceptionShowing := False;
end;
end;
end;
//--------------------------------------------------------------------------------------------------
class procedure T%FORMNAME%.ExceptionThreadHandler(Thread: TJclDebugThread);
var
E: Exception;
begin
E := Exception(Thread.SyncException);
if Assigned(E) then
if ExceptionShowing then
Application.ShowException(E)
else
begin
ExceptionShowing := True;
try
if IsIgnoredException(E.ClassType) then
Application.ShowException(E)
else
ShowException(E, Thread);
finally
ExceptionShowing := False;
end;
end;
end;
//--------------------------------------------------------------------------------------------------
procedure T%FORMNAME%.FormCreate(Sender: TObject);
begin
%if LogFile FSimpleLog := TJclSimpleLog.Create(%StrValue LogFileName);%endif
FFullHeight := ClientHeight;
DetailsVisible := False;
Caption := Format(RsAppError, [Application.Title]);
end;
//--------------------------------------------------------------------------------------------------
procedure T%FORMNAME%.FormDestroy(Sender: TObject);
begin
%if LogFile FreeAndNil(FSimpleLog);%endif
end;
//--------------------------------------------------------------------------------------------------
procedure T%FORMNAME%.FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
begin
if (Key = Ord('C')) and (ssCtrl in Shift) then
begin
CopyReportToClipboard;
MessageBeep(MB_OK);
end;
end;
//--------------------------------------------------------------------------------------------------
procedure T%FORMNAME%.FormPaint(Sender: TObject);
begin
DrawIcon(Canvas.Handle, TextLabel.Left - GetSystemMetrics(SM_CXICON) - 15,
TextLabel.Top, LoadIcon(0, IDI_ERROR));
end;
//--------------------------------------------------------------------------------------------------
procedure T%FORMNAME%.FormResize(Sender: TObject);
begin
UpdateTextLabelScrollbars;
end;
//--------------------------------------------------------------------------------------------------
procedure T%FORMNAME%.FormShow(Sender: TObject);
begin
BeforeCreateDetails;
MessageBeep(MB_ICONERROR);
if (GetCurrentThreadId = MainThreadID) and (GetWindowThreadProcessId(Handle, nil) = MainThreadID) then
PostMessage(Handle, UM_CREATEDETAILS, 0, 0)
else
CreateReport;
end;
//--------------------------------------------------------------------------------------------------
function T%FORMNAME%.GetReportAsText: string;
begin
Result := StrEnsureSuffix(AnsiCrLf, TextLabel.Text) + AnsiCrLf + DetailsMemo.Text;
end;
//--------------------------------------------------------------------------------------------------
procedure T%FORMNAME%.NextDetailBlock;
begin
DetailsMemo.Lines.Add(StrRepeat(ReportNewBlockDelimiterChar, ReportMaxColumns));
end;
//--------------------------------------------------------------------------------------------------
function T%FORMNAME%.ReportNewBlockDelimiterChar: Char;
begin
Result := '-';
end;
%if LogFile//--------------------------------------------------------------------------------------------------
procedure T%FORMNAME%.ReportToLog;
begin
FSimpleLog.WriteStamp(ReportMaxColumns);
try
FSimpleLog.Write(ReportAsText);
finally
FSimpleLog.CloseLog;
end;
end;
%endif
//--------------------------------------------------------------------------------------------------
procedure T%FORMNAME%.SetDetailsVisible(const Value: Boolean);
var
DetailsCaption: string;
begin
FDetailsVisible := Value;
DetailsCaption := Trim(StrRemoveChars(DetailsBtn.Caption, ['<', '>']));
if Value then
begin
Constraints.MinHeight := FNonDetailsHeight + 100;
Constraints.MaxHeight := Screen.Height;
DetailsCaption := '<< ' + DetailsCaption;
ClientHeight := FFullHeight;
DetailsMemo.Height := FFullHeight - DetailsMemo.Top - 3;
end
else
begin
FFullHeight := ClientHeight;
DetailsCaption := DetailsCaption + ' >>';
if FNonDetailsHeight = 0 then
begin
ClientHeight := BevelDetails.Top;
FNonDetailsHeight := Height;
end
else
Height := FNonDetailsHeight;
Constraints.MinHeight := FNonDetailsHeight;
Constraints.MaxHeight := FNonDetailsHeight
end;
DetailsBtn.Caption := DetailsCaption;
DetailsMemo.Enabled := Value;
end;
//--------------------------------------------------------------------------------------------------
class procedure T%FORMNAME%.ShowException(E: TObject; Thread: TJclDebugThread);
begin
if %FORMNAME% = nil then
%FORMNAME% := %FORMNAME%Class.Create(Application);
try
with %FORMNAME% do
begin
if Assigned(Thread) then
FThreadID := Thread.ThreadID
else
FThreadID := MainThreadID;
%if ActiveControls FLastActiveControl := Screen.ActiveControl;%endif
if E is Exception then
TextLabel.Text := AdjustLineBreaks(StrEnsureSuffix('.', Exception(E).Message))
else
TextLabel.Text := AdjustLineBreaks(StrEnsureSuffix('.', E.ClassName));
UpdateTextLabelScrollbars;
DetailsMemo.Lines.Add(Format(RsExceptionClass, [E.ClassName]));
if E is Exception then
DetailsMemo.Lines.Add(Format(RsExceptionMessage, [StrEnsureSuffix('.', Exception(E).Message)]));
if Thread = nil then
DetailsMemo.Lines.Add(Format(RsExceptionAddr, [ExceptAddr]))
else
DetailsMemo.Lines.Add(Format(RsThread, [Thread.ThreadInfo]));
NextDetailBlock;
ShowModal;
end;
finally
FreeAndNil(%FORMNAME%);
end;
end;
//--------------------------------------------------------------------------------------------------
procedure T%FORMNAME%.UMCreateDetails(var Message: TMessage);
begin
Update;
CreateDetails;
end;
//--------------------------------------------------------------------------------------------------
procedure T%FORMNAME%.UpdateTextLabelScrollbars;
begin
%if AutoScrollBars Canvas.Font := TextLabel.Font;
if TextLabel.Lines.Count * Canvas.TextHeight('Wg') > TextLabel.ClientHeight then
TextLabel.ScrollBars := ssVertical
else
TextLabel.ScrollBars := ssNone;%endif
end;
//==================================================================================================
// Exception handler initialization code
//==================================================================================================
var
AppEvents: TApplicationEvents = nil;
procedure InitializeHandler;
begin
if AppEvents = nil then
begin
AppEvents := TApplicationEvents.Create(nil);
AppEvents.OnException := T%FORMNAME%.ExceptionHandler;
%repeatline IgnoredExceptionsCount AddIgnoredException(%IgnoredExceptions);
%if TraceEAbort RemoveIgnoredException(EAbort);%endif
%if TraceAllExceptions JclStackTrackingOptions := JclStackTrackingOptions + [stTraceAllExceptions];%endif
%if RawData JclStackTrackingOptions := JclStackTrackingOptions + [stRawMode];%endif
%if HookDll JclStackTrackingOptions := JclStackTrackingOptions + [stStaticModuleList];%endif
%if DelayedTrace JclStackTrackingOptions := JclStackTrackingOptions + [stDelayedTrace];%endif
JclDebugThreadList.OnSyncException := T%FORMNAME%.ExceptionThreadHandler;
JclStartExceptionTracking;
%if HookDll if HookTApplicationHandleException then
JclTrackExceptionsFromLibraries;%endif
end;
end;
//--------------------------------------------------------------------------------------------------
procedure UnInitializeHandler;
begin
if AppEvents <> nil then
begin
FreeAndNil(AppEvents);
JclDebugThreadList.OnSyncException := nil;
JclUnhookExceptions;
JclStopExceptionTracking;
end;
end;
//--------------------------------------------------------------------------------------------------
initialization
InitializeHandler;
finalization
UnInitializeHandler;
end.
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?