问题
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.
回答1:
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;
回答2:
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.
来源:https://stackoverflow.com/questions/5290084/delphi-synchronize-thread-with-frame