Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > [ "Начинающим" ]
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 15.03.2015, 19:22
Аватар для SpectraL
SpectraL SpectraL вне форума
Начинающий
 
Регистрация: 19.05.2011
Адрес: Санкт-Петербург
Сообщения: 112
Версия Delphi: 10.1 Berlin
Репутация: 10
Вопрос Вызов события OnPaint из другого потока

Скажите пожалуйста, как правильно вызвать событие TForm1.PaintBox1Paint из TThread.Execute?
Код:
unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Unit2, Vcl.ExtCtrls;

type
  TForm1 = class(TForm)
    PaintBox1: TPaintBox;
    procedure FormCreate(Sender: TObject);
    procedure PaintBox1Paint(Sender: TObject);
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
  Thread1 := TThread1.Create;
end;

procedure TForm1.PaintBox1Paint(Sender: TObject);
begin
  BitBlt(Form1.PaintBox1.Canvas.Handle, 0, 0, Bitmap1.Width, Bitmap1.Height, Bitmap1.Canvas.Handle, 0, 0, SrcCopy); // копируем изображение из Bitmap1 в PaintBox1
end;

end.
Код:
unit Unit2;

interface

uses
  System.Classes, Vcl.Graphics;

type
  TThread1 = class(TThread)
  protected
    procedure Execute; override;
  end;

var
  Thread1: TThread1;
  Bitmap1: TBitmap;

implementation

uses
  Unit1;

procedure TThread1.Execute;
begin
  Bitmap1 := TBitmap.Create;
  Bitmap1.SetSize(Form1.PaintBox1.Width, Form1.PaintBox1.Height); // определяем размер изображения (создаём его)
  Synchronize(procedure
  begin
    Form1.PaintBox1Paint(Nil);
  end);
end;

end.

Последний раз редактировалось SpectraL, 16.03.2015 в 12:58.
Ответить с цитированием
  #2  
Старый 15.03.2015, 20:01
Аватар для Alex_4444
Alex_4444 Alex_4444 вне форума
Прохожий
 
Регистрация: 22.12.2014
Сообщения: 14
Версия Delphi: XE5
Репутация: 50
По умолчанию

1) В модуле с потоком приготовь заранее процедуру синхронизации с главной формой.
2) Что за битмап? Битмап надо передать главной форме в процедуре синхронизации.
3) Как правило: всё, что принадлежит главной форме (размер её компонентов, сами компоненты и т.д.), считывается или изменяется только в процедуре синхронизации. (Иначе глюков не оберёшься)
4) Form1.PaintBox1Paint(Form1) - не надо nil-ов в потоках. Кто-то должен отвечать за происходящее в системе.
__________________
Самые сильные программисты были на заре компьютеризации.
И чем дольше я программист, тем больше это понимаю - мы до сих пор поддерживаем их код...

Последний раз редактировалось Alex_4444, 15.03.2015 в 20:06.
Ответить с цитированием
Этот пользователь сказал Спасибо Alex_4444 за это полезное сообщение:
SpectraL (15.03.2015)
  #3  
Старый 16.03.2015, 10:06
Аватар для SpectraL
SpectraL SpectraL вне форума
Начинающий
 
Регистрация: 19.05.2011
Адрес: Санкт-Петербург
Сообщения: 112
Версия Delphi: 10.1 Berlin
Репутация: 10
По умолчанию

"Form1.PaintBox1Paint(Form1);" - это же просто вызов, поэтому можно использовать без синхронизации?
Ответить с цитированием
  #4  
Старый 16.03.2015, 10:39
Аватар для NumLock
NumLock NumLock вне форума
Let Me Show You
 
Регистрация: 30.04.2010
Адрес: Северодвинск
Сообщения: 5,426
Версия Delphi: 7, XE5
Репутация: 59586
По умолчанию

а из потока посылать сообщение форме, а она уже сама заставит PaintBox перерисоваться:
Код:
PostMessage(Form1.Handle, CM_INVALIDATE, 0, 0);
полный код:
Код:
unit Unit1;

interface

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

