Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is this the correct way to set a thread's name in Delphi 6?

I want to have a nice user friendly name appear in the thread list window while in the Delphi 6 IDE. I found the code below on the web for doing this in Delphi 6 since as far as I know that version does not have SetThreadName() implemented natively. I call it from my thread's Execute() method. I know it's being called because the IDE pops up when the Exception is raised. However, when I look in the thread list (Ctrl + Alt + T), I don't see the name I set. I just see the usual Thread Id, State, Status, and Location columns, nothing else.

What do I need to do differently to get the thread names to appear? Also, does anyone have an idea on how to stop the IDE from pausing on the RaiseException line? I have a lot of threads in the program and it's annoying to have the IDE popping up N times every time I run the program.
I know I can disable the IDE from stopping on Delphi Exceptions, but I want that normally and I'd prefer not to have to toggle that off and on every time a new set of threads is created.

Named threads in Delphi - what is that for?

procedure SetThreadName_delphi(const Name: string);
    type
      TThreadNameInfo =
        record
          RecType: LongWord;
          Name: PChar;
          ThreadID: LongWord;
          Flags: LongWord;
        end;
var
    info:TThreadNameInfo;
begin
    // This code is extremely strange, but it's the documented way of doing it!

    info.RecType := $1000;
    info.Name := PChar(Name);
    info.ThreadID := $FFFFFFFF;
    info.Flags := 0;

    try
        RaiseException($406D1388, 0,
        SizeOf(info) div SizeOf(LongWord), PDWord(@info));
    except
    end;
end;
like image 377
Robert Oschler Avatar asked Feb 01 '12 02:02

Robert Oschler


1 Answers

I have found the original code

It is an application-specific exception (that means it is specific for Visual C++ compiler). I see no reason why Delphi should support this strange feature (though it is possible).


Edit : BUT IT WORKS! (Thanks to Remy Lebeau)

Just tested on Delphi XE (I see 'Wow!' in the debugger 'Thread status' window):

unit NameTest;

interface

uses
  Windows, Classes;

type
  TTestThread = class(TThread)
  private
    { Private declarations }
  protected
    procedure Execute; override;
  end;

implementation

{ TTestThread }

procedure SetThreadName_delphi(const Name: string);
    type
      TThreadNameInfo =
        record
          RecType: LongWord;
          Name: PAnsiChar;
          ThreadID: LongWord;
          Flags: LongWord;
        end;
var
    info:TThreadNameInfo;
    AnsiName: AnsiString;

begin
    AnsiName:= Name;
    info.RecType := $1000;
    info.Name := PAnsiChar(AnsiName);
    info.ThreadID := $FFFFFFFF;
    info.Flags := 0;
    try
        RaiseException($406D1388, 0,
        SizeOf(info) div SizeOf(LongWord), PDWord(@info));
    except
    end;
end;

procedure TTestThread.Execute;
begin
  SetThreadName_delphi('Wow!');
  while not Terminated do
    Sleep(1000);
end;

end.
like image 149
kludg Avatar answered Sep 19 '22 05:09

kludg