Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > Varios
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Grupo de Teaming del ClubDelphi

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 12-01-2014
paquechu paquechu is offline
Miembro
 
Registrado: oct 2008
Posts: 51
Poder: 16
paquechu Va por buen camino
Question Como asignar un valor a una variable global desde un componente

Hola,
Estoy intentando ver como podría asignar un valor a una variable global desde un componente gráfico de forma que la asignación se produzca desde el propio código del componente.
He intentado hacerlo con una propiedad en el propio objeto definiendola como puntero pero no encuentro la forma.
¿Se os ocurre como hacerlo?
Si es que es posible, claro.
Muchas gracias.
Saludos.
Responder Con Cita
  #2  
Antiguo 13-01-2014
Avatar de ecfisa
ecfisa ecfisa is offline
Moderador
 
Registrado: dic 2005
Ubicación: Tres Arroyos, Argentina
Posts: 10.508
Poder: 36
ecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to behold
Hola paquechu.

La verdad tu planteo me resulta confuso... me cuesta entender lo que estas intentando.

Pero si puedo decirte que salvo muuuy contadas excepciones no es aconsejable el uso de variables globales. Estas no ofrecen restricción de acceso alguno y además, una declaración con el mismo nombre dentro de un procedimiento tiene precedencia sobre ella solapándola, lo que hace muy difícil la detección de eventuales errores.

Aún así, todo se reduce a una cuestión de ámbito, si por ejemplo declaras una unidad como esta:
Código Delphi [-]
unit MiVarGlobal;

interface

var
  VarGlobal : TUnTipo;

implementation

...
end.
Y es incluida antes de la declaración del componente, este tendrá conocimiento de ella y por tanto podrá accederla, ejemplo:
Código Delphi [-]
unit MiUnidad;

interface

uses
  MiVarGlobal, Windows, Messages, SysUtils, ... ;

type
  ...

Saludos
__________________
Daniel Didriksen

Guía de estilo - Uso de las etiquetas - La otra guía de estilo ....
Responder Con Cita
  #3  
Antiguo 13-01-2014
paquechu paquechu is offline
Miembro
 
Registrado: oct 2008
Posts: 51
Poder: 16
paquechu Va por buen camino
Hola Ecfisa :-)
No va por ahí. A ver si me explico un poco mejor...
El caso es que a raíz de lo que comento en este hilo: http://www.clubdelphi.com/foros/showthread.php?t=84979
En donde planteo el problema de la lentitud a la hora de evaluar la propiedad checked del componente CheckListBox en un bucle con gran numero de iteraciones y donde se comenta como solución utilizar una variable booleana en su lugar, se me plantea el problema de actualizar esta variable booleana una vez que hago clic sobre un elemento del componente CheckListBox. Así en ese bucle de muchas iteraciones tendria que preguntar por la variable bool en lugar de por la propiedad checked con el consiguiente aumento en la velocidad de ejecución.
Todo esto es fácilmente solucionable con codigo en los eventos del CheckListBox, pero prefiero dejarlo todo integrado en un componente en la medida de lo posible; por ese motivo he creado un componente derivado de TCustomControl que contiene un objeto TCheckListBox, entre otros y es aqui donde estoy intentando vincular en una propiedad (o en algun otro sitio) esa variable booleana (que entiendo que debe ser externa al componente para que sea eficaz su uso en el bucle) al evento OnClickCheck para que la asignación se haga de forma automática y sin codigo a la vista cuando inserte el componente en el formulario correspondiente.
Espero se me entienda mejor ahora :-)
Saludos.
Responder Con Cita
  #4  
Antiguo 13-01-2014
Avatar de ecfisa
ecfisa ecfisa is offline
Moderador
 
Registrado: dic 2005
Ubicación: Tres Arroyos, Argentina
Posts: 10.508
Poder: 36
ecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to behold
Hola paquechu.

