Delphi - 同步线程与框架

发布于 2024-10-21 17:34:03 字数 605 浏览 1 评论 0原文

下午好 :-), 我有一个框架。这个框架是我通过主窗体动态创建的。

主要形式:

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

在框架中我有一个线程。我将此称为“框架中的线程”。为什么Thread和Frame可以同步?没有:

var
Form1: TForm1;

在框架内调用线程,并且我想更改框架中进度条的位置。我不知道,为什么我可以在Thread的Synchronize方法中访问ProgressBar。

如果是 Form 中的 Thread 和 ProgressBar - 同步访问是 Form1.ProgressBar ...

但是我在 Frame 中有 Thread 和 ProgressBar。

Good afternoon :-),
I have one Frame. This Frame I dynamically created by Main Form.

Main form:

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

In Frame I have a Thread. I call this Thread from Frame. Why I can synchronize Thread with Frame? There isn't any:

var
Form1: TForm1;

I call Thread inside Frame and I want to change Position of ProgressBar in Frame. I don't know, why I can in Synchronize method of Thread access the ProgressBar.

If would be Thread and ProgressBar in Form - Synchronize access is Form1.ProgressBar ...

But I have Thread and ProgressBar in Frame.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

小女人ら 2024-10-28 17:34:03

如果您唯一要做的就是从线程更新进度条,那么有一个更轻量级的选项。我会考虑使用 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.

If the only thing you're trying to do is update the progress bar from the thread, there is a lighter weight option. I would consider using PostMessage instead. You don't want your thread to know too much about the details of the frame anyway.

When you create the thread, give it the handle of your frame so it knows where to post the message. Have the frame listen for the Windows message, which includes the progress position, and update the progress bar.

Here is a very simple example that increments the progress bar from 0 to 100 with a short sleep between each increment:

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.
阿楠 2024-10-28 17:34:03

您可以为线程提供进度条的参考。

示例线程类。

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;

You can give a reference to your progress bar to the thread.

Sample thread class.

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.

Use like this

var
    PBT: TProgressBarThread;
begin
    PBT := TProgressBarThread.Create(True);
    PBT.FreeOnTerminate := True;
    PBT.SetProgressBar(ProgressBar1);
    PBT.Start;
//  PBT.Resume;
end;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文