아래와 같이 해 보았습니다.
=== 호출폼
unit processing;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, ComCtrls, ExtCtrls, ThreadProcess;
const
WM_THREAD_COMPLETE = WM_APP + 5437;
type
Tfrm_processing = class(TForm)
btn_cancel: TButton;
ProgressBar1: TProgressBar;
Animate1: TAnimate;
Label1: TLabel;
procedure btn_cancelClick(Sender: TObject);
procedure FormShow(Sender: TObject);
private
FThread: TPrimeThrd;
procedure HandleThreadCompletion(var Message: TMessage);
{ Private declarations }
public
{ Public declarations }
end;
var
frm_processing: Tfrm_processing;
implementation
{$R *.DFM}
procedure Tfrm_processing.HandleThreadCompletion(var Message: TMessage);
begin
if Assigned(FThread) then
begin
FThread.WaitFor;
FThread.Free;
FThread := nil;
end;
Close;
end;
procedure Tfrm_processing.btn_cancelClick(Sender: TObject);
begin
if Assigned(FThread) then
begin
FThread.Terminate;
FThread.WaitFor;
FThread.Free;
FThread := nil;
end;
end;
procedure Tfrm_processing.FormShow(Sender: TObject);
begin
Screen.Cursor := crAppStart;
if not Assigned(FThread) then
begin
FThread := TPrimeThrd.Create(False);
FThread.FreeOnTerminate := False;
try
with FThread do
begin
IniFileName := CurrFileName;
TempDirectory := TempDir;
Resume;
end;
except
on EConvertError do
begin
FThread.Free;
FThread := nil;
end;
end;
end;
end;
end.
== thread
unit ThreadProcess;
interface
uses
Classes, IniFiles;
type
TPrimeThrd = class(TThread)
Private
FTempDir: String;
FIniFileName: String;
FCaption: String;
protected
procedure UpdateLabel;
function StartFileCopy: Boolean;
procedure Execute; override;
public
property IniFileName: String write FIniFileName;
property TempDirectory: String write FTempDir;
end;
implementation
uses SysUtils, Dialogs, Windows, processing;
procedure TPrimeThrd.UpdateLabel;
begin
frm_processing.Label1.Caption := FCaption;
end;
procedure TPrimeThrd.Execute;
begin
if not Terminated then
begin
if StartFileCopy then
PostMessage(frm_processing.Handle, WM_THREAD_COMPLETE, 0, 0);
end;
end;
function TPrimeThrd.StartFileCopy: Boolean;
begin
.
.
.
FCaption := '시작합니다...';
Synchronize(UpdateLabel);
Result := True;
end;
end.
문제는 위의
procedure TPrimeThrd.UpdateLabel;
begin
frm_processing.Label1.Caption := FCaption;
end;
에서 frm_processing.Label1 을 액세스 할수가 없어서 Access Violation이 발생합니다.
처음 해 보는 거라서 왜 문제가 생기는 지를 알 수가 없네요...
좀 알려 주십시오. 고맙습니다.
고드름 김정입니다.
다른 Unit1 과 Unit2 에서 다른 편의 객체를 참조할 경우,
uses 구문에 해당 unit명만 넣어주면 됩니다.
하지만 객체 참조의 Circula 방식의 참조는 불가능합니다.
즉, 서로 Uni1은 Unit2를, 그리고 Unit2는 Unit1을 참조하는게 안됩니다.
( 일반 함수 참조는 가능하더군요... )
이럴 경우 어쩔 수 없지, 한 Unit 내에서 두 개의 객체를 구현해야 합니다.
그럼.
김경식 wrote:
> 아래와 같이 해 보았습니다.
>
> === 호출폼
> unit processing;
>
> interface
>
> uses
> Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
> StdCtrls, ComCtrls, ExtCtrls, ThreadProcess;
>
> const
> WM_THREAD_COMPLETE = WM_APP + 5437;
>
> type
> Tfrm_processing = class(TForm)
> btn_cancel: TButton;
> ProgressBar1: TProgressBar;
> Animate1: TAnimate;
> Label1: TLabel;
> procedure btn_cancelClick(Sender: TObject);
> procedure FormShow(Sender: TObject);
> private
> FThread: TPrimeThrd;
> procedure HandleThreadCompletion(var Message: TMessage);
> { Private declarations }
> public
> { Public declarations }
> end;
>
> var
> frm_processing: Tfrm_processing;
>
> implementation
>
> {$R *.DFM}
>
> procedure Tfrm_processing.HandleThreadCompletion(var Message: TMessage);
> begin
> if Assigned(FThread) then
> begin
> FThread.WaitFor;
> FThread.Free;
> FThread := nil;
> end;
> Close;
> end;
>
> procedure Tfrm_processing.btn_cancelClick(Sender: TObject);
> begin
> if Assigned(FThread) then
> begin
> FThread.Terminate;
> FThread.WaitFor;
> FThread.Free;
> FThread := nil;
> end;
> end;
>
> procedure Tfrm_processing.FormShow(Sender: TObject);
> begin
> Screen.Cursor := crAppStart;
> if not Assigned(FThread) then
> begin
> FThread := TPrimeThrd.Create(False);
> FThread.FreeOnTerminate := False;
> try
> with FThread do
> begin
> IniFileName := CurrFileName;
> TempDirectory := TempDir;
> Resume;
> end;
> except
> on EConvertError do
> begin
> FThread.Free;
> FThread := nil;
> end;
> end;
> end;
> end;
>
> end.
>
>
> == thread
>
> unit ThreadProcess;
>
> interface
>
> uses
> Classes, IniFiles;
>
> type
> TPrimeThrd = class(TThread)
> Private
> FTempDir: String;
> FIniFileName: String;
> FCaption: String;
> protected
> procedure UpdateLabel;
> function StartFileCopy: Boolean;
> procedure Execute; override;
> public
> property IniFileName: String write FIniFileName;
> property TempDirectory: String write FTempDir;
> end;
>
> implementation
>
> uses SysUtils, Dialogs, Windows, processing;
>
> procedure TPrimeThrd.UpdateLabel;
> begin
> frm_processing.Label1.Caption := FCaption;
> end;
>
> procedure TPrimeThrd.Execute;
> begin
> if not Terminated then
> begin
> if StartFileCopy then
> PostMessage(frm_processing.Handle, WM_THREAD_COMPLETE, 0, 0);
> end;
> end;
>
> function TPrimeThrd.StartFileCopy: Boolean;
> begin
> .
> .
> .
> FCaption := '시작합니다...';
> Synchronize(UpdateLabel);
> Result := True;
> end;
>
> end.
>
> 문제는 위의
> procedure TPrimeThrd.UpdateLabel;
> begin
> frm_processing.Label1.Caption := FCaption;
> end;
> 에서 frm_processing.Label1 을 액세스 할수가 없어서 Access Violation이 발생합니다.
> 처음 해 보는 거라서 왜 문제가 생기는 지를 알 수가 없네요...
>
> 좀 알려 주십시오. 고맙습니다.