정리는 아직 못하고 테스트만 했다. 뭐라고 설명해야할지 잘 몰라서이다. ;;
program Project1;
uses
FastMM4, FastMM4Messages, SyncObjs,
Forms,
uMain in 'uMain.pas' {fmMain},
uTest1 in 'uTest1.pas';
{$R *.res}
begin
//RegisterExpectedMemoryLeak(TCriticalSection ,1); // TCriticalSection 이 SyncObjs 안에 있음.
Application.Initialize;
Application.CreateForm(TfmMain, fmMain);
Application.Run;
end.
unit uMain;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, uTest1;
type
TfmMain = class(TForm)
Memo1: TMemo;
Button1: TButton;
Button2: TButton;
Button3: TButton;
Button4: TButton;
procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
{ Private declarations }
FTest1List: array of TTest1;
procedure DoTest(Sender: TObject);
procedure DoTestButtonClick(Sender: TObject);
public
{ Public declarations }
end;
var
fmMain: TfmMain;
implementation
{$R *.dfm}
procedure TfmMain.FormCreate(Sender: TObject);
var
iTmp1: Integer;
iLoop1: Integer;
begin
Left := 0;
Top := 0;
iTmp1 := 3;
SetLength(FTest1List, iTmp1);
for iLoop1 := 0 to iTmp1 - 1 do
begin
FTest1List[iLoop1] := TTest1.Create;
FTest1List[iLoop1].TestIndex := iLoop1 + 1;
FTest1List[iLoop1].OnTest := DoTest;
end;
end;
procedure TfmMain.FormDestroy(Sender: TObject);
var
iTmp1: Integer;
iLoop1: Integer;
begin
for iLoop1 := Length(FTest1List) - 1 downto 0 do
begin
FTest1List[iLoop1].Free;
FTest1List[iLoop1] := nil;
end;
end;
procedure TfmMain.Button1Click(Sender: TObject);
begin
DoTestButtonClick(Sender);
end;
procedure TfmMain.DoTestButtonClick(Sender: TObject);
begin
try
if Assigned(FTest1List[TButton(Sender).tag]) then
begin
FTest1List[TButton(Sender).tag].Test;
end;
except
on E: Exception do
begin
Memo1.Lines.Add('TfmMain.DoTestButtonClick Exception ' + E.Message);
end;
end;
end;
procedure TfmMain.DoTest(Sender: TObject);
begin
if (Sender is TTest1) then
begin
Memo1.Lines.Add('TTest1, TestIndex is ' + IntToStr(TTest1(Sender).TestIndex));
end;
end;
end.
unit uTest1;
interface
uses
SysUtils, Classes, Dialogs
;
type
TTest1 = class
private
FOnTest: TNotifyEvent;
public
TestIndex: Integer;
procedure Test;
property OnTest: TNotifyEvent read FOnTest write FOnTest;
end;
implementation
{ TTest1 }
procedure TTest1.Test;
begin
ShowMessage('TTest1, TestIndex is ' + IntToStr(TestIndex));
if Assigned(FOnTest) then
begin
FOnTest(Self);
end;
end;
end.
TTest1 객체를 여러 개 생성한 후 TTest1 의 테스트 이벤트 OnTest 에 이 TTest1 의 객체를 생성하고 사용하는 fmMain 의 DoTest 프로시져를 연결한 경우 어떤 TTest1 의 객체에서라도 OnTest 이벤트가 발생하면 DoTest 프로시져가 실행되는 것이다.
보면 알겠지만 TTest1 의 이벤트와 fmMain의 프로시져를 연결한 것이라 TTest1 이 fmMain을 직접 알고 있지 않아도, TTest1 이 있는 pas 파일의 Uses 에 uMain 이 없어도 된다는 것이다. 이래야 나중에 fmMain 이 바뀌거나 할 때도 TTest1 의 소스는 수정하지 않을 수 있다. 특히나 fmMain 에 TMemo 객체 하나 올려놓고 로그를 찍는 경우라면 더 말할 나위 없을 것이다. TMemo 객체 이름이 바뀌거나 대상이 바뀌거나 하면 이곳저곳 수정하기 바쁜데 수정할 곳을 fmMain 안에 모아둘 수 있다.
...이걸 어디에 써먹으려고 한 것이가하면...Indy 의 OnConnect 와 OnDisconnect 이벤트를 이벤트 방식으로 처리하기 위해서 시험한 것이다.
최근 덧글