RichEdit znika bo modyfikuję jego zawartość w wątku

0

Tworzę dynamicznie komponent RichEdit. Potem tworzę wątek za pomocą konstruktora klasy TThread. W procedurze Execute modyfikuję zawartość tego RichEdita. Po zakończeniu wątku RichEdit znika. Jeśli niczego w nim nie modyfikuję, to nie znika... rozwiązaniem jest dodanie w wyżej wspomnianym konstruktorze linii RichEdit.Lines.Add('cokolwiek'); ale przyznacie chyba, że to dziwne rozwiązanie... może mi ktoś wyjaśnić, o co w tym wszystkim chodzi?

0

Trudno odpowiedzieć tak bez zobaczenia tego co napisałeś. Uchyl rąbka tajemnicy czyli pokaż fragment kodu a może znajdziemy błąd bo faktycznie tak nie powinno być

0

W wątku:

procedure Thread.RichEditChange;
begin
 // Zmiany w RichEdit... 
end;

procedure Thread.Execute;
begin
Synchronize(RichEditChange);
end;

Powinnno działać.

0

A jak tworzysz RichEdita ?

0
constructor TKlasa.Create;
begin
  TabSheet := TTabSheet.Create(Form1);
  TabSheet.PageControl := Form1.PageControl;
  RichEdit := TRichEdit.Create(TabSheet);
  RichEdit.ReadOnly := True;
  RichEdit.Left := 10;
  RichEdit.Top := 219;
  RichEdit.Width := 943;
  RichEdit.Height := 142;
  RichEdit.Parent := TabSheet;
//jeśli wstawiłbym rodzica Form1, to komponent nie zniknie, ale ja chcę żeby 
//rodzicem był TabSheet
  RichEdit.ScrollBars := ssVertical;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  Klasa := TKlasa.Create;
end;

constructor TWatek.Create;
begin
  Klasa.RichEdit.Lines.Add('');
//od powyższej linii zależy, czy RichEdit zniknie czy też nie - nie musi ona 
//znajdować się tutaj, może być gdziekolwiek, byle przed rozpoczęciem wątku
  inherited Create(False);
end;

procedure TWatek.Execute;
begin
    Klasa.RichEdit.Lines.Add('lol');
end;

Wolę już wstawiać linię do RichEdita przed rozpoczęciem wątku, niż użyć Synchronize... ale i tak chciałbym wiedzieć o co chodzi...

0

Cóś strasznie, żeś pomerdał, bo nie mam pojęcia co ma przedstawiać klasa TKlasa (ale chyba TabSheet-a z RichEdit-em) a co klasa TWatek.
I w jaki sposób wywołujesz ten wątek?

ps. jak pisał DETOX używaj Synchronizen tak jak masz napisane w helpie (zabezpiecza przed jednoczesnym dostępem dwóch wątków do kontrolki VCL)

Executes a method call within the main VCL thread.

type TThreadMethod = procedure of object;
procedure Synchronize(Method: TThreadMethod);

Description
Synchronize causes the call specified by Method to be executed using the main VCL thread, thereby avoiding multi-thread conflicts. If you are unsure whether a method call is thread-safe, call it from within the main VCL thread by passing it to the Synchronize method.
Execution of the thread is suspended while Method is executing in the main VCL thread.

Note:You can also protect unsafe methods using critical sections or the multi-read exclusive-write synchronizer.</I>

i przykładzik

procedure TMyThread.PushTheButton;
begin
  Button1.Click();
end;

procedure TMyThread.Execute;
begin
...
  Synchronize(PushTheButton);
  ...
end;
0
unit Unit1;

interface

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

type
  TWatek = class(TThread)
  private
    { Private declarations }
  protected
    procedure Execute; override;
    constructor Create;
  end;
  TKlasa = class
  public
  constructor Create;
  end;
  TForm1 = class(TForm)
    PageControl: TPageControl;
    Button1: TButton;
    procedure FormCreate(Sender: TObject);
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  RichEdit: TRichEdit;
  TabSheet: TTabSheet;
  Klasa: TKlasa;
  

implementation

constructor TKlasa.Create;
begin
 TabSheet := TTabSheet.Create(Form1);
 TabSheet.PageControl := Form1.PageControl;
 RichEdit := TRichEdit.Create(TabSheet);
 RichEdit.readonly := True;
 RichEdit.Left := 10;
 RichEdit.Top := 219;
 RichEdit.Width := 943;
 RichEdit.Height := 142;
 RichEdit.Parent := TabSheet;
//jeśli wstawiłbym rodzica Form1, to komponent nie zniknie, ale ja chcę żeby 

//rodzicem był TabSheet

 RichEdit.ScrollBars := ssVertical;
end;


{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
  Klasa := TKlasa.Create;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  NewThread: TWatek;
begin
  NewThread := TWatek.Create;
end;


procedure TWatek.Execute;
begin
  RichEdit.Lines.Add('lol');
end;

constructor TWatek.Create;
begin
 RichEdit.Lines.Add('');
//od powyższej linii zależy, czy RichEdit zniknie czy też nie - nie musi ona

//znajdować się tutaj, może być gdziekolwiek, byle przed rozpoczęciem wątku

 inherited Create(False);
end;

end.
0

Faktycznie trochę namieszałem, bo jak się okazało, kluczem było właśnie miejsce tworzenia wątku. Tworzyłem go zaraz po tworzeniu Klasy w FormCreate, a trzeba było trochę odczekać i odpalić go np wciskając Button.

1 użytkowników online, w tym zalogowanych: 0, gości: 1