Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Как организовать поток с графикой? [D7, WinXP]


Fed ©   (2005-11-09 00:32:00) 

Здравствуйте! Пишу курсовую по Delphi. Задача в том, чтобы нарисовать данный механизм и заставить его двигаться, также рассчитать скорости точек механизма.
 Движение механизма создается с помощью цикла рисования(и стирания) на  Canvas. Если выполнять рисование в основном потоке, то пока цикл не кончится на форма не реагирует на запросы(ни кнопку нажать, ни даже закрыть).
  Если выполнять в отдельном потоке (TThread), то в какой-то случайный момент времени цикл прерывается и dephi выдаёт что-то типа "Canvas does not allow drawing".
Если при организации потока используем Synchronize (а многие издания пишут что без него вообще нельзя), то повторяется ситуация с выполнением цикла в основном потоке, т.е. на время выполнения цикла форма недоступна.
   Был бы очень признателен, если бы кто-нибудь что-нибудь подсказал.


Fed   (2005-11-14 11:51:00) [1]


> А не нужно синхронизировать все тело цикла.
> Во вторичном потоке ведешь расчеты и отрисовку на битмап,
>  а в синхронизируемом методе потока ТОЛЬКО быстренько копируешь
> битмап на форму.

Что-то все равно не работает :(
вот простенький пример (в самой проге расчеты гораздо ложнее)

//Основной модуль
unit Unit1;

interface

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

type
 TForm1 = class(TForm)
   Button1: TButton;
   Button2: TButton;
   procedure Button1Click(Sender: TObject);
 private
   T1:TMyClass;
   { Private declarations }
 public
   { Public declarations }
 end;

var
 Form1: TForm1;
 flg:boolean;
implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
flg:=true;
T1:=TMyClass.Create(false);
end;

end.

//Модуль потока
unit Unit2;

interface

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

type
 TMyClass = class(TThread)
 private
 procedure Copy;
   { Private declarations }
 protected
   procedure Execute; override;
 end;
 Var Bitmap:TBitmap;

implementation
uses Unit1;

{ Important: Methods and properties of objects in visual components can only be
 used in a method called using Synchronize, for example,

     Synchronize(UpdateCaption);

 and UpdateCaption could look like,

   procedure TMyClass.UpdateCaption;
   begin
     Form1.Caption := 'Updated in a thread';
   end; }

{ TMyClass }
procedure TMyClass.Copy;
var Rect1,Rect2:TRect;
begin
Rect1.Left:=0;
Rect1.Top:=0;
Rect1.Right:= Rect1.Left+150;
Rect1.Bottom:=Rect1.Top+150;
Rect2.Left:=0;
Rect2.Top:=0;
Rect2.Right:= Rect1.Left+150;
Rect2.Bottom:=Rect1.Top+150;
Form1.Canvas.BrushCopy(Rect1,Bitmap,Rect1,Form1.Color);
end;
procedure TMyClass.Execute;
var i:integer;
begin
with Bitmap do begin
Canvas.Pen.Color:=ClBlue;
i:=0;
While flg do begin
Canvas.Pen.Color:=clWhite;
Canvas.Ellipse(100+i-1,100,50+i-1,50);
Canvas.Pen.Color:=clBlue;
Canvas.Ellipse(100+i,100,50+i,50);
Synchronize(Copy);
i:=i+1;
 { Place thread code here }
end;
end;
end;

end.



Или я не так понял, может копировать не через BrushCopy?


Eraser   (2005-11-09 19:35:00) [2]


> Fed ©   (09.11.05 00:32)

Так же советую прорисовку на форму осуществлять в событии OnPaint, а инициировать через вызов InvalidateRect.


MBo   (2005-11-09 07:03:00) [3]

>т.е. на время выполнения цикла форма недоступна.
А не нужно синхронизировать все тело цикла.
Во вторичном потоке ведешь расчеты и отрисовку на битмап, а в синхронизируемом методе потока ТОЛЬКО быстренько копируешь битмап на форму.
Кстати, у TCanvas есть еще метод Lock - может пригодиться.


Наверх

Титульная страница Поиск, карта сайта Написать письмо