![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Потоки на WinApi [D7, WinXP]
Grinder © (2004-01-08 17:37:00)
Мастера. Подскажите ошибочку.
Вот есть код
Procedure ThreadTime;
begin
timesetwindow.GetInetTime(dtm);
ExitThread(0);
end;
procedure Ttimesetwindow.resbtnClick(Sender: TObject);
begin
createthread(nil, 128, @ThreadTime, self, 0, h1);
end;
При закрытии этого окна после работы потока выводится ошибка
System Error. Code: 1400.
Invalid window handle.
Что она значит? И почему она вывобится после использования потока?
panov (2004-01-08 20:50:00) [1]
Обрати внимание на строки
FDT := TIdDayTime.Create(nil);
и
Synchronize(Update);
Synchronize используется только для обновления уже полученными данными, процедура Update работает в основном потоке, поэтому Synchronize использут как можно реже.
Grinder (2004-01-08 20:46:00) [2]
Спасибо огромное. Надо же.
Работает :)
panov (2004-01-08 20:41:00) [3]
Забыл деструктор добавить:
destructor TSyncTime.Destroy;
begin
FDT.Free;
inherited;
end;
panov (2004-01-08 20:39:00) [4]
unit uTSyncTime;
interface
uses
Classes,
Unit1,
IdDayTime;
type
TSyncTime = class(TThread)
private
FDT: TIdDayTime;
FStr: String;
protected
procedure Execute; override;
procedure Update;
public
constructor Create;
end;
implementation
procedure TSyncTime.Update;
begin
Form1.Memo1.Lines.Add(FStr);
end;
constructor TSyncTime.Create;
begin
inherited Create(True);
FDT := TIdDayTime.Create(nil);
FDT.Host := "time-a.nist.gov";
FreeOnTerminate := True;
Resume;
end;
procedure TSyncTime.Execute;
begin
FStr := FDT.DayTimeStr;
Synchronize(Update);
end;
end.
Grinder (2004-01-08 20:24:00) [5]
Кстати, а ведь в статье тоже Design Time компоненты.
Grinder (2004-01-08 20:22:00) [6]
Вот сделал в run-time
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, IdBaseComponent, IdComponent, IdTCPConnection,
IdTCPClient, IdTime;
type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
type
TTimeThread = class(TThread)
private
GetDateTime:TDateTime;
protected
procedure GetInetTime;
procedure Execute; override;
end;
var
Form1: TForm1;
dtm:string;
implementation
{$R *.dfm}
procedure TTimeThread.GetInetTime;
var
datetime1:TIdTime;
begin
try
datetime1:=TIdTime.Create(form1);
datetime1.Timeout:=10000;
datetime1.Host:="www.time.com";
dtm:=DateToStr(datetime1.DateTime);
finally
datetime1.Free;
end;
end;
procedure TTimeThread.Execute;
begin
Synchronize(GetInetTime);
end;
procedure TForm1.Button1Click(Sender: TObject);
var
TimeThread:TTimeThread;
begin
TimeThread:=TTimeThread.Create(False);
Caption:=dtm;
end;
end.
А всё равно висит.
panov (2004-01-08 20:12:00) [7]
Метод Synchronize выполняется в контексте основного потока, поэтому подход, который реализован у тебя, в корне не верен.
Для работы в потоке тебе придется объекты, которые ты создавал в Design-Time, создавать и реализовывать динамически в Run-Time.
panov (2004-01-08 20:09:00) [8]
Заметил, что ты уже прочитал статью, сорри.
panov (2004-01-08 20:08:00) [9]
Рекомендую сначала почитать статьи на сайте.
http://www.delphimaster.ru/articles/thread/index.html
http://www.delphimaster.ru/articles/panov/index.html
Grinder (2004-01-08 20:02:00) [10]
чотбы народ не запутывать, я вот экзампл маленткий написал
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, IdBaseComponent, IdComponent, IdTCPConnection,
IdTCPClient, IdTime;
type
TForm1 = class(TForm)
IdTime: TIdTime;
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
type
TTimeThread = class(TThread)
private
GetDateTime:TDateTime;
protected
procedure GetInetTime;
procedure Execute; override;
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TTimeThread.GetInetTime;
begin
form1.CAption:=DateToStr(Form1.IdTime.DateTime);
end;
procedure TTimeThread.Execute;
begin
Synchronize(GetInetTime);
end;
procedure TForm1.Button1Click(Sender: TObject);
var
TimeThread:TTimeThread;
begin
TimeThread:=TTimeThread.Create(False);
end;
end.
Так вот зависание всё равно происходит.
Grinder (2004-01-08 19:50:00) [11]
Вот решил сделать через Tthread, но что-то не видно работы поотка. Виснит.
type
TTimeThread = class(TThread)
private
GetDateTime:TDateTime;
protected
procedure GetInetTime;
procedure Execute; override;
end;
procedure TTimeThread.GetInetTime;
begin
with timesetwindow do begin
GetDateTime:=now;
okbtn.Enabled:=False;
try
with the_main_form_1983.sysframe.timesync do
begin
progpanel.Show;
Application.ProcessMessages;
Screen.Cursor:=crHourGlass;
Timer.Enabled:=False;
try
indate:=DateTime; (вот место зависания. тут идёт синхронизация времени)
...
end;
procedure TTimeThread.Execute;
begin
Synchronize(GetInetTime);
end;
procedure Ttimesetwindow.resbtnClick(Sender: TObject);
var
TimeThread:TTimeThread;
begin
TimeThread:=TTimeThread.Create(False);
end;
Вот как реализовал всё. Но зависон всё равно идёт. С WinAPI не было. Как думаете почему?
Я всё старался делать как описано тут
http://www.delphimaster.ru/articles/thread/
BiN (2004-01-08 18:45:00) [12]
... winapi лучше работает
фактически все компоненты используют winapi/ Если же тебя не устраивает чересчур громоздкий код дельфи при работе с ВСЛ, то нужно писать приложение с нуля, используя сходные с борландовскими конструкции, пусть и не такие универсальные, но зато компактные.
А TThread - это не VCL, а просто полезный класс, инкапсулирующий в себя функции для работы с объектами системного ядра Windows.
Grinder (2004-01-08 18:33:00) [13]
Да VCL
Попробую. Просто везде на форуме говорят что на winapi лучше работает.
BiN (2004-01-08 18:25:00) [14]
Пользуйся TThread и Synchronize иже с ним - ведь у тебя timesetwindow - это vcl-форма, как я понимаю
Grinder (2004-01-08 18:20:00) [15]
А как тогда быть?
Компонент синхронизации времени находится на этой форме. Сложновато как-то выкрутиться.
P.S. Вы уж извините за мои такие вопросы. Но просто я недавно работаю с потоками.
Polevi (2004-01-08 18:09:00) [16]
не надо обращаться к окну, созданному в другом кодовом потоке
Grinder (2004-01-08 18:05:00) [17]
Спасибо.
А как сделать чтобы работало :)
panov (2004-01-08 17:50:00) [18]
Все дело вот здесь -
timesetwindow.GetInetTime(dtm);