2013-11-03 4 views
3

저는 델파이가 처음이고 새로운 폼을 동적으로 생성하는데 문제가 있습니다. 내가 만든 GUI의 요소 속성을 사용하여 새 양식을 만들고 싶습니다. 내가 생성자에서 다시 모든 GUI 요소를 만들 단지 캡션과 같은 요소의 일부 속성을 modificate 것이 아니라에서 위치 및 기타 속성을 유지 싶지 않는델파이 6은 생성자를 사용하여 새로운 폼을 생성합니다.

unit AddEmployeeF; 

interface 

uses 
    Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, 
    Dialogs, StdCtrls, Buttons; 

type 
    TAddEmployee = class(TForm) 
    GroupBox1: TGroupBox; 
    AddName: TLabel; 
    AddDept: TLabel; 
    AddPhone: TLabel; 
    AddExtension: TLabel; 
    AddDetails: TLabel; 
    Edit1: TEdit; 
    Edit2: TEdit; 
    Edit3: TEdit; 
    Edit4: TEdit; 
    Edit5: TEdit; 
    BitBtn1: TBitBtn; 
    BitBtn2: TBitBtn; 
    procedure CancelButtonClick(Sender: TObject); 
private 
    { Private declarations } 
    public 
    constructor CreateNew(AOwner: TComponent; Dummy: Integer = 0); override; 
    end; 
var 
    AddEmployee: TAddEmployee; 

implementation 

{$R *.dfm} 
     constructor TAddEmployee.CreateNew(AOwner: TComponent; Dummy: Integer = 0; Detail : String); 
begin 
    inherited Create(AOwner); 
    AddDetails.Caption := Detail; 
end; 


procedure TAddEmployee.CancelButtonClick(Sender: TObject); 
begin 
    self.Close; 
end; 

end. 

을 : 여기에 동적으로 생성 할 양식입니다 GUI 정의. 있을 수있다? 그리고 다른 양식에서 양식을 만드는 방법은? :

procedure TWelcome.SpeedButton1Click(Sender: TObject); 
var 
myForm :TAddEmployee; 
begin 
     myForm := TAddEmployee.CreateNew(AOwner, Dummy, Details); 

    myForm.ShowModal; 

end; 

답변

4

은 다음과 같이 생성자를 선언 :

constructor Create(AOwner: TComponent; const Detail: string); reintroduce; 

이처럼 구현 :

constructor TAddEmployee.Create(AOwner: TComponent; const Detail: string); 
begin 
    inherited Create(AOwner); 
    AddDetails.Caption := Detail; 
end; 

과 같이 호출 :

myForm := TAddEmployee.Create(MainForm, Details); 

을 잘 모르겠어요 당신이 주인이되기를 원하는 것. 주요 폼이 될 수도 있고, 뭔가 다른 것이 될 수도 있습니다.

또한 AddEmployee라는 전역 변수를 제거해야하므로 양식의 인스턴스화를 제어해야합니다.

생성자의 이름을 Create로 지정 했으므로 해당 이름의 상속 된 생성자를 숨겨서 클래스 소비자가 클래스의 인스턴스를 만들기 위해 Details 매개 변수를 제공하도록합니다.

+3

는 TCustomForm' 이미 사용자 정의'은'reintroduce' 수정하거나, 다른 사람에게로()'생성자를 만듭니다를 선언해야합니다,') (만들기 '라는 이름의 생성자가 W1010 Method 'Create'가 기본 유형 'TCustomForm'경고의 가상 메소드를 숨 깁니다. –

+0

@Remy 고마워, 나는 그것을 놓쳤다. –

6

잘못된 생성자를 대체했습니다. TForm.CreateNew() 생성자는 DFM 스트리밍을 바이 패스하므로 모든 디자인 타임 구성 요소가 런타임에 생성되지 않습니다. 더구나 재정의 된 CreateNew() 생성자가 내부에서 CreateNew()을 호출하는 상속 된 TForm.Create() 생성자를 호출하므로 런타임에 스택 오버플로 오류가 발생하는 무한 루프에 갇히게됩니다.

원하는 것을 수행하려면 TForm.Create() 생성자를 대신 덮어 쓰거나 TForm.Create()을 내부적으로 호출하는 완전히 새로운 생성자를 정의하십시오. TForm.CreateNew()을 전혀 포함하지 마십시오.

type 
    TAddEmployee = class(TForm) 
    ... 
    public 
    constructor Create(AOwner: TComponent); override; // optional 
    constructor CreateWithDetail(AOwner: TComponent; Detail : String); 
    end; 

constructor TAddEmployee.Create(AOwner: TComponent); 
begin 
    CreateWithDetail(AOwner, 'Some Default Value Here'); 
end; 

constructor TAddEmployee.CreateWithDetail(AOwner: TComponent; Detail : String); 
begin 
    inherited Create(AOwner); 
    AddDetails.Caption := Detail; 
end; 
`이후

procedure TWelcome.SpeedButton1Click(Sender: TObject); 
var 
    myForm : TAddEmployee; 
begin 
    myForm := TAddEmployee.CreateWithDetail(AOwner, Details); 
    myForm.ShowModal; 
    myForm.Free; 
end;