2009-07-04 3 views
5

comment puis-je faire mon code pour travailler? :) J'ai essayé de formuler cette question, mais après plusieurs tentatives infructueuses, je pense que vous verrez le problème plus rapidement en regardant le code que de lire mes «explications». Je vous remercie.cast TObject utilisant son 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; 

Répondre

5

Il serait plus facile d'utiliser RTTI au lieu de coulée explicite, à savoir:

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

c'est * exactement * ce que je cherchais. Je vous remercie! –

4

Vous devez jeter l'objet ct à un TMemo/TEdit/TButton avant de pouvoir définir les propriétés de l'objet.

La ligne sur laquelle vous obtenez des erreurs est erronée car ct est toujours un TClass, pas un TButton/etc. Si vous lancez un TButton, vous pourrez activer true. Je recommande de lire sur le casting in Delphi. Personnellement, je recommanderais d'utiliser les opérateurs as/is au lieu d'utiliser ClassType. Le code sera plus simple dans ce cas, et beaucoup plus compréhensible.


Personnellement, je voudrais écrire ce plus comme:

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

Vous devez explicitement jeter objet à une classe. Cela devrait fonctionner:

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; 

Cela peut être raccourci en utilisant « is » opérateur - pas besoin de variable 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

ne devrait-deuxième Typecast dans chaque cas « TEdit » au lieu de « TMemo »? – Argalatyr

+0

+0.5 pour dire que vous devez effectuer des castings pour chaque type. +0.5 pour l'utilisation de "est" –

+0

J'ai corrigé la faute de frappe mentionnée par Argalatyr –

3

Il n'y a pas besoin de jeter à TMemo et TEdit séparément, car ils sont les deux descendants de la classe parente commune, qui ont la propriété 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

Vous pouvez éviter de référencer différentes unités et le casting explicite si vous ne vous occupez pas d'un petit succès de performance et limitez les changements aux propriétés publiées. Jetez un oeil à l'unité TypInfo incluse avec Delphi.

Questions connexes