![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
VCL и многопоточность...
Jolik © (2004-08-08 00:03:00)Здрассте!
Как народ выкручивается когда надо вызывать визуальные компоненты из неосновного потока программы.
Такая задача:
Из нескольких нитей программы в одну точку приходят текстовые предложения, которые должны выводиться в Мемо. Сейчас я данные из разных нитей сначала группирую в защищенный критическими секциями СтрингЛист, и посылаю, причем через ПостМессаже, сообщение в основное окно. В ответ на это сообщение основное окно добавляет в Мемо данные из СтрингЛиста. Решение подсмотрел в реализации Syncronize Дельфей.
Может есть какой другой способ?
Как то читал, что можно вызвать АПИ функцию которая сообщит когда можно вызывать функции визуальных объектов Виндовс, типа как INT21 в ДОСе. Не знаю, относится ли это к VCL (там ведь и у самих борландов куча кода).
Спасибо!
Jolik (2004-08-08 02:07:00) [21]Может (и скорее всего) я и не прав - в Syncronize применяется SendMessage, но при использовании SendMessage мои приложения практически моментально зависали... Приходилось менять на PostMessage (Со всеми вытекающими - в момент когда обрабатывается сообщение ссылка на строку может уже быть недействительной...) Попробую еще раз..
Спасибо!
Fay (2004-08-08 01:08:00) [22]2 Jolik © (08.08.04 00:13) [2]
>> SendMessage - выполняет код обработки сообщений окна В ТОМ ЖЕ ПОТОКЕ
Это УЖАСНО !!! 8) Проверьте в отладчике.
Сделано нкрасиво - просто показать, что я имел ввиду. Надеюсь, Вы простите мне маленькую лень 8)
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
const
WM_FYVM = WM_USER + 345;
type
TForm1 = class(TForm)
Button1 : TButton;
Memo1 : TMemo;
Button2 : TButton;
procedure Button2Click(Sender : TObject);
procedure Button1Click(Sender : TObject);
private
procedure WMFyvm(var M : TMessage); message WM_FYVM;
end;
var
Form1 : TForm1;
implementation
{$R *.dfm}
var
dwEvent : DWORD;
procedure ThreadProc(p : PDWORD); stdcall;
var
r, h : DWORD;
procedure DoMsg(s : string);
begin
SendMessage(Form1.Handle, WM_FYVM, Integer(PChar(@s[1])), 0);
end;
begin
h := p^;
repeat
r := WaitForSingleObject(dwEvent, 1000);
case r of
WAIT_TIMEOUT : DoMsg(Format('Строка от потока %d', [h]));
WAIT_ABANDONED :
begin
DoMsg('Сдохло событие');
Break;
end;
WAIT_OBJECT_0 :
begin
DoMsg(Format('Поток %d прощается с Вами', [h]));
Break;
end;
end;
until False;
CloseHandle(h);
end;
procedure TForm1.Button2Click(Sender : TObject);
begin
PulseEvent(dwEvent);
end;
procedure TForm1.WMFyvm(var M : TMessage);
begin
Memo1.Lines.Add(PChar(M.WParam));
end;
procedure TForm1.Button1Click(Sender : TObject);
var
h, id : DWORD;
begin
h := CreateThread(nil, 0, @ThreadProc, @h, CREATE_SUSPENDED, id);
ResumeThread(h);
end;
initialization
dwEvent := CreateEvent(nil, True, False, nil);
finalization
CloseHandle(dwEvent);
end.
Jolik (2004-08-08 00:13:00) [23]Посмотрите исходники Synchronize - убожество. Тем более, что все что я выше написал - тоже самое.
SendMessage - выполняет код обработки сообщений окна В ТОМ ЖЕ ПОТОКЕ откуда вызывается и поэтому не прокатывает. Да и как передать например строку в сообщении? Можно передать только ссылку, и пока сообщение не отработается, ссылка должна быть активной - тоже не очень красиво...
В любом случае, спасибо!
Fay (2004-08-08 00:06:00) [24](Synchronize or SendMessage) and F1