//callback func 정의
function GetCaption(HWnd : THandle; Param : Pointer): Boolean; stdcall;
// Win32 호출 관례를 따른다는 것을 나타내기 위해 Stdcall 지시자와 함께 선언되어야만 한다
var
Text : String;
begin
SetLength(Text, 100);
GetWindowText(Hwnd, PChar(Text), 100);
Form1.ListBox1.Items.Add(IntToStr(Hwnd) + ':' + Text);
Result := True;
end;
procedure TForm1.Button1Click(Sender: TObject);
//var
// EnumWin : EnumWindowsProc;
begin
ListBox1.Items.Clear;
// EnumWin := GetCaption;
EnumWindows(@GetCaption, 0);
end;
EnumWindowsProc()은 EnumWindows() Win32 API 함수에 넘겨줄 콜백 함수다.
이 함수는 Win32 호출 관례를 따른다는 것을 나타내기 위해 Stdcall 지시자와 함께 선언되어야만 한다.
이 함수를 EnumWindows() 함수에 넘겨주면, 각 최상위 레벨의 윈도우마다 윈도우 핸들을 첫 파라미터로 넘겨주고 호출하게 된다. 각 윈도우의 윈도우 이름과 클래스 이름을 얻기 위해 이 윈도우 핸들을 사용한다
결과
Callback 함수의 좋은 예제로 디렉토리를 뒤지면서 파일을 검색하고, 파일이 발견될 때마다 콜백 함수를 호출하여 이를 표시하는 등이 있다.
콜백 함수를 사용하기 위해서는 먼저 procedure 형을 유닛의 type 섹션(Form이 달려있는 type 섹션이 아닌)에 다음과 같이 선언해야 한다.
TFileSearchCallback = procedure(FileName: string) of Object;
이와 같이 콜백 함수를 사용하기 위해서는 객체의 메소드로서의 procedure 형을 선언해서 사용한다. 여기서 파라미터 형이 맞을 경우 얼만든지 콜백으로 사용이 가능하다.
그리고 나서는 실제로 콜백 함수를 호출할 procedure를 다음과 같이 선언.
(private 섹션에)
procedure SearchDirectory(Dir, Condition: stirng; cb: TFileSearchCallback);
이 procedure의 형태를 살펴보면 검색을 할 Directory와 검색할 문자열을 나타내는 파라미터인 Dir, Condition은 다른 procedure의 형태와 별로 다를 것이 없지만, cb 파라미터에서 앞에서 선언한 TFileSearchCallback procedure 형을 사용하는 것이 중요한 부분이다. 이 파라미터의 의미는 여기에 콜백 함수를 대입하여 콜백을 이용할 수 있게 된다는 것이다.
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, FileCtrl, StdCtrls;
//선언하는 장소 헷갈리지 말 것!!
type
TFileSearchCallback = procedure(FileName: string) of Object;
type
TForm1 = class(TForm)
Button1: TButton;
ListBox1: TListBox;
Edit1: TEdit;
DriveComboBox1: TDriveComboBox;
DirectoryListBox1: TDirectoryListBox;
procedure Button1Click(Sender: TObject);
private
procedure SearchDirectory(Dir, Condition: string; cb: TFileSearchCallback);
procedure FileSearchCallback(FileName: string);
public
{ Public 먬뙻 }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.SearchDirectory(Dir, Condition: string; cb: TFileSearchCallback);
var
SearchRec: TSearchRec; // used for searching files
Value: Longint;
begin
Value := FindFirst(Dir + '\' + Condition, faAnyFile, SearchRec);
while Value = 0 do
begin
cb(Dir + '\' + SearchRec.Name);
Value := FindNext(SearchRec);
end;
end;
procedure TForm1.FileSearchCallback(FileName: string);
begin
ListBox1.Items.Add(ExtractFileName(FileName));
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
ListBox1.Items.Clear;
SearchDirectory(DirectoryListBox1.Directory, Edit1.Text, FileSearchCallback);
end;
end.
이 procedure는 Dir 파라미터로 넘어온 Directory를 검색하서 파일을 찾게 되면 콜백 함수를 호출하는데, 콜백 함수에게 현재 파일의 경로를 포함한 파일 이름을 파라미터로 넘겨주게 된다.
사용 컴포넌트 : TButton, TListBox, TEdit, TDriveComboBox, TDirectoryListBox
설정: Button1-시작, Edit1-'', DriveComboBox1의 DirList-DirectoryListBox1