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?
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ć
W wątku:
procedure Thread.RichEditChange;
begin
// Zmiany w RichEdit...
end;
procedure Thread.Execute;
begin
Synchronize(RichEditChange);
end;
Powinnno działać.
A jak tworzysz RichEdita ?
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...
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;
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.
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.