Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   OOP (https://www.clubdelphi.com/foros/forumdisplay.php?f=5)
-   -   Bloquear Edits (https://www.clubdelphi.com/foros/showthread.php?t=93817)

oscarac 19-03-2019 16:51:58

Bloquear Edits
 
buenos dias
tengo esta rutina para bloquear edit dentro de un formulario

Código Delphi [-]
Procedure BloquearEdits (Form :TForm);
Var i :Integer;
Begin
   for i := 0 to (Form.ComponentCount - 1) do
    begin
     if (Form.Components[i] is TDBEdit) then
         TEdit(Form.Components[i]).Enabled := False;
     end;
end;

la pregunta es...
como bloquear otros componentes que no sean edit, como por ejemplo datetimepicker que pregunta debe ir en el if ???
como identifico "el origen" del componente ?

Caminante 19-03-2019 17:30:37

Hola


Puedes cambiar la comprobacion de TEdit a Twincontrol.


Saludos

bucanero 19-03-2019 17:39:49

hola

El tema es que la herencia en un TDateTimePicker es asi:

Código:

  TDateTimePicker = class(TCommonCalendar) -->  TCommonCalendar = class(TWinControl)
q
y salvo el TWinControl no tiene nada mas en común con respecto a los TEdit / TDBEdit
Código:

 
  TEdit = class(TCustomEdit) -->  TCustomEdit = class(TWinControl)
 
  TDBEdit = class(TCustomMaskEdit) -->  TCustomMaskEdit = class(TCustomEdit)  -->  TCustomEdit = class(TWinControl)

Una idea como te ha sugerido caminante es preguntar por TWinControl, lo que pasa que si tienes otros componentes que hereden de TWinControl en el form y seguramente si (botones, grids, etc) puedes terminar desabilitando mas de los que realmente te interesan.

Otra opción es buscar solamente los que quieres desabilitar:

Código Delphi [-]
procedure BloquearEdits(Form: TForm);
var
  i: Integer;
begin
  for i := 0 to (Form.ComponentCount - 1) do begin
    if (Form.Components[i] is TCustomEdit) then
      TCustomEdit(Form.Components[i]).Enabled := False
    else if (Form.Components[i] is TDateTimePicker) then
      TDateTimePicker(Form.Components[i]).Enabled := False;
  end;
end;

ecfisa 19-03-2019 17:43:41

Hola Oscar.

Fijate si te sirve de este modo:
Código Delphi [-]
procedure ControlsOn(AForm: TForm; const Active: Boolean);
var
  i: Integer;
begin
  for i := AForm.ControlCount-1 downto 0 do
    AForm.Controls[i].Enabled := Active;
end;

Ej. de uso:
Código Delphi [-]
begin
  ControlsOn(Form1, False);

Saludos :)

oscarac 19-03-2019 18:00:34

Cita:

Empezado por ecfisa (Mensaje 531138)
Hola Oscar.

Fijate si te sirve de este modo:
Código Delphi [-]
procedure ControlsOn(AForm: TForm; const Active: Boolean);
var
  i: Integer;
begin
  for i := AForm.ControlCount-1 downto 0 do
    AForm.Controls[i].Enabled := Active;
end;

Ej. de uso:
Código Delphi [-]
begin
  ControlsOn(Form1, False);

Saludos :)

interesante tu ejemplo pero me bloquea absolutamente todo y quiero que los botones de "Eliminar" y "Cancelar" queden activos

oscarac 19-03-2019 18:05:15

Cita:

Empezado por bucanero (Mensaje 531136)
hola

El tema es que la herencia en un TDateTimePicker es asi:

Código:

  TDateTimePicker = class(TCommonCalendar) -->  TCommonCalendar = class(TWinControl)
q
y salvo el TWinControl no tiene nada mas en común con respecto a los TEdit / TDBEdit
Código:

 
  TEdit = class(TCustomEdit) -->  TCustomEdit = class(TWinControl)
 
  TDBEdit = class(TCustomMaskEdit) -->  TCustomMaskEdit = class(TCustomEdit)  -->  TCustomEdit = class(TWinControl)

Una idea como te ha sugerido caminante es preguntar por TWinControl, lo que pasa que si tienes otros componentes que hereden de TWinControl en el form y seguramente si (botones, grids, etc) puedes terminar desabilitando mas de los que realmente te interesan.

Otra opción es buscar solamente los que quieres desabilitar:

