2009-07-04 8 views
5

Tôi làm cách nào để mã của mình hoạt động? :) Tôi đã cố gắng để xây dựng câu hỏi này nhưng sau khi một số nỗ lực không thành công tôi nghĩ rằng các bạn sẽ phát hiện ra vấn đề nhanh hơn khi nhìn vào mã hơn đọc 'giải thích' của tôi. cảm ơn bạn.cast TObject sử dụng ClassType của mình?

setCtrlState([ memo1, edit1, button1], False); 

_

procedure setCtrlState(objs: array of TObject; bState: boolean = True); 
var 
    obj: TObject; 
    ct: TClass; 
begin 
    for obj in objs do 
    begin 
    ct := obj.ClassType; 


    if (ct = TMemo) or (ct = TEdit) then 
     ct(obj).ReadOnly := not bState;  // error here :(

    if ct = TButton then 
     ct(obj).Enabled:= bState;  // and here :(

    end; 
end; 

Trả lời

5

Nó sẽ được dễ dàng hơn để sử dụng RTTI thay vì đúc rõ ràng, ví dụ:

uses 
    TypInfo; 

setCtrlState([ memo1, edit1, button1], False); 

procedure setCtrlState(objs: array of TObject; bState: boolean = True); 
var 
    obj: TObject; 
    PropInfo: PPropInfo; 
begin 
    for obj in objs do 
    begin 
    PropInfo := GetPropInfo(obj, 'ReadOnly'); 
    if PropInfo <> nil then SetOrdProp(obj, PropInfo, not bState); 

    PropInfo := GetPropInfo(obj, 'Enabled'); 
    if PropInfo <> nil then SetOrdProp(obj, PropInfo, bState); 
    end; 
end; 
+0

đây là * chính xác * những gì tôi đang tìm kiếm. Cảm ơn bạn! –

4

Bạn cần phải cast đối tượng ct đến một TMemo/TEdit/TButton trước khi bạn có thể thiết lập các thuộc tính trên các đối tượng.

Dòng mà bạn gặp phải lỗi là do lỗi ct vẫn là một TClass, không phải là TButton/etc. Nếu bạn truyền sang một TButton, thì bạn sẽ có thể đặt được bật thành true.

Tôi khuyên bạn nên đọc trên casting in Delphi. Cá nhân, tôi khuyên bạn nên sử dụng các toán tử as/is thay vì sử dụng ClassType. Mã sẽ đơn giản hơn trong trường hợp đó và dễ hiểu hơn nhiều.


Cá nhân, tôi sẽ viết này giống như:

procedure setCtrlState(objs: array of TObject; bState: boolean = True); 
var 
    obj: TObject; 
begin 
    for obj in objs do 
    begin 
    // I believe these could be merged by using an ancestor of TMemo+TEdit (TControl?) 
    // but I don't have a good delphi reference handy 
    if (obj is TMemo) then 
     TMemo(obj).ReadOnly := not bState; 

    if (obj is TEdit) then 
     TEdit(obj).ReadOnly := not bState; 

    if (obj is TButton) then 
     TButton(obj).Enabled := bState; 
    end; 
end; 
7

Bạn phải đúc một cách rõ ràng đối tượng để một số lớp. này nên làm việc:

procedure setCtrlState(objs: array of TObject; bState: boolean = True); 
var 
    obj: TObject; 
    ct: TClass; 
begin 
    for obj in objs do 
    begin 
    ct := obj.ClassType; 

    if ct = TMemo then 
     TMemo(obj).ReadOnly := not bState 
    else if ct = TEdit then 
     TEdit(obj).ReadOnly := not bState 
    else if ct = TButton then 
     TButton(obj).Enabled := bState; 
    end; 
end; 

Điều này có thể được rút ngắn sử dụng "is" điều hành - không cần ct biến:

procedure setCtrlState(objs: array of TObject; bState: boolean = True); 
var 
    obj: TObject; 
begin 
    for obj in objs do 
    begin 
    if obj is TMemo then 
     TMemo(obj).ReadOnly := not bState 
    else if obj is TEdit then 
     TEdit(obj).ReadOnly := not bState 
    else if obj is TButton then 
     TButton(obj).Enabled := bState; 
    end; 
end; 
+0

nên không thứ hai định kiểu trong mỗi trường hợp là "TEdit" thay vì "TMemo"? – Argalatyr

+0

+0.5 để nói rằng bạn phải thực hiện phôi cho từng loại. +0.5 để sử dụng "là" –

+0

tôi đã sửa lỗi đánh máy được đề cập bởi Argalatyr –

3

Không cần để cast để TMemo và TEdit riêng biệt, vì họ là cả hai hậu duệ từ lớp cha mẹ chung, có thuộc tính ReadOnly:

procedure TForm1.FormCreate(Sender: TObject); 

    procedure P(const Obj: TComponent); 
    begin 
    if Obj is TCustomEdit then 
     TCustomEdit(Obj).ReadOnly := True; 
    end; 

begin 
    P(Memo1); 
    P(Edit1); 
end; 
2

Bạn có thể tránh tham chiếu các đơn vị khác nhau và truyền rõ ràng nếu bạn đừng bận tâm đến việc đạt hiệu suất nhỏ và giới hạn các thay đổi đối với các thuộc tính đã xuất bản. Hãy xem xét đơn vị TypInfo đi kèm với Delphi.