Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Varios (https://www.clubdelphi.com/foros/forumdisplay.php?f=11)
-   -   Alguna sugerencia para sistema d skin? (https://www.clubdelphi.com/foros/showthread.php?t=12589)

MLROJO 21-07-2004 15:17:58

Alguna sugerencia para sistema d skin?
 
Hola.

Os comento, estoy desarrollando un sistema de skins para un programa, mediante este sistema de skin me gustaria cambiar varias imagenes del programa, cosa que consigo satisfactoriamente y también cambiar diferentes propiedades (color, color del borde...) de diferentes botones, checkbox, listbox, groupbox, etc.. los colores que deberan utilizarse se guardan en un ini.
Cada grupo de componentes (por ejemplo todos los botones), llevarian la misma variable, es decir, todos los botones irian con borde negro y color gris, y asi con todos los componentes del programa que quiera cambiar.
El problema me surge a la hora de asignar ese color a cada uno de los componentes, puesto que mi metodo, no se si es el mas correcto, pero es el único que se me ocurre.

Consiste en mostarar en un listbox todas las subcarpetas que existen dentro de \skin\ y una vez selecionada una subcarpeta cargará el ini que lleva dentro esta subcarpeta, con todas las propiedades que deben adjudicarse a los componentes. Hasta aquí todo bien, es decir, cargo bien el ini y cargo bien las imagenes.

El problema se da cuando tengo que adjudicar cada color a cada boton, puesto que son bastantes componentes (varios botones, varios checkboxs, varios radiobuttons, etc..), mi metodo para hacerlo es el siguiente:
Primero accedo al fichero ( tinifile.create(blblabblbla..) ), y a continuación:
Código:

boton1.color := fichero.readinteger('botones','color',boton1.color);
y aquí es donde se situa mi duda, ¿podria hacer algo para no tener que cargar propiedades componente por componente? supongo que si se podrá pero no se como podria hacerlo.

Espero que me puedan hechar una mano, porque la verdad que cargar uno a uno las propiedades d cada componente es algo pesado..
Si alguno sabe o se le ocurre alguna otra forma d crear skins que sean facil d cargar aunque no usen ini, o no se.. vayan de otra forma pues se lo agradeceria.

Muchas gracias de antemano.

Novás 21-07-2004 17:30:20

A mi se me ocurre que podrías establecer la propiedad tag de los botones por ejemplo a 1
Código Delphi [-]
Boton1.Tag:=1;
Boton2.tag:=1;
Esto lo harías en tiempo de diseño... Luego recorriendo la matriz de controles comprobarias se el tag coincide con el que tu le asignaste y así podrías hacer la asignación del color

Código Delphi [-]
for i:=0 to ComponentsCount-1 do
begin
  if Componets[i].Tag=1 then Components[i].Color:=fichero.readinteger('botones','color',boton1.color);

Esto yo no lo he probado, pero debería funcionar
end;

Novás 21-07-2004 17:33:00

Perdón, se me ha colado una cosilla

Código Delphi [-]
for i:=0 to ComponentsCount-1 do
  begin
    if Components[i].Tag=1 then (Components[i] as TButton).Color:=fichero.readinteger('botones','color',boton1.color);
  end;

ruina 21-07-2004 18:06:57

casi mejor que con el tag se puede hacer con el operador is para verificar la clase:

Código Delphi [-]
var i:integer;
begin
  for i:=0 To ComponentCount-1 DO
      IF Components[i] is TButton then
        with Components[i] as TButton do
        begin
            Caption:='hola';
            //...
        end
      else  if Components[i] is TCheckBox then
        with Components[i] as TCheckBox do
        begin
             Color:=clred;
             //...
        end;
end;

aunque lo realmente interesante seria verificar la propiedad 'Color' en runtime y cambiarla, para ello hay un par de funciones muy interesantes en TypInfo.pas, por ejemplo vease esta funcion que cambia el 'Color' a todos los componentes del form que tengan 'Color':

Código Delphi [-]
var pinfo:ppropinfo;
var i:integer;
begin
  for i:=0 To ComponentCount-1 DO
  begin
       pinfo:=GetPropInfo(Components[i].ClassInfo,'Color');
       if pinfo<>nil then
          SetPropValue(Components[i],'Color',clred);
  end;
end;

MLROJO 21-07-2004 18:18:12

Hola de nuevo.

Muchisimas gracias, por ahora solo he probado la opción que me ha dado Novás y me va perfecta para lo que quiero, aunque no dejaré de probar tanto las de ruina , como todas las que propongais.

Me habeis ayudado mucho.

Pues lo dicho, muchisimas gracias de nuevo, sois todo/as magnificos ;)

ruina 21-07-2004 18:45:04

bueno, enredando enredando he hecho un ejemplito que creo que es bastante parecido a lo que estabas intentando hacer:

Código Delphi [-]
procedure TForm1.BitBtn1Click(Sender: TObject);
  procedure RellenarPropiedades(NombreSeccion:string;Componente:Tcomponent);
  var k:integer;
      valor:string;
      SL:TStringList;
      pinfo:ppropinfo; // está en TypInfo
  begin
      SL:=TStringList.Create;
      try
          ini.ReadSection(NombreSeccion,SL);
          for k:=0 to SL.count-1 do
          begin
               pinfo:=GetPropInfo(Componente.ClassInfo,SL[k]);
               if pinfo<>nil then
               begin
                    valor:=ini.ReadString(NombreSeccion,SL[k],'');
                    if valor<>'' then
                      SetPropValue(Componente,SL[k],valor);
               end;
          end;
        finally
            SL.Free;
        end;
  end;
var i:integer;
begin
      for i:=0 To ComponentCount-1 DO
      begin
            RellenarPropiedades(Components[i].ClassName,Components[i]);
            RellenarPropiedades(Components[i].Name,Components[i]);
      end;
end;

y el ini seria de la forma
Código:

[TButton]
Color=1205
Caption=hola
 
[TCheckBox]
Checked=true
color=23123
 
[Memo1]
BorderStyle=bsnone
 
[Button1]
Caption=Boton Nº 1

Vease que se puede escribir las porpiedades de los componentes según su clase o su nombre concreto ^_^

ruina 21-07-2004 18:46:23

valla, a ver si apendo a escibir con porpiedad....

ruina 21-07-2004 20:25:03

bueno, tenia un ratillo libre asi que le he dado un por de vueltas de tuerca al asunto.


Bien, estabamos en que podiamos asignar propieades a las Clases o a instancias concretas por el Nombre del componente, pero...
No podiamos hacer algo tan util como:
Código:

[TLabel]
 Font.Name=MS Sans Serif

!!
afortunadamente podemos usar la función GetObjectProp, basicamente es GetOrdProp con un resultado formateado a Tobjetc

Bueno, me dejo de rollos y meto codigo (he intentado que sea lo menos criptico posible):
Código Delphi [-]
procedure TForm1.BitBtn1Click(Sender: TObject);
  procedure RellenarPropiedades(NombreSeccion:string;Componente:Tcomponent);
  var k:integer;
      valor:string;
      SL:TStringList;
      pinfo:ppropinfo; // está en TypInfo
      NombrePropiedad,NombreSubPropiedad:string; //Ej:'Font.Size'
      SubObjeto:TObject;
  begin
      SL:=TStringList.Create;
      try
          ini.ReadSection(NombreSeccion,SL);
          for k:=0 to SL.count-1 do  //recorremos la seccion entera:
          begin
               if pos('.',SL[k])>0 then
               begin
                    NombrePropiedad:=copy(SL[k],1,pos('.',SL[k])-1);
                    NombreSubPropiedad:=copy(SL[k],pos('.',SL[k])+1,length(SL[k]));
               end
               else
               begin
                    NombrePropiedad:=SL[k];
                    NombreSubPropiedad:='';
               end;
               pinfo:=GetPropInfo(Componente.ClassInfo,NombrePropiedad); //pillamos la información de la propiedad
               if pinfo<>nil then
               begin
                    Valor:=ini.ReadString(NombreSeccion,SL[K],'');
                    if Valor<>'' then
                    begin
                          if NombreSubPropiedad='' then
                             SetPropValue(Componente,NombrePropiedad,valor) //asignamos el valor
                          else
                          begin
                                SubObjeto:=GetObjectProp(Componente,pinfo.Name); // en este caso (Font.name) primero sacamos la instancia a la propiedad
                                if GetPropinfo(SubObjeto,NombreSubPropiedad)<>nil then
                                   SetPropValue(SubObjeto,NombreSubPropiedad,valor); //y asignamos el valor!!
                          end;
                    end;
               end;
          end;
        finally
            SL.Free;
        end;
  end;
var i:integer;
begin
      for i:=0 To ComponentCount-1 DO
      begin
            RellenarPropiedades(Components[i].ClassName,Components[i]);
            RellenarPropiedades(Components[i].Name,Components[i]);
      end;
      RellenarPropiedades(name,self);
end;

DarkByte 06-08-2004 15:52:08

Usar el componente http://www.torry.net/vcl/packs/inter...entpackage.zip , es gratuito ;)

edgusano 10-08-2004 01:59:32

Componente para SKIN
 
La componente que mencionan, no tiene version para Delphi 7

Sirkius 10-08-2004 08:23:02

Has probado la de Delphi 6?? El 99% de las veces funcionan sin problemas, y el 1% restante tienes que hacer unos cambios minimos.


La franja horaria es GMT +2. Ahora son las 22:30:38.

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