2012-09-26 42 views
6

MainForm tạo một số đối tượng Khung phụ trong thời gian chạy để hiển thị các bảng tùy chọn khác nhau.Sự khác biệt trong việc khởi tạo biểu mẫu giữa Delphi và Lazarus?

Dưới đây là một constructor điển hình cho một trong những lớp khung (họ từng mở rộng TFrame):

constructor Tframe2.Create(AOwner: TComponent); 
begin 
    inherited; 
    edTime.Text := '12:00pm'; //edTime is a TEdit control. this line is where it throws the exception 
    //etc. 
end; 

Mã này làm việc tốt trong Delphi (có hay không nó là đúng cách để làm những việc), nhưng cùng một mã trong Lazarus giữ ném một ngoại lệ EInvalidOperation, bởi vì kiểm soát (TEdit) không có cha mẹ "cửa sổ" được giao (rsControlHasNoParentWindow), mà thực sự loại có ý nghĩa khi tôi kiểm tra mã vì cha mẹ dường như không được giao cho đến sau khi hàm tạo được gọi.

Đây là mã trong MainForm sẽ khởi khung thứ:

if Assigned(frame) then FreeAndNil(frame); 
case Node.AbsoluteIndex of 
    optInterval: frame := Tframe2.Create(Self); //here's where the constructor gets called. 
    //etc 
end; 
frame := TframeOther.Create(Self); 
if Assigned(frame) then 
begin 
    frame.Parent := panOptions; //here's where Tframe2's parent gets set 
    frame.Align := alClient; 
end; 

Vì vậy, bất cứ ai có thể giải thích cho dù có bất kỳ sự khác biệt quan trọng giữa Delphi và Lazarus như xa như chuỗi thức khởi tạo?

Và cách tiêu chuẩn nhất để giải quyết loại sự cố khởi tạo đơn hàng này sẽ là gì? So với các ngôn ngữ khác tôi quen thuộc hơn, có thể có các chiến lược khác nhau để giải quyết các lỗi như vậy. Tôi có thể thêm một tham số khác vào constructor, hoặc nếu có method được gọi là post constructor trước khi vẽ nó trên màn hình mà tôi có thể ghi đè tôi có thể định vị lại mã đó, hoặc chỉ cần thực hiện một phương thức trợ giúp và gọi nó sau khi setParent được gọi. Bất kỳ thực hành tốt nhất nào ở đây?

Chỉnh sửa]: Có vẻ như điều này có thể dành riêng cho TEdit theo một cách nào đó. Có vẻ như các dòng khởi tạo trạng thái cho các hộp kiểm không có cùng vấn đề. Có thể đây chỉ là một lỗi trong Lazarus?

+0

Tôi không biết điều đó có khắc phục được sự cố hay không, nhưng hãy đặt kế thừa Tạo (AOwner); trong quy trình tạo. – Ravaut123

+0

Hãy thử mã đơn giản * TEdit.Create (nil) .Text: = '12345' *; Mã này tạo ra ít chỉnh sửa cha mẹ và gán một số chú thích cho nó. Nếu công việc này trong VCL nhưng không phải trong LCL - thì đó chính xác có nghĩa là họ có wrt khác nhau có cha mẹ. Cũng lưu ý rằng LCL chỉ là một trình bao bọc đối với một số thư viện bộ công cụ. Có LCL trên GTK +, LCL trên Qt và ai biết điều gì khác. Có lẽ bạn có thể chuyển chương trình phụ trợ LCL sang một thư viện khác và sửa nó. Hoặc có thể không. –

+0

Tôi đã cho nó một shot, nhưng tôi không thể lặp lại vấn đề này (lazarus 0.9.30.4). –

Trả lời

1

Sau khi thử nghiệm thêm, tôi đã có thể giải quyết hầu hết các vấn đề tức thời của nó bị lỗi bằng cách thêm một dòng để đặt cha mẹ của TEdit thành Frame (so với cài đặt cha mẹ của Frame). Cũng giống như vậy:

edTime.Parent := Self; 
edTime.Text := '12:00'; 

Nhưng tôi vẫn rất muốn hiểu rõ hơn về lý do tại sao này là "đôi khi" cần thiết.

chỉnh sửa: trong khi bản sửa lỗi này có thể đặt văn bản trên TEdit, điều này không khắc phục mã tự động mà tôi lặp lại thông qua các thành phần và thay đổi kích thước bất kỳ điều gì xảy ra là hộp kiểm. Rõ ràng hình thức không có bộ cha mẹ của nó vẫn là "loại" một vấn đề.

edit2: Thêm tham số thứ hai vào hàm tạo và đặt cha mẹ cho toàn bộ biểu mẫu trong hàm tạo dường như không cần thiết đặt Parent cho TEdit hoàn toàn.

+2

Điều này hầu như luôn luôn được yêu cầu khi bạn tạo một điều khiển trực quan (như 'TEdit'). Nó có nội dung trực quan, vì vậy nó cần một nơi nào đó để vẽ nội dung đó, và đó là trên 'Parent.Canvas'. Phương thức streaming DFM thực hiện điều này một cách tự động (và bạn có thể thấy 'lineage' hoặc' thứ tự cha' của các điều khiển con trong Structure View hoặc bằng cách xem DFM dưới dạng văn bản và quan sát mức thụt lề). Khi bạn tạo điều khiển trong mã trong thời gian chạy, bạn phải tự làm điều đó (như bạn đã khám phá ra). –