📄 threadexceptdemomain.pas
字号:
unit ThreadExceptDemoMain;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ComCtrls, JclDebug;
type
TDemoThread = class(TJclDebugThread)
private
procedure SomeErrorHere;
protected
procedure Execute; override;
end;
TMainForm = class(TForm)
MessageRichEdit: TRichEdit;
ThreadsRichEdit: TRichEdit;
CreateThreadBtn: TButton;
ThreadNameEdit: TEdit;
ListThreadsBtn: TButton;
Label1: TLabel;
Label2: TLabel;
procedure FormCreate(Sender: TObject);
procedure CreateThreadBtnClick(Sender: TObject);
procedure ListThreadsBtnClick(Sender: TObject);
private
procedure DoThreadSyncException(Thread: TJclDebugThread);
procedure DoThreadRegistered(ThreadID: DWORD);
procedure DoThreadUnregistered(ThreadID: DWORD);
public
ThreadCnt: Integer;
function GetNewThreadName: string;
procedure ScrollDownRichEdit(RichEdit: TRichEdit);
end;
var
MainForm: TMainForm;
implementation
{$R *.dfm}
{ !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! }
{ }
{ You have to install ThreadNameExpert package located in "\experts\debug\threadnames" }
{ }
{ !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! }
{$DEFINE IdeThreadStatusWindowExtension}
{$IFDEF IdeThreadStatusWindowExtension}
uses
JclIdeThreadStatus;
{$ENDIF}
{ TDemoThread }
procedure TDemoThread.Execute;
var
I: Integer;
begin
try
I := 0;
while not Terminated and (I < 5) do
begin
Sleep(2000);
MessageBeep(0);
try
SomeErrorHere;
except
HandleException;
end;
Inc(I);
{$IFDEF IdeThreadStatusWindowExtension}
// You can change Thread Name displayed in Thread Status Window in code. This does not change
// TDemoThread.ThreadName property value
// ChangeThreadName(Self, Format('I = %d', [I]));
{$ENDIF}
end;
except
HandleException;
end;
end;
procedure TDemoThread.SomeErrorHere;
begin
// Set Breakpoint on "begin", uncheck "Break" and check "Ingore subsequent exceptions" in
// dialog advanced breakpoint actions
StrToInt('x');
end;
{ TMainForm }
procedure TMainForm.DoThreadRegistered(ThreadID: DWORD);
begin
ThreadsRichEdit.Lines.Add(Format('Thread registered: %s', [JclDebugThreadList.ThreadInfos[ThreadID]]));
ScrollDownRichEdit(ThreadsRichEdit);
end;
procedure TMainForm.DoThreadSyncException(Thread: TJclDebugThread);
begin
MessageRichEdit.Lines.Add(Format('Exception in thread: %s', [Thread.ThreadInfo]));
// Note: JclLastExceptStackList always returns list for *current* thread ID. To simplify getting the
// stack of thread where an exception occured JclLastExceptStackList returns stack of the thread instead
// of current thread when called *within* the JclDebugThreadList.OnSyncException handler. This is the
// *only* exception to the behavior of JclLastExceptStackList described above.
JclLastExceptStackList.AddToStrings(MessageRichEdit.Lines, False, True, True);
ScrollDownRichEdit(MessageRichEdit);
end;
procedure TMainForm.DoThreadUnregistered(ThreadID: DWORD);
begin
ThreadsRichEdit.Lines.Add(Format('Thread unregistered: %s', [JclDebugThreadList.ThreadInfos[ThreadID]]));
ScrollDownRichEdit(ThreadsRichEdit);
end;
procedure TMainForm.FormCreate(Sender: TObject);
begin
with JclDebugThreadList do
begin
OnSyncException := DoThreadSyncException;
OnThreadRegistered := DoThreadRegistered;
OnThreadUnregistered := DoThreadUnregistered;
end;
ThreadNameEdit.Text := GetNewThreadName;
end;
function TMainForm.GetNewThreadName: string;
begin
Inc(ThreadCnt);
Result := Format('Thread%d', [ThreadCnt]);
end;
procedure TMainForm.CreateThreadBtnClick(Sender: TObject);
var
DemoThread: TDemoThread;
begin
DemoThread := TDemoThread.Create(True, ThreadNameEdit.Text);
DemoThread.FreeOnTerminate := True;
DemoThread.Resume;
ThreadNameEdit.Text := GetNewThreadName;
end;
procedure TMainForm.ListThreadsBtnClick(Sender: TObject);
var
I: Integer;
begin
ThreadsRichEdit.Lines.Add('List of registered threads:');
with JclDebugThreadList do
for I := 0 to ThreadIDCount - 1 do
ThreadsRichEdit.Lines.Add(ThreadInfos[ThreadIDs[I]]);
ScrollDownRichEdit(ThreadsRichEdit);
end;
procedure TMainForm.ScrollDownRichEdit(RichEdit: TRichEdit);
begin
SendMessage(RichEdit.Handle, EM_SCROLLCARET, 0, 0);
end;
initialization
Include(JclStackTrackingOptions, stRawMode);
JclStartExceptionTracking;
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -