Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 27.12.2010, 19:55   #1
Alter
Старожил
 
Аватар для Alter
 
Регистрация: 06.08.2007
Сообщений: 2,183
Злость Возврат значения из класса TThread

Есть простой класс на основе TThread. В примере должен вернуть строку.
Прототип http://www.interface.ru/home.asp?artId=23280
Код:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  Pstring = ^string;

type TMyThread = class(TThread)
  private
   FTxt :string;
  protected
   procedure Execute; override;
  public
    constructor Create(Txt :Pstring; CreatePaused :Boolean=True);
    destructor Destroy; override;
  published

end;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Edit1: TEdit;
    procedure Button1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
   MyThr :TMyThread;
   FEndThr :Boolean;
   procedure ThrTerminate(Sender :TObject);
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

{ TMyThread }

constructor TMyThread.Create(Txt: Pstring; CreatePaused: Boolean);
begin
 inherited Create(CreatePaused);
 Priority := tpNormal;
 FreeOnTerminate := True;
 Pointer(FTxt) := Txt;
end;

destructor TMyThread.Destroy;
begin
 inherited Destroy;
end;

procedure TMyThread.Execute;
begin
  try
 FTxt := 'Какой-то текст';
  finally
// Pointer(FTxt) := Nil;
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  Buf :Pstring;
begin
 Edit1.Text := '';
  //
 New(Buf);
 MyThr := TMyThread.Create(Buf, True);
  try
    try
 FEndThr := False; // запущенно
 MyThr.OnTerminate := ThrTerminate;
 MyThr.Resume;
// MyThr.WaitFor;
 while FEndThr = False do
  Application.ProcessMessages();
  //
 Edit1.Text := Buf^;
 ShowMessage('Завершенно');
    except
 Edit1.Text := 'Непредвиденная ошибка';
    end;
  finally
 Dispose(Buf);
 FEndThr := True;
  end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
 FEndThr := True;
end;

procedure TForm1.ThrTerminate(Sender: TObject);
begin
 FEndThr := True;
end;

end.
Замучался, несколько дней "это" пытало меня. Уже и не знаю что тут не так, при закрытии приложения AV, если был ранее запущен поток.
Вложения
Тип файла: rar Test.rar (8.4 Кб, 8 просмотров)
Alter вне форума Ответить с цитированием
Старый 27.12.2010, 21:48   #2
GunSmoker
Старожил
 
Регистрация: 13.08.2009
Сообщений: 2,581
По умолчанию

PString? OMFG!

Читаем мат-часть.

Код:
type
  TMyThread = class(TThread)
  private
    FTxt: string;
  protected
    procedure Execute; override;
  public
    constructor Create(const ATerminateHandler: TNotifyEvent = nil);
    property StrResult: String read FTxt;
  end;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Edit1: TEdit;
    procedure Button1Click(Sender: TObject);
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

{ TMyThread }

constructor TMyThread.Create(const ATerminateHandler: TNotifyEvent);
begin
  inherited Create(False);

  Priority := tpNormal;
  FreeOnTerminate := False;
  OnTerminate := ATerminateHandler;
end;

procedure TMyThread.Execute;
begin
  FTxt := 'Какой-то текст';
  Sleep(1000);
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  MyThr: TMyThread;
begin
  Edit1.Text := '';

  MyThr := TMyThread.Create;
  try
    MyThr.WaitFor;

    Edit1.Text := MyThr.StrResult;
  finally
    FreeAndNil(MyThr);
  end;

  ShowMessage('Завершенно');
end;
Или:

Код:
type
  TMyThread = class(TThread)
  private
    FTxt: string;
  protected
    procedure Execute; override;
  public
    constructor Create(const ATerminateHandler: TNotifyEvent = nil);
    property StrResult: String read FTxt;
  end;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Edit1: TEdit;
    procedure Button1Click(Sender: TObject);
  private
    procedure NotifyMainThread(Sender: TObject);
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

{ TMyThread }

constructor TMyThread.Create(const ATerminateHandler: TNotifyEvent);
begin
  inherited Create(False);

  Priority := tpNormal;
  FreeOnTerminate := False;
  OnTerminate := ATerminateHandler;
end;

procedure TMyThread.Execute;
begin
  try
    FTxt := 'Какой-то текст';
    Sleep(1000);
  finally
    Terminate;
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  MyThr: TMyThread;
begin
  Edit1.Text := '';

  MyThr := TMyThread.Create(NotifyMainThread);
  try
    while not MyThr.Terminated do
      Application.HandleMessage;

    Edit1.Text := MyThr.StrResult;
  finally
    FreeAndNil(MyThr);
  end;

  ShowMessage('Завершенно');
end;

procedure TForm1.NotifyMainThread(Sender: TObject);
begin
  SendMessage(Handle, WM_NULL, 0, 0);
end;
Опытный программист на C++ легко решает любые не существующие в Паскале проблемы.
GunSmoker вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
вектор как закрытый член класса, как изменять его значения? Zhigool' Общие вопросы C/C++ 3 08.08.2010 23:19
Массиву класса не присваивается значения локального массива MoroZzz45 Общие вопросы C/C++ 7 06.06.2010 14:42
Возврат класса kedbl4 Общие вопросы C/C++ 2 10.09.2009 01:31
Метод Synchronize класса TThread EdNovice Общие вопросы Delphi 10 01.08.2009 14:47
Возврат значения функции по ссылке(подскажите новичку) Malkovich Общие вопросы C/C++ 11 14.07.2009 08:48