2009-07-04 15 views
5

come posso far funzionare il mio codice? :) ho provato a formulare questa domanda ma dopo diversi tentativi falliti penso che voi individuerete il problema più velocemente guardando il codice che leggendo le mie "spiegazioni". grazie.cast TObject usando il suo ClassType?

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; 

risposta

5

Sarebbe più facile da usare al posto di RTTI cast esplicito, vale a dire:

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

questo è * esattamente * quello che stavo cercando. Grazie! –

4

È necessario il cast dell'oggetto ct ad un TMemo/TEdit/TButton prima di poter impostare le proprietà per l'oggetto.

La riga in cui si verificano errori si sta verificando perché ct è ancora un TClass, non un TButton/etc. Se si esegue il cast su un TButton, sarà possibile abilitare true.

Consiglio di leggere su casting in Delphi. Personalmente, consiglierei di usare gli operatori as/is invece di usare ClassType. In tal caso, il codice sarà più semplice e molto più comprensibile.


Personalmente, vorrei scrivere questo più simile:

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

Devi lanciare esplicitamente oggetto da qualche classe. Questo dovrebbe funzionare:

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; 

Questo può essere abbreviato tramite operatore "is" - non c'è bisogno per la variabile ct:

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

Non dovrebbe secondo typecast in ogni caso essere "TEdit" invece di "TMemo"? – Argalatyr

+0

+0,5 per aver detto che devi eseguire cast per ogni tipo. +0.5 per l'utilizzo di "è" –

+0

Ho corretto l'errore menzionato da Argalatyr –

3

Non c'è bisogno di lanciare a TMemo e TEdit a parte, in quanto sono entrambi discendenti da classe genitore comune, che hanno proprietà 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

È possibile evitare riferimento a diverse unità e il casting esplicito se si non preoccupatevi di un piccolo successo nelle prestazioni e limitate le modifiche alle proprietà pubblicate. Dai un'occhiata all'unità TypInfo inclusa in Delphi.

Problemi correlati