Estuve leyendo el enlace que mencionas y no veo como una sola variable te puede servir para recorrer y verificar los n items del CheckListBox... Lo que se me ocurre, es mantener un arreglo de boolean paralelo al CheckListBox y realizar las búsquedas sobre él.

Hice una prueba con 1.400.000 items y obtuve estos resultados:
Código:
Busqueda sobre el CheckListBox : 3.030.443 µs.
Busqueda sobre el arreglo      :     1.921 µs.
Claro está que el tiempo de carga aumenta un poco ya que también hay que asignar los valores al arreglo...

La prueba:
Código Delphi [-]
...
type
  TForm1 = class(TForm)
    CheckListBox1 : TCheckListBox;
    ListBox1: TListBox;
    Label1: TLabel;
    Label2: TLabel;
    btnSearchInChkLstBox: TButton;
    btnSearchInArray: TButton;
    procedure FormCreate(Sender: TObject);
    procedure CheckListBox1ClickCheck(Sender: TObject);
    procedure btnSearchInChkLstBoxClick(Sender: TObject);
    procedure btnSearchInArrayClick(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    FFreq, FIni, FEnd: Int64;
    procedure InitClock;
    function EndClock: string;
  public
  end;
...

implementation

const
  MAX = 1400000;

var
  ChkArray : array of Boolean;

procedure TForm1.InitClock;
begin
  QueryPerformanceFrequency(FFreq);
  QueryPerformanceCounter(FIni);
end;

function TForm1.EndClock: string;
begin
  QueryPerformanceCounter(FEnd);
  Result := FormatFloat('0,', (FEnd - FIni) * 1000000 div FFreq);
end;

procedure TForm1.FormCreate(Sender: TObject);
var
  i: Integer;
begin
  Randomize;
  SetLength(ChkArray, MAX);
  for i:= 0 to MAX-1 do
    with CheckListBox1 do
    begin
      Items.Add(IntToStr(i));
      Checked[i]:= Boolean(Random(2));
      ChkArray[i]:= Checked[i];
    end;
end;

procedure TForm1.CheckListBox1ClickCheck(Sender: TObject);
begin
  with CheckListBox1 do
    ChkArray[ItemIndex]:= Checked[ItemIndex];
end;

procedure TForm1.btnSearchInChkLstBoxClick(Sender: TObject);
var
  i,x : Integer;
begin
  x:= 0;
  InitClock;
  for i:= 0 to CheckListBox1.Items.Count-1 do
    if CheckListBox1.Checked[i] then
      Inc(x); // una acción
  Label1.Caption:= EndClock;
end;

procedure TForm1.btnSearchInArrayClick(Sender: TObject);
var
  i,x: Integer;
begin
  x:= 0;
  InitClock;
  for i:= Low(ChkArray) to High(ChkArray) do
    if ChkArray[i] then
      Inc(x); // una acción
  Label2.Caption:= EndClock;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  Finalize(ChkArray);
end;
end.

Saludos
__________________
Daniel Didriksen

Guía de estilo - Uso de las etiquetas - La otra guía de estilo ....
Responder Con Cita
  #5  
Antiguo 14-01-2014
paquechu paquechu is offline
Miembro
 
Registrado: oct 2008
Posts: 51
Poder: 16
paquechu Va por buen camino
Hola Ecfisa,
Eso es, creo que queda demostrado con el codigo que has puesto la diferencia de hacerlo de una forma a otra.

Por eso yo necesito usar esa variable array booleana y me gustaría realizar la asignación de los valores Checked[] hacia la variable booleana, incluyendola en el código del componente.

Pongo esta imagen a ver si queda mas claro... Mi idea era definir un tipo de propiedad en el componente, como pueda ser Color, BorderStyle o cualquier otra, que pueda contener esa variable booleana y de esta manera hacer el bucle de asignación dentro del componente, pero en una variable EXTERNA al componente.


Saludos.
Responder Con Cita
  #6  
Antiguo 15-01-2014
elrayo76 elrayo76 is offline
Miembro
 
Registrado: ene 2004
Ubicación: En la tierra, por eso mis archivos en la tierra y no en la nuebe...
Posts: 290
Poder: 21
elrayo76 Va por buen camino
Se entiende lo que quieres hacer. El problema es que no se entiende el porque de querer asignar desde dentro del componente una variable que es externa al mismo.

Lo que te aconsejo es que cargues como dijo Eficsa el array y mediante una función pública se lo asignes a la variable array externa al componente desde fuera del componente.

Por mi parte jamas he visto ni en libros ni en Internet algo como lo que tu quieres hacer. Además que pasa si no existiera esa variable en el proyecto donde usas el componente, o si esa variable tiene otro nombre porque alguien no sabia cual es el nombre que debía tener?

Además tienes un problema mas que es que la unit donde existe la variable externa al componente debe ser incluida en el componente para que se pueda acceder a la misma (a la variable). Con esto esa unit pasaría a formar parte del componente.

Saludos,
El Rayo
__________________
Si tienes una función o procedimiento con diez parámetros, probablemente hayas olvidado uno
Responder Con Cita
  #7  
Antiguo 15-01-2014
paquechu paquechu is offline
Miembro
 
Registrado: oct 2008
Posts: 51
Poder: 16
paquechu Va por buen camino
Hola Elrayo76,
El porqué quiero hacerlo como he comentado es por reducir el código visible en el proyecto, dejando a la vista el código más "importante". Esta tarea de asignar una serie de valores a un array la entiendo como secundaria y si ya la tiene implementada el componente responsable de este comportamiento, pues mejor. A la hora de revisar el resto del código del proyecto todo me sería más fácil (esto es simplemente la forma de trabajar que prefiero, pero vamos, para gustos los colores.... :-) )