Código Delphi [-]
procedure BloquearEdits(Form: TForm);
var
  i: Integer;
begin
  for i := 0 to (Form.ComponentCount - 1) do begin
    if (Form.Components[i] is TCustomEdit) then
      TCustomEdit(Form.Components[i]).Enabled := False
    else if (Form.Components[i] is TDateTimePicker) then
      TDateTimePicker(Form.Components[i]).Enabled := False;
  end;
end;



respecto a este ejemplo me aperece este mensaje de error

Cita:

[dcc32 Error] Librerias_u.pas(264): E2015 Operator not applicable to this operand type

la pregunta es, como saber que tipo de componente es el componente actual (de la lista de componentes en el form), para saber si lo deshabilito o no

ecfisa 19-03-2019 18:54:30

Hola de nuevo.
Cita:

Empezado por oscarac (Mensaje 531139)
interesante tu ejemplo pero me bloquea absolutamente todo y quiero que los botones de "Eliminar" y "Cancelar" queden activos

Entiendo...

Para el control actual podrías usar:
Código Delphi [-]
 
procedure ControlsOn(AForm: TForm; const Active: Boolean);
var
  i: Integer;
begin
  for i := AForm.ControlCount-1 downto 0 do
    if AForm.Controls[i] <> AForm.ActiveControl then
       AForm.Controls[i].Enabled := False;
end;

Pero, al tener que mantener activo mas de un botón ('Cancelar' y 'Eliminar'), seguramente te sirva de este modo:
Código Delphi [-]
type
  TControlExt = class(TControl);

procedure ControlsOn(AForm: TForm; const Active: Boolean);
var
  i: Integer;
  C: TControlExt;
begin
  for i := AForm.ControlCount-1 downto 0 do
  begin
    C := TControlExt(AForm.Controls[i]);
    C.Enabled := TControl(C) is TButton and((C.Caption = 'Cancelar') or (C.Caption = 'Eliminar'));
  end;
end;

Saludos :)

oscarac 19-03-2019 20:33:59

Como llevo cierto orden al nombrar los controles lo solucione de esta manera

Código Delphi [-]
Procedure BloquearEdits (Form :TForm);
Var i :Integer;
_name : string;
Begin
  for i := 0 to (Form.ComponentCount - 1) do
  begin
    _name := Form.Components[i].Name;
    if (Form.Components[i] is TCustomEdit) then
      TCustomEdit(Form.Components[i]).Enabled := False;

    if _en('dtp', _name) then   // procedimiento que busca una cadena en otra
      TWinControl(Form.Components[i]).Enabled := False
  end;
end;

Neftali [Germán.Estévez] 20-03-2019 11:27:53

Otra opción es parametrizar las clases que quieres deshabilitar. Eso sí, deben ser todos los de las clases especificadas. Con esta opción no puedes escoger unos TEdit si y otros no.
Algo así:

Código Delphi [-]
Procedure BloquearComponentes (Form :TForm; arrayClass:array of TComponentClass);
Var
  i :Integer;
  c:TComponentClass;
Begin
  for i := 0 to (Form.ComponentCount - 1) do  begin
    for c in arrayClass do begin
      if (Form.Components[i] is c) then begin
         TWinControl(Form.Components[i]).Enabled := False;
      end;
    end;
  end;
end;

De forma que puedes llamarlo así:

Código Delphi [-]
// Para deshabilitar TEdit y descendientes
BloquearComponentes(Self, [TEdit]);
// Para deshabilitar TEdit, TCheckbox y descendientes...
BloquearComponentes(Self, [TEdit, TCheckbox]);
// ... y así sucesivamente
BloquearComponentes(Self, [TEdit, TCheckbox, TDateTimePicker]);

roman 20-03-2019 14:46:54

También, dependiendo de cómo se organice ell formulario, se pueden poner los controles que se deshabiltan dentro de un contenedor común (Panel o Groupbox p. ej.) y deshabilitar el contenedor.

// Saludos

oscarac 20-03-2019 15:14:20

Cita:

Empezado por Neftali [Germán.Estévez] (Mensaje 531158)
Otra opción es parametrizar las clases que quieres deshabilitar. Eso sí, deben ser todos los de las clases especificadas. Con esta opción no puedes escoger unos TEdit si y otros no.
Algo así:

