가끔식 form의 이름을 Edit 등으로 입력받아서 Form을 생성하는 기능을 만들고 싶을때가 있다.
그럴때 유용하게 쓰일수 있는 기능이다.
이는 Form뿐만 아니라 다른 Control 생성에서 문제 없다.
[힌트]
프로그램의 시작점인 프로젝트 파일(예 Project1.cpp ) 을 보면
아래와 같은 식으로 Form을 생성한다.
Application->CreateForm(__classid(TForm1), &Form1);
Application->CreateForm(__classid(TForm2), &Form2);
일반적으로 Form을 생성하는 방식과 좀 다르다.
TForm1 *frm=new TForm1(NULL);
__classid(TForm1) ==> 요놈이 무엇일까?
이건 TMetaClass 라는것으로 TForm1 클래스에 대한 정보를 가지고 있는 놈이다.
그렇다면 string으로 각 class의 MetaClass만 알아내면
얼마든지 string으로 Form을 생성할수 있지 않을까?
[방법]
1. 먼저 class를 등록해 줘야한다.
void __fastcall TForm1::FormCreate(TObject *Sender)
{
RegisterClassA(__classid(TForm1));
RegisterClassA(__classid(TForm2));
RegisterClassA(__classid(TForm3));
RegisterClassA(__classid(TForm4));
}
메인폼이 시작할때 TForm1 , TForm2 , TForm3 , TForm4 클래스를 등록해줬다.
2. GetClass라는 함수를 이용하여 string으로 해당 class의 TMetaClass 를 얻는다.
그런다음은 Application의 CreateForm을 호출해서 생성하면 된다.
void __fastcall TForm1::Button1Click(TObject *Sender)
{
TForm *frm;
if(CreateForm(&frm,Edit1->Text))
frm->Show();
}
//---------------------------------------------------------------------------
bool __fastcall TForm1::CreateForm(TForm **frm,String sClsName)
{
TMetaClass *mt;
mt=GetClass(sClsName);
if(mt)
{
Application->CreateForm(mt,frm);
return true;
}
return false;
}
//---------------------------------------------------------------------------
//델파이 코드는?
procedure TForm1.FormCreate(Sender: TObject);
begin
RegisterClass(TForm1);
RegisterClass(TForm2);
RegisterClass(TForm3);
RegisterClass(TForm4);
end;
procedure TForm1.Button6Click(Sender: TObject);
var
frm: TForm;
begin
if(CreateForm(frm,Edit1.Text)) then
begin
frm.ShowModal();
frm.Free;
end;
end;
function TForm1.CreateForm(var frm:TForm;sFormClass:String): boolean;
var
mt : TPersistentClass;
begin
Result:=false;
mt:=GetClass(sFormClass);
if mt<>nil then
begin
Application.CreateForm(TComponentClass(mt),frm);
Result:=true;
end;
end;
그럼..