자동생성이 아니라 동적생성으로 하면서 폼을 딱 한번만 생성하기.....

님께서 하신 방법도 한 방법이 됩니다
델파이 유저들이 많이 쓰는 방법 몇가지를 소개하고자 합니다.

첫번째.  Form의 변수 자체를 이용한 방법
     님처럼 따로 변수를 두지 않고 Form을 추가하면 자동으로 생성되는 전역변수 자체를 이용합니다.
   
     1)   Form의 OnDestory이벤트에 Form변수를 nil로 Assign해줍니다.
            procedure TForm3.FormDestroy(Sender: TObject);
            begin
              Form3:=nil;
           end;

    2) 이제 Form을 사용할땐 Form3 변수에 객체가 할당되어있는지 체크하고 없으면 다시 생성한후에 Show합니다.

            procedure TForm1.Button2Click(Sender: TObject);
            begin
                if not Assigned(Form3) then Form3:=TForm3.Create(Application);
                Form3.Show();
            end;


두번째. 전역함수를 이용한 방법
      델파이 유저들이 비교적 많이 쓰는 방법같던데...
      Form의 전역변수를 implementation 영역으로 이름 바꿔 옮기구요
      interface 부분에 변수이름과 같은 function을 정의해둡니다.

     1) TForm2 클래스에서 

       unit Unit2;
       interface

       type
       //생략
       
         function Form2():TForm2;

       implementation
       {$R *.dfm}
       var
         frm: TForm2;           //다음과 같이 Form2변수를 수정한다.
       //------------------------------------------
       //Form2() 함수에서 frm변수에 할당된 객체가 없으면 create하여서 return한다.
       function Form2():TForm2;
       begin
         if( not Assigned(frm))then frm:=TForm2.Create(Application);
         Result:=frm;
       end;
       //---------------------------------------------------
       //form의 종료시 frm변수에 nil 로 assign한다.
       procedure TForm2.FormDestroy(Sender: TObject);
       begin
         frm:=nil;
       end;

    2)  위와같이 해놓은후에 사용은 Form객체의 생성파괴 전혀 신경쓰지 않고 다음과 같이 간단히...
       procedure TForm1.Button1Click(Sender: TObject);
       begin
         Form2.Show();  //이때 Form2변수가 아닌 Form2() 함수의 return값을 가지고 Show()를 호출하게 된다.
       end;

세번째. Screen.Forms 리스트를 이용
     VCL에서 Form이 생성되면 전역객체인 Screen객체의 Forms 리스트에 등록되게 됩니다.
     Form이 free 되면 Screen.Forms리스트에서도 삭제가 되구요 

     즉 Screen.Forms 리스트를 검색해보면 Form이 있는지 없는지 쉽게 확인이 되겠죠

      //GetForm함수에서는 파라메터로 받은 classname의 Form이 있는 검색해보고 없으면 새로 생성해서 return해 줍니다.       
       function GetForm(frmClsName:String):TForm ;
       var
         frm: TForm;
         idx: Integer;
       begin
         for idx:=0 to Screen.FormCount -1 do
         begin
           if(Screen.Forms[idx].ClassNameIs(frmClsName))then
           begin
             Result:=Screen.Forms[idx];
             Exit;
           end;
         end;

         Application.CreateForm(TComponentClass(GetClass(frmClsName)),frm);
         // frm:=TForm2.Create(Application);
         Result:=frm;
       end;

       //-----------------------------------------------------------------------------------------
       // 사용은 다음과 같이 간단히....
       procedure TForm1.btn1Click(Sender: TObject);
       begin
         GetForm('TForm2').Show();
       end;
 
       앗참 이경우 GetClass를 이용하여 객체를 생성하려면
       해당 class가 등록되어있어야 합니다.
       다음과 같이 하면 될듯...
       initialization
          RegisterClass(TForm2);


두번째 방법이 많이 쓰이는듯 하구요
세번째 방법은 Form생성뿐만 아니라  다양하게 쓰일수 있습니다.

 
그럼...
      
   
────────────────────────────────────────────────
▷ 모처사님께서 작성하신 내용입니다. 
────────────────────────────────────────────────

>>

// Main 폼
>> procedure TfrmMain.FormCreate(Sender: TObject);
>> begin
>>     IsFirstAbout := True;
>> end;
>> 
>> procedure TfrmMain.btnAboutClick(Sender: TObject);
>> begin
>>   if IsFirstAbout then
>>   begin
>>     fAbout1 := TfrmAbout.Create(Application);
>>     fAbout1.show();
>>     IsFirstAbout := False;
>>   end;
>> end;
>> 
>> // 자식폼 종료시 
>> procedure TfrmAbout.FormDestroy(Sender: TObject);
>> begin
>>   IsFirstAbout := True;
>> end;
>> 
>> 위처럼 폼을 동적으로 생성하고 있습니다.
>> 
>> 버튼을 처음 눌렀을때에는 폼이 한번만 생성되고 있습니다.
>> 그런데 폼을 종료할때 전역변수 IsFirstAbout을 값을 저장해도 값이 저장되지 않는것 같습니다.
>> 
>> 폼을 종료하고 다시 버튼을 클릭해도 폼이 생성되지 않습니다.
>> 
>> 다시 폼을 생성하려 하면 어떻게 해야 할까요?



출처 : http://www.delmadang.com/community/bbs_view.asp?bbsNo=17&bbsCat=41&indx=416788&page=309

Posted by 레디37
,