Código Delphi [-]
Procedure BloquearComponentes (Form :TForm; arrayClass:array of TComponentClass);
Var
  i :Integer;
  c:TComponentClass;
Begin
  for i := 0 to (Form.ComponentCount - 1) do  begin
    for c in arrayClass do begin
      if (Form.Components[i] is c) then begin
         TWinControl(Form.Components[i]).Enabled := False;
      end;
    end;
  end;
end;

De forma que puedes llamarlo así:

Código Delphi [-]
// Para deshabilitar TEdit y descendientes
BloquearComponentes(Self, [TEdit]);
// Para deshabilitar TEdit, TCheckbox y descendientes...
BloquearComponentes(Self, [TEdit, TCheckbox]);
// ... y así sucesivamente
BloquearComponentes(Self, [TEdit, TCheckbox, TDateTimePicker]);



Esta me parece una solucion muy interesante, puesto que yo tendria el control de lo que quiero deshabilitar
muchas gracias

cloayza 20-03-2019 19:47:21

Amigo otro opción es hacer uso de las RTTI...Hace unos años recopile unos procedimientos para realizar esta tarea en un desarrollo.

Te adjunto la unidad y un ejemplo. Espero te ayude.

Es solo otra opción de realizar lo que requieres...

Código Delphi [-]
{
Funciones y procedimientos para accesar objetos a traves de la RTTI.

Christian Loayza
Abril/2012


String   := GetEnumName(TypeInfo(TFieldType),  Integer(ftString));
DataType := TFieldType(GetEnumValue(TypeInfo(TFieldType),'ftString')) ;

}
unit CLRtti;

interface
uses Classes, TypInfo, SysUtils;

function CreateAClass(const AClassName: string): TObject;
function ClonarPropiedades( Origen, Destino: TObject; APropiedades: array of string ): Boolean;
function DesignNameIsUnique(AOwner: TComponent; const AName: string): Boolean;
function DesignUniqueName(AOwner: TComponent; const AClassName: string): string;

procedure SetIntegerProperty(AComp: TComponent; APropName: String; AValue: Integer);
procedure SetFloatProperty(AComp: TComponent; APropName: String; AValue: Double);
procedure SetObjectProperty(AComponent: TComponent; APropName: String; AValue: TObject);

procedure SetBooleanProperty(AComp: TComponent     ;APropName: String; AValue: Boolean);overload;
procedure SetBooleanProperty(AComp:Array of TObject;APropName:string; AValue:Boolean);overload;
procedure SetBooleanProperty(AComp:Array of TObject;APropName:string; AValue:Array Of Boolean);overload;

procedure SetStringProperty(AComp: TComponent; APropName: String; AValue: String);
procedure SetMethodProperty(AComp: TComponent; APropName: String; AMethod: TMethod);

function GetIntegerProperty(AComp: TComponent; APropName:String): Integer;
function GetFloatProperty(AComp: TComponent; APropName:String): Double;
function GetObjectProperty(AComponent: TComponent; APropName:String): TObject;
function GetBooleanProperty(AComp: TComponent; APropName:String):Boolean;
Function GetStringProperty(AComp: TComponent; APropName:String):String;
//function GetEnumerationProperty(AComp:TComponent; APropName:string):Integer;
function GetMethodProperty(AComp: TComponent; APropName:String):TMethod;

function ExistProperty(AComp: TComponent; APropName: String):Boolean;

implementation


function CreateAClass(const AClassName: string): TObject;
var
  C : TComponentClass;
  SomeObject: TObject;
begin
     C         := TComponentClass(FindClass(AClassName));
     SomeObject := C.Create(nil);
     Result     := SomeObject;
end;

function ClonarPropiedades( Origen, Destino: TObject; APropiedades: array of string ): Boolean;
var
  i: Integer;
begin
     Result := True;
     try
       for i := Low( APropiedades ) to High( APropiedades ) do
       begin
         // ¿Existe la propiedad en el control origen?
         if not IsPublishedProp( Origen, APropiedades[i] ) then
           Continue;

         // ¿Existe la propiedad en el control destino?
         if not IsPublishedProp( Destino, APropiedades[i] ) then
           Continue;

         // ¿Son del mismo tipo las dos propiedades?
         if PropType( Origen, APropiedades[i]) <>
           PropType( Destino, APropiedades[i] ) then
           Continue;

         // Copiamos la propiedad según si es variable o método
         case PropType(Origen, APropiedades[i]) of
           tkClass:
             SetObjectProp( Destino, APropiedades[i],
               GetObjectProp( Origen, APropiedades[i] ) );

           tkMethod:
             SetMethodProp( Destino, APropiedades[i],
                            GetMethodProp( Origen, APropiedades[i] ) );
           else
             SetPropValue( Destino, APropiedades[i],
                           GetPropValue( Origen, APropiedades[i] ) );
         end;
       end;
     except
       Result := False;
     end;