Ayer por la noche vi como hacer lo que quería (no del todo, pero de una forma bastante aproximada). Se trata de utilizar la propiedad tag del componente como almacen para la dirección de memoria de la variable externa, y de esta forma que he visto no aplican los problemas que me comentas.

El procedimiento es tal que así:

Código Delphi [-]
Type
   TArrayB = array of bool;
   PTArrayB = ^TArrayB;

En el OnCreate del formulario principal introduzco esta línea de código:

Código Delphi [-]
SetLength(bBooleana,7); // Yo lo hago asi porque me interesa más pero si el array no es dinámico no sería necesaria esta línea
cComponente.Tag:=NativeInt(@bBooleana);   // En la propiedad tag del componente se guarda la dirección de la variable
Esto es todo el código que hay que poner fuera del componente.

En el componente:

Código Delphi [-]
Type
   TArrayB = array of bool;
   PTArrayB = ^TArrayB;
En la sección public

Código Delphi [-]
B: ^TArrayB;

Dentro de la funcion para hacer la asignación de la propiedad checked del CheckListBox a la variable externa primero pregunto por el valor de Tag (que lo inicializo a 0 en la creacion del componente) y si es <>0 entonces hago referencia a B como sigue:

Código Delphi [-]
If Tag<>0 then B:=@PTArrayB(Self.Tag)^;

Y luego en el bucle y con la variable i como índice:

Código Delphi [-]
B^[i] := CheckListBox1.Checked[i];

Así me funciona, lo pongo por si a alguien se le ha ocurrido alguna cosa igual de rara que esta :-)
Un saludo y gracias por vuestra participación
Paco
Responder Con Cita
Respuesta



Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
Asignar el valor de una variable de php a una variable js que puede no existir jandroruiz PHP 5 04-03-2013 12:23:02
Problema con valor en variable global judit25 Conexión con bases de datos 2 06-07-2006 01:16:59
Asignar el valor de DayOfTheWeek a una variable gluglu Varios 7 23-01-2005 19:47:47
Asignar valor ComboBox a una variable gluglu Varios 6 11-10-2004 17:54:44
como asignar un valor a una variable juan Varios 6 18-06-2003 01:26:19


La franja horaria es GMT +2. Ahora son las 07:03:32.


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
Copyright 1996-2007 Club Delphi