type
  TMyThread = class(TThread)
  protected
    procedure Execute; override;
  end;

  TForm1 = class(TForm)
    PaintBox1: TPaintBox;
    procedure FormCreate(Sender: TObject);
    procedure PaintBox1Paint(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

{ TMyThread }

procedure TMyThread.Execute;
begin
  while true do
  begin
    PostMessage(Form1.Handle, CM_INVALIDATE, 0, 0);
    Sleep(33);
  end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  TMyThread.Create(False);
end;

procedure TForm1.PaintBox1Paint(Sender: TObject);
begin
  PaintBox1.Canvas.Brush.Color:=clInfoBk;
  PaintBox1.Canvas.FillRect(PaintBox1.ClientRect);
  PaintBox1.Canvas.Font.Color:=clInfoText;
  PaintBox1.Canvas.TextOut(0, 0, IntToStr(GetTickCount));
end;

end.
__________________
Пишу программы за еду.
__________________
Ответить с цитированием
Этот пользователь сказал Спасибо NumLock за это полезное сообщение:
SpectraL (16.03.2015)
  #5  
Старый 16.03.2015, 12:52
Аватар для SpectraL
SpectraL SpectraL вне форума
Начинающий
 
Регистрация: 19.05.2011
Адрес: Санкт-Петербург
Сообщения: 112
Версия Delphi: 10.1 Berlin
Репутация: 10
Вопрос

Почему постоянно вызывается событие OnPaint, если в его процедуру добавить ShowMessage, а на форму добавить TButton?
Код:
unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.ExtCtrls, Vcl.StdCtrls;

type
  TForm1 = class(TForm)
    PaintBox1: TPaintBox;
    Button1: TButton;
    procedure PaintBox1Paint(Sender: TObject);
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.PaintBox1Paint(Sender: TObject);
begin
  ShowMessage('yes')
end;

end.

Последний раз редактировалось SpectraL, 16.03.2015 в 13:29.
Ответить с цитированием
  #6  
Старый 16.03.2015, 16:30
Аватар для Alex_4444
Alex_4444 Alex_4444 вне форума
Прохожий
 
Регистрация: 22.12.2014
Сообщения: 14
Версия Delphi: XE5
Репутация: 50
По умолчанию

использовал код NumLock-а? Там же просто пример. Поэтому у тебя каждые 33 наносекунды окно выскакивает))))Нужно вникать в код же)))
Под твою задачу как-то так:
Код:
unit Unit2;
 
interface
 
uses
  System.Classes, Vcl.Graphics;
 
type
  TThread1 = class(TThread)
  protected
    procedure Execute; override;
    procedure RepaintPaintBox(Bitmap : TBitmap);
  end;
 
var
  Thread1: TThread1;
  Bitmap1: TBitmap;
 
implementation
 
uses
  Unit1;
 
procedure TThread1.Execute;
begin
  Bitmap1 := TBitmap.Create;
  // делай со своим битмапом что угодно затем отдавай форме

  Synchronize(RepaintPaintBox(Bitmap1));

  Bitmap1.Free;
  
end;

procedure TThread1.RepaintPaintBox(Bitmap : TBitmap);
begin
   Form1.RepaintMyPaintBoxPlease(Bitmap);
end;
 
end.

Ну а главный модуль как-то так:

Код:
unit Unit1;
 
interface
 
uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Unit2, Vcl.ExtCtrls;
 
type
  TForm1 = class(TForm)
    PaintBox1: TPaintBox;
    procedure FormCreate(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure PaintBox1Paint(Sender: TObject);
    public
    bitmap1 : TBitmap;
    procedure RepaintMyPaintBoxPlease(Bitmap: TBitmap);
  end;
 
var
  Form1: TForm1;

 
implementation
 
{$R *.dfm}
 
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
    Bitmap1.Free;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
   Bitmap1 := TBitmap.create;
   Thread1 := TThread1.Create;
end;
 
procedure TForm1.PaintBox1Paint(Sender: TObject);
begin
  // эта процедура нам по сути не нужна ))))
end;

procedure RepaintMyPaintBoxPlease(Bitmap: TBitmap);
begin
    Bitmap1.Assign(Bitmap);
    // копируем изображение из Bitmap1 в PaintBox1
    BitBlt(Form1.PaintBox1.Canvas.Handle, 0, 0,
             Bitmap1.Width,  Bitmap1.Height,
             Bitmap1.Canvas.Handle, 0, 0, SrcCopy);
    PaintBox1.Repaint;
end; 

end.
__________________
Самые сильные программисты были на заре компьютеризации.
И чем дольше я программист, тем больше это понимаю - мы до сих пор поддерживаем их код...

Последний раз редактировалось Alex_4444, 16.03.2015 в 16:34.
Ответить с цитированием
Этот пользователь сказал Спасибо Alex_4444 за это полезное сообщение:
SpectraL (16.03.2015)
  #7  
Старый 17.03.2015, 19:58
Аватар для SpectraL
SpectraL SpectraL вне форума
Начинающий
 
Регистрация: 19.05.2011
Адрес: Санкт-Петербург
Сообщения: 112
Версия Delphi: 10.1 Berlin
Репутация: 10
Вопрос

При рисовании по событию OnResize программа зависает. Эту проблему решает процедура Sleep. Можете ещё что-нибудь порекомендовать или использование процедуры Sleep то что надо?
Код:
unit Unit1;

// Form1.Anchors = [akLeft,akTop,akRight,akBottom]
 
interface
 
uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.ExtCtrls, Unit2;
 
type
  TForm1 = class(TForm)
    PaintBox1: TPaintBox;
    procedure FormCreate(Sender: TObject);
    procedure FormResize(Sender: TObject);
    procedure PaintBox1Paint(Sender: TObject);
  end;
 
var
  Form1: TForm1;
 
implementation
 
{$R *.dfm}
 
procedure TForm1.FormCreate(Sender: TObject);
begin
  Thread1 := TThread1.Create
end;

procedure TForm1.FormResize(Sender: TObject);
begin
  Thread1.Suspended := False; // запускаем итерацию рисования
  Sleep(10)
end;
 
procedure TForm1.PaintBox1Paint(Sender: TObject);
begin
  BitBlt(Form1.PaintBox1.Canvas.Handle, 0, 0, Bitmap1.Width, Bitmap1.Height,
  Bitmap1.Canvas.Handle, 0, 0, SrcCopy) // копируем изображение из Bitmap1 в PaintBox1
end;
 
end.
Код:
unit Unit2;
 
interface
 
uses
  System.Classes, Vcl.Graphics;
 
type
  TThread1 = class(TThread)
  protected
    procedure Execute; override;
  end;
 
var
  Thread1: TThread1;
  Bitmap1: TBitmap;
 
implementation
 
uses
  Unit1;
 
procedure TThread1.Execute;
begin
  Bitmap1.Canvas.Lock; // блокируем холст от других потоков

  repeat
    Bitmap1.SetSize(Form1.PaintBox1.Width, Form1.PaintBox1.Height); // определяем размер изображения (создаём его)
    Form1.PaintBox1Paint(Nil); // передаём изображение в PaintBox1
    Thread1.Suspended := True // приостанавливаем поток
  until Thread1.Terminated
end;

initialization

Bitmap1 := TBitmap.Create

finalization

Bitmap1.Canvas.Unlock; // разблокируем холст
Bitmap1.Free

end.

Последний раз редактировалось SpectraL, 18.03.2015 в 12:47.
Ответить с цитированием
  #8  
Старый 18.03.2015, 08:11
Аватар для NumLock
NumLock NumLock вне форума
Let Me Show You
 
Регистрация: 30.04.2010
Адрес: Северодвинск
Сообщения: 5,426
Версия Delphi: 7, XE5
Репутация: 59586
Восклицание

все неправильно!
__________________
Пишу программы за еду.
__________________
Ответить с цитированием
  #9  
Старый 18.03.2015, 10:26
Аватар для SpectraL
SpectraL SpectraL вне форума
Начинающий
 
Регистрация: 19.05.2011
Адрес: Санкт-Петербург
Сообщения: 112
Версия Delphi: 10.1 Berlin
Репутация: 10
Лампочка

Цитата:
Сообщение от NumLock
все неправильно!
Всё идеально.
Ответить с цитированием
Ответ


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 17:23.


 

Сайт

Форум

FAQ

Соглашения

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2025