end;

function DesignNameIsUnique(AOwner: TComponent; const AName: string): Boolean;
begin
     Result := True;
     while Result and (AOwner <> nil) do
     begin
       Result := AOwner.FindComponent(AName) = nil;
       AOwner := AOwner.Owner;
     end;
end;

function DesignUniqueName(AOwner: TComponent; const AClassName: string): string;
var
  Base: string;
  I: Integer;
begin
     Base := Copy(AClassName, 2, MAXINT);
     I := 0;
     repeat
       Inc(I);
       Result := Base + IntToStr(I);
     until DesignNameIsUnique(AOwner, Result);
end;

function ExistProperty(AComp: TComponent; APropName: String):Boolean;
var
  PropInfo: PPropInfo;
begin
     PropInfo := GetPropInfo(AComp.ClassInfo, APropName);
     Result:=Assigned(PropInfo);
end;

procedure SetIntegerProperty(AComp: TComponent; APropName: String; AValue: Integer);
var
  PropInfo: PPropInfo;
begin
     PropInfo := GetPropInfo(AComp.ClassInfo, APropName);
     if PropInfo <> nil then
     begin
       if PropInfo^.PropType^.Kind = tkInteger then
         SetOrdProp(AComp, PropInfo, AValue);
     end;
end;

function GetIntegerProperty(AComp: TComponent; APropName:String): Integer;
var
  PropInfo: PPropInfo;
begin
     PropInfo := GetPropInfo(AComp.ClassInfo, APropName);
     if PropInfo <> nil then
     begin
          if PropInfo^.PropType^.Kind = tkInteger then
             Result:=GetOrdProp(AComp, PropInfo)
          else If PropInfo^.PropType^.Kind = tkEnumeration then
              Result:=GetEnumValue(PropInfo^.PropType^, PropInfo^.PropType^.Name);

     end;
end;

function GetFloatProperty(AComp: TComponent; APropName:String): Double;
var
  PropInfo: PPropInfo;
begin
     PropInfo := GetPropInfo(AComp.ClassInfo, APropName);
     if PropInfo <> nil then
     begin
          if PropInfo^.PropType^.Kind = tkFloat then
             Result:=GetFloatProp(AComp, PropInfo);
     end;
end;

procedure SetFloatProperty(AComp: TComponent; APropName: String; AValue: Double);
var
  PropInfo: PPropInfo;
begin
     PropInfo := GetPropInfo(AComp.ClassInfo, APropName);
     if PropInfo <> nil then
     begin
          if PropInfo^.PropType^.Kind = tkFloat then
             SetFloatProp(AComp, PropInfo, AValue);
     end;
end;

procedure SetObjectProperty(AComponent: TComponent; APropName: String; AValue: TObject);
var
  PropInfo: PPropInfo;
begin
     PropInfo := GetPropInfo(AComponent.ClassInfo, APropName);
     if PropInfo <> nil then
     begin
          if PropInfo^.PropType^.Kind = tkClass then
            SetObjectProp(AComponent, PropInfo, AValue);
     end;
end;

function GetObjectProperty(AComponent: TComponent; APropName:String): TObject;
var
  PropInfo: PPropInfo;
begin
     Result:=Nil;
     PropInfo := GetPropInfo(AComponent.ClassInfo, APropName);
     if PropInfo <> nil then
     begin
          if PropInfo^.PropType^.Kind = tkClass then
             Result:=GetObjectProp(AComponent, PropInfo);
     end;
end;

procedure SetBooleanProperty(AComp: TComponent; APropName: String; AValue: Boolean);
var
  PropInfo: PPropInfo;
begin
     PropInfo := GetPropInfo(AComp.ClassInfo, APropName);
     if PropInfo <> nil then
     begin
          if PropInfo^.PropType^.Kind = tkEnumeration then
            SetOrdProp(AComp, PropInfo, Integer(AValue));
     end;
end;

