Delphi - синхронизировать поток с фреймом - PullRequest
2 голосов
/ 13 марта 2011

Добрый день :-), У меня есть один кадр. Этот фрейм я динамически создавал по главной форме.

Основная форма:

Interface := TInterface.Create(self);
    with handlingInterface do begin
      Parent := Form1;
      Left := 0; Top := 35;
      Width := 570; Height := 250;
    end;

В кадре у меня есть тема. Я называю эту тему из кадра. Почему я могу синхронизировать поток с фреймом? Там нет ни одного:

var
Form1: TForm1;

Я вызываю Thread внутри кадра , и я хочу изменить положение ProgressBar в кадре . Я не знаю, почему я могу в Синхронизировать метод Thread получить доступ к ProgressBar.

Если бы в форме были Thread и ProgressBar, доступ к синхронизации - Form1.ProgressBar ...

Но у меня есть Thread и ProgressBar в Frame .

Ответы [ 2 ]

9 голосов
/ 13 марта 2011

Если единственное, что вы пытаетесь сделать, это обновить индикатор выполнения из потока, есть вариант с более легким весом. Я хотел бы рассмотреть использование PostMessage вместо этого. В любом случае вы не хотите, чтобы ваша ветка слишком много знала о деталях фрейма.

Когда вы создаете тему, дайте ей дескриптор вашего фрейма, чтобы он знал, где разместить сообщение. Попросите фрейм прослушать сообщение Windows, которое включает в себя позицию прогресса, и обновите индикатор выполнения.

Вот очень простой пример, который увеличивает индикатор выполнения с 0 до 100 с коротким сном между каждым шагом:

unit Unit2;

interface

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

const
  WM_PROGRESS_MESSAGE = WM_USER + 99;

type
  TProgressThread = class(TThread)
  private
    FWindowHandle: HWND;
  protected
    procedure Execute; override;
  public
    property WindowHandle: HWND read FWindowHandle write FWindowHandle;
  end;

  TFrame2 = class(TFrame)
    ProgressBar1: TProgressBar;
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    procedure OnProgressMessage(var Msg: TMessage); message WM_PROGRESS_MESSAGE;
  public
  end;

implementation

{$R *.dfm}

{ TFrame2 }

procedure TFrame2.Button1Click(Sender: TObject);
var
  lThread: TProgressThread;
begin
  lThread := TProgressThread.Create(True);
  lThread.FreeOnTerminate := True;
  lThread.WindowHandle := Self.Handle;
  lThread.Start;
end;

procedure TFrame2.OnProgressMessage(var Msg: TMessage);
begin
  ProgressBar1.Position := Msg.WParam;
end;


{ TProgressThread }

procedure TProgressThread.Execute;
var
  lProgressCount: Integer;
begin
  inherited;

  for lProgressCount := 0 to 100 do
  begin
    PostMessage(FWindowHandle, WM_PROGRESS_MESSAGE, lProgressCount, 0);
    Sleep(15);
  end;
end;

end.
2 голосов
/ 13 марта 2011

Вы можете дать ссылку на ваш индикатор выполнения для потока.

Пример класса потока.

unit Unit6;

interface

uses
    Classes, ComCtrls;

type
    TProgressBarThread = class(TThread)
    private
        { Private declarations }
        FProgressBar: TProgressBar;
        procedure MoveProgress;
    protected
        procedure Execute; override;
    public
        procedure SetProgressBar(ProgressBar: TProgressBar);
    end;

implementation

{ ProgressBarThread }
procedure TProgressBarThread.Execute;
begin
    { Place thread code here }
    Synchronize(MoveProgress);

end;

procedure TProgressBarThread.MoveProgress;
begin
    FProgressBar.StepIt;
end;

procedure TProgressBarThread.SetProgressBar(ProgressBar: TProgressBar);
begin
    FProgressBar := ProgressBar;
end;

end.

Используйте вот так

var
    PBT: TProgressBarThread;
begin
    PBT := TProgressBarThread.Create(True);
    PBT.FreeOnTerminate := True;
    PBT.SetProgressBar(ProgressBar1);
    PBT.Start;
//  PBT.Resume;
end;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...