procedure SetBooleanProperty(AComp:Array of TObject; APropName:string; AValue:Boolean);
Var
     i:Integer;
begin
     For i:=Low(AComp) To High(AComp) Do
         SetBooleanProperty(TComponent(AComp[i]), APropName, AValue);
end;

procedure SetBooleanProperty(AComp:Array of TObject;APropName:string; AValue:Array Of Boolean);
Var
   i:Integer;
begin
     For i:=Low(AComp) To High(AComp) Do
         SetBooleanProperty(TComponent(AComp[i]), APropName, AValue[i]);
end;

function GetBooleanProperty(AComp: TComponent; APropName:String):Boolean;
var
  PropInfo: PPropInfo;
begin
     Result:=False;
     PropInfo := GetPropInfo(AComp.ClassInfo, APropName);
     if PropInfo <> nil then
     begin
          if PropInfo^.PropType^.Kind = tkEnumeration then
             Result:=Boolean(GetOrdProp(AComp, PropInfo));
     end;
end;


procedure SetStringProperty(AComp: TComponent; APropName: String; AValue: String);
var
  PropInfo: PPropInfo;
begin
     PropInfo := GetPropInfo(AComp.ClassInfo, APropName);
     if PropInfo <> nil then
     begin
          if (PropInfo^.PropType^.Kind in [tkString, tkLString, tkWString]) then
             SetStrProp(AComp, PropInfo, AValue);
     end;
end;

Function GetStringProperty(AComp: TComponent; APropName:String):String;
var
  PropInfo: PPropInfo;
begin
     Result:='';
     PropInfo := GetPropInfo(AComp.ClassInfo, APropName);
     if PropInfo <> nil then
     begin
       if (PropInfo^.PropType^.Kind in [tkString, tkLString, tkWString, tkUString]) then
         Result:=GetStrProp(AComp, PropInfo);
     end;
end;


{Function GetEnumerationProperty(AComp: TComponent; APropName:String):Integer;
var
  PropInfo: PPropInfo;
begin
     PropInfo := GetPropInfo(AComp.ClassInfo, APropName);
     if PropInfo <> nil then
     begin
       if (PropInfo^.PropType^.Kind in [tkString, tkLString, tkWString, tkUString]) then
         Result:=GetStrProp(AComp, PropInfo);
     end;
end;
}
procedure SetMethodProperty(AComp: TComponent; APropName: String; AMethod: TMethod);
var
  PropInfo: PPropInfo;
begin
     PropInfo := GetPropInfo(AComp.ClassInfo, APropName);
     if PropInfo <> nil then
     begin
          if PropInfo^.PropType^.Kind = tkMethod then
             SetMethodProp(AComp, PropInfo, AMethod);
     end;
end;

function GetMethodProperty(AComp: TComponent; APropName:String):TMethod;
var
  PropInfo: PPropInfo;
begin
     Result.Code:=NIL;
     Result.Data:=NIL;
     PropInfo := GetPropInfo(AComp.ClassInfo, APropName);
     if PropInfo <> nil then
     begin
          if PropInfo^.PropType^.Kind = tkMethod then
             Result:=GetMethodProp(AComp, PropInfo);
     end;
end;
end.

Ejemplo: Un formulario y varios componentes...
Código Delphi [-]
unit Unit4;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils,
  System.Variants,
  System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;

type
  TForm4 = class(TForm)
    Edit1: TEdit;
    Edit2: TEdit;
    Label1: TLabel;
    Memo1: TMemo;
    Button1: TButton;
    CheckBox1: TCheckBox;
    ListBox1: TListBox;
    Button2: TButton;
    Button3: TButton;
    procedure Button2Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form4: TForm4;

implementation
uses CLRtti;

{$R *.dfm}

procedure TForm4.Button2Click(Sender: TObject);
begin
       CLRtti.SetBooleanProperty([Edit1, Edit2, Label1,
                                Memo1, Button1,
                                CheckBox1,
                                ListBox1],'Enabled',true);
end;

procedure TForm4.Button3Click(Sender: TObject);
begin
     CLRtti.SetBooleanProperty([Edit1, Edit2, Label1,
                                Memo1, Button1,
                                CheckBox1, ListBox1], 'Enabled',false);

end;

end.

Saludos cordiales

oscarac 20-03-2019 20:51:25

interesante, lo tendré en cuenta gracias


La franja horaria es GMT +2. Ahora son las 16:08:48.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi