Está en la página 1de 7

SISTEMA DE PLUGINS EN DELPHI (Parte I)

Germn Estvez -Neftal - Contact@

INTRODUCCIN

Pues ha llovido mucho desde la primera parte de este articulillo; Por lo que he visto en los fuentes del ejemplo, lo empec hace aproximadamente hace 2 aos, as que eso es lo que lleva de retardo! ;"# $n ese primer art culo se da%a una visi&n 'eneral de lo que pod a ser un sistema de Plu'(ns) *nas ideas 'enerales + al'o de c&di'o para empe,ar) -ueda%a en el tintero profundi,ar un poco m.s en el tema + ver un ejemplo un poco m.s pr.ctico que pudiera servir en una aplicaci&n real) $so es lo que he intentado tratar en esta se'unda parte, centrandome en un sistema de Pl!"Ins H#m#"ne#s, con car'a %ajo petici&n /por parte del usuario#)

TIPOS DE PLUGINS
Como +a vimos en la primera entre'a, podemos dividir los plu'(ns en dos tipos se'0n las tareas que desempean en una aplicaci&n) 1s podemos ha%lar de plu'(ns o 'rupos de ellos + catalo'arlos como homo'neos si la tarea que reali,an es similar o catalo'arlos como hetero'neos /no"a'rupados# si las tareas que desarrollan son independientes + no a'rupa%les se'0n su funcionalidad) 2rupos homo'neos de Plu'(ns Plu'(ns hetero'neos

$sta divisi&n no s&lo es conceptual en funci&n de las caracter sticas + desempeos de cada uno, sino que afecta directamente a la estructura con que se disear.n estos elementos) 1s , los Plu'(ns que pertene,can a un 'rupo homo'neo tendr.n estructura similar + un punto de entrada com0n /formulario %ase o procedimiento de ejecuci&n#) 3ientras que los hetero'neos posi%lemente no ten'an una estructura com0n + la forma se ejecutarlos sea m.s tosca + menos inte'rada que los anteriores)

PLUGINS HOMOGENEOS
$n este art culo vamos a tratar m.s profundamente esta variante de plu'(ns) Como +a hemos comentado se trata de plu'(ns con una estructura similar, aunque con variaciones en su funcionalidad) 4al ve, con un ejemplo se vea m.s claro) 4omemos como 'rupo homo'neo de Plu'(ns; 5os efectos aplica%les a una ima'en dentro de un pro'rama de diseo) 1 partir de una ima'en podemos desarrollar plu'(ns que efect0en un determinado cam%io de forma que la ima'en resultante sea diferente a la ori'inal) 5a estructura + los par.metros de todos ellos parece claro que ser.n similares o idnticos) 4odos ellos toman una ima'en inicial + a partir de unos par.metros la modifican, para devolver una ima'en de salida)

ESTRUCTURA FSICA
Para tra%ajar con esta estructura de plu'ins, utili,aremos un sistema de car'a din.mica) 5os plu'ins de pro'ramar.n utili,ando pac6a'es /7P5# con una estructura com0n + dependiendo de un pac6a'e principal que contiene la Clase 7ase) 4odos los plu'ins derivar.n /heredar.n# de una clase %ase que estar. pro'ramada en el pac6a'e principal) 1l car'ar la aplicaci&n se car'a /puesto que est. lin6ado de forma est.tica "utili,ando la clausula *8$8"# tam%in el pac6a'e correspondiente a la clase 7ase) $sto da acceso a todos los mtodos que estn definidos en la clase %ase /+ en los derivados# desde el pro'rama principal) $l resto de pac6a'es se car'an de forma din.mica + todos de%en derivar /sus clases# de la Clase 7ase pro'ramada en el pac6a'e 7ase)

P$%T%TIP%
$l prototipo que vamos a reali,ar para ilustrar el art culo simula un pro'rama para reali,ar 'r.ficos + dia'ramas simples) $l pro'rama utili,ar. un sistema de plu'(ns para aadir %i%liotecas de o%jetos que puedan aadirse a los 'r.ficos) Cada plu'in' /7P5# aade una n!eva &ate"#r a de elementos + cada cate'or a implementa !n# # var'#s #()et#s) 4odos los o%jetos que implementa una cate'or a derivan de una Clase 7ase /TS*a+eE,-ase# + esta clase %ase se implementa en un pac6a'e que est. l'n.a/# estt'&amente a la a+l'&a&'0n +r'n&'+al /se car'a siempre al arrancar la aplicaci&n# + es o%li'atorio que exista, de otra forma la aplicaci&n fallar a al ejecutarse) $n la primera ima'en que se ve a la derecha, vemos la ventana correspondiente al Plu'in de 1rro9s; 1qu implementa la clase TS*a+eE,Arr#1 /que deriva de TS*a+eE,-ase# + en

esta clase se han pro'ramado los o%jetos que se ven en la ima'en) $n nuestro ejemplo para este art culo se &ar"an l#s +l!"Ins (a)# +et'&'0n) $s decir, en una primera pasada la aplicaci&n revisa la existencia de Plu'(ns + detecta todos los ficheros presentes) 3uestra una ventana con los plu'ns disponi%les + la descripci&n de cada uno de ellos + a medida que el usuario los selecciona se car'an de forma din.mica) (ma'en de la derecha) $l c&di'o de la car'a es el si'uiente: ... 1 // Comprobacin 2 if not FileExists(AName) then begin 3 _mens(Format('No se a !o"i"o #ar$ar el !a#%a$e 4 &lt'(s&$t''' ) 5 'No existe en "is#o.'*+AName,))' 6 Exit' 7 end' 8 9 // Cargar 10 n"l -. /oa"0a#%a$e(AName)' 11 "es# -. 1et0a#%a$e2es#ri!tion(PChar(AName))' 12 3es4lt -. n"l' 13 14 // Acceder a la clase del menu 15 !Name -. 5 an$eFileExt(Extra#tFileName(AName)* 16 '')' 17 6 -. Ex5lass/ist.Fin"(!Name* i)' 18 // Encontrada? 19 if (6) then begin 20 A5lass -. 70ersistent5lass(Ex5lass/ist.869e#ts+i,)' end'

2LASE -ASE (TS*a+eE,-ase)


5a clase %ase para nuestro sistema de plu'ins se llama 48hape$x7ase) $sta clase sirve como punto de partida para todas las dem.s) 1dem.s de contener los mtodos comunes a todos los plu'ins nos permitir. acceder desde la aplicaci&n principal a todas las funciones de los plu'ins) Para ello los mtodos importantes estar.n definidos en esta clase + lue'o so%reescritos /override# en las clases derivadas)

; {: Clase base lapa las clases implementadas en los plugins.} 2 48hape$x7ase D &lass/48hape# < +r'vate = E8hape$x: str'n"; > ? // Marca el tipo de Shape @ +r#&e/!re 8et8hape$x/&#nst Falue: str'n"#; v'rt!al; A B +r#te&te/ ;C G, H, 8: Inte"er; ;; I, J:Inte"er; ;2 IG, JH:Inte"er; ;< G2, H2, G<, H<, H=, G=, HA, GA, G;?, H;?:Inte"er; ;= ;> // Mtodo de pintado ;? +r#&e/!re Paint; #verr'/e; ;@ +r#&e/!re CalculateKata/#;

;A ;B 2C 2; 22 2< 2= 2> 2? 2@ 2A 2B <C <; <2 << <= <> <? <@

// PROCE !M!E"#OS E !"$ORM%C!O" //&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& // %utor del pac'age f!n&t'#n 1utor/#:str'n"; v'rt!al; a(stra&t; // (ersi)n del Pac'age f!n&t'#n Fersion/#:str'n"; v'rt!al; a(stra&t; // $echa de creaci)n f!n&t'#n EechaCreacion/#:TDate; v'rt!al; a(stra&t; +!(l'& // constructor de la clase &#nstr!&t#r Create/1L9ner: 4Component#; #verr'/e; // destructor de la clase /estr!&t#r Kestro+; #verr'/e; +!(l's*e/ // #ipo de Shape +r#+ert3 8hape$x: str'n" read E8hape$x 9rite 8et8hape$x; en/;

$n nuestro caso es una clase sencilla) 5a funci&n implementa el di%ujo de componentes derivados de un 48hape en pantalla) 5a propiedad S*a+eE, es la m.s importante, e indica el tipo /identificador# de la fi'ura) $quivalente a lo que en los TS*a+e son los valores st$e&tan"le, st$llipse, st8quare,! $n nuestra clase no puede ser un elemento tipificado como lo es en 48hape, puesto que los nuevos plu'ins ir.n aadiendo elementos a esta propiedad que a priori no conocemos) 8e aaden tam%in procedimientos de informaci&n acerca del plu'in como pueden ser el 1utor, la fecha de creaci&n o la versi&n) $l mtodo Pa'nt, que para la clase %ase est. vac o, en las clases derivadas ser. donde se implementen las instrucciones de pintado para cada uno de los elementos) Einalmente la clase 7ase implementa el procedimiento 2al&!lateData + al utili,a al'unas varia%les en la parte protected, que precalculan datos + los ponen a disposici&n de las clases derivadas /protected#, para facilitar la implementaci&n del mtodo Paint + dar acceso a medidas +a precalculadas) $n la clase 7ase adem.s se definen dos 5istas /48trin'5ist# que nos servir.n de apo+o a la hora de acceder a los diferentes o%jetos de los plu'(ns; 4anto para las clases, como para los 8hapes definidos en cada clase) ; 2 < = //: *ista de clases registradas en los pac'ages din+micos $xClass5ist:48trin'5ist; //: *ista de ob,etos registrados en una clase -tipos de Shapes. $x8hape5ist:48trin'5ist;

$n la primera aadiremos la referen&'a a la 2lase + el 8trin' correspondiente al nom%re del pac6a'e + en la se'unda, para cada 8hape implementado en la Clase, su valor de la +r#+'e/a/ S*a+eE, /comentada anteriormente# + el apuntador a su clase) Ke esta forma, por ejemplo, el Plu'(n que implementa la clase Ts*a+eE,Arr#1 que corresponde a la ima'en que se ve m.s arri%a, aadir. en las lista los si'uientes valores: ; // Registrar los tipos 2 $x8hape5ist)1ddL%ject/Mst1rrorNi'htM, P#'nter/48hape$x1rro9##; < $x8hape5ist)1ddL%ject/Mst1rrorNi'htGM, P#'nter/48hape$x1rro9##;

= > ?

))) // registrar la clase $xClass5ist)1ddL%ject/MPlu'1rro9sM, P#'nter/48hape$x1rro9##;

$n las l neas anteriores podemos ver que el plu'(n Plu'1rro9 /;# tiene implementada la clase 48hape$x1rro9 /;#, + que dentro de esta clase ha+ ? o%jetos diferentes de tipo 8hape$x; Cu+os identificadores son: st1rrorNi'ht, st1rrorNi'ht, st1rrorNi'ht3, st1rror5eft, st1rror*p + st1rrorKo9n)

2LASES DE$I4ADAS
4al + como est. diseada la estructura, las clases derivadas de la clase 7ase /48hape$x7ase# de%en redefinir el mtodo Pa'nt para definir c&mo se define cada uno de los o%jetos de esa clase)

SISTEMA DE CARGA/DESCARGA
$l sistema de car'a es simple + lo 0nico que hace de especial en este caso es compro%ar primero si el pac6a'e +a ha sido car'ado, + si no es as llama a la funci&n 2ar"arPa&.a"e del formulario principal, utili,ando el nom%re del fichero) Podemos ver por pasos + comentar qu hace esta funci&n: ; 2 < = // Cargar hndl :D 5oadPac6a'e/1Oame#; desc :D 2etPac6a'eKescription/P2*ar/1Oame##; Nesult :D hndl;

$n primer lu'ar /una ve, hemos compro%ado que el fichero existe# car'amos el pac6a'e a partir de su nom%re) *na ve, car'ado o%tenemos la Kescripci&n) Para ello se llama a la funci&n GetPa&.a"eDes&r'+t'#n que se encuentra en la *nidad 8+s*tils)pas + que develve el valor almacenado en el KPP junto a la directiva 56DES2$IPTI%N7 o 56D7 que permite almacenar hasta 2>> caracteres) 4odos los pac6a'es cuentan con una secci&n de (O(4(15(Q14(LO donde aaden a las lista de clases /E,2lassL'st# + a la lista de 8hapes /E,S*a+eL'st# los elementos que ese pac6a'e implementa) $stas dos clases son importantes puesto que nos facilitan mucho el tra%ajo a la hora de reali,ar todo tipo de operaciones con los elementos de cada pac6a'es) 1dem.s se re'istra la clase utili,ando el mtodo Ne'isterClass de Kelphi) Por ejemplo, el pac6a'e de 1rro9s contiene esta secci&n de INITIALI8ATI%N: ; 2 < = > ? @ A B ///////////////////////////////////////////////////////// //////////// // // ! " ! # ! % * ! 0 % # ! O " // ///////////////////////////////////////////////////////// //////////// 'n't'al'zat'#n // Registrar la clase del 1orm

;C ;; ;2 ;< ;= ;> ;? ;@ ;A

Ne'isterClass/48hape$x1rro9#; // Registrar los tipos $x8hape5ist)1ddL%ject/Mst1rrorNi'htM, P#'nter/48hape$x1rro9##; $x8hape5ist)1ddL%ject/Mst1rrorNi'htGM, P#'nter/48hape$x1rro9##; $x8hape5ist)1ddL%ject/Mst1rrorNi'ht3M, P#'nter/48hape$x1rro9##; $x8hape5ist)1ddL%ject/Mst1rror5eftM, P#'nter/48hape$x1rro9##; $x8hape5ist)1ddL%ject/Mst1rror*pM, P#'nter/48hape$x1rro9##; $x8hape5ist)1ddL%ject/Mst1rrorKo9nM, P#'nter/48hape$x1rro9##; // registrar la clase $xClass5ist)1ddL%ject/MPlu'1rro9sM, P#'nter/48hape$x1rro9##; ///////////////////////////////////////////////////////// ////////////

5o si'uiente que vamos necesitamos, una ve, que tenemos car'ado el pac6a'e, es crear la clase que se implementa en el pac6a'e; *na ve, hecho esto +a tendremos total acceso a los mtodos que necesitemos + realmente +a ha%remos conse'uido nuestro o%jetivo) Para crear la clase utili,amos la lista de clases /E,2lassL'st# que hemos comentado en el p.rrafo anterior + que hemos rellenado en la secci&n de iniciali,aci&n; Ltra opci&n tam%in via%le es utili,ar Get2lass de Kelphi mediante N44( junto con el nom%re de la clase re'istrada /48hape$x1rro9#) 4am%in funcionar a, aunque en este caso, por comodidad, hemos utili,ado estas listas auxiliares) ; // Crear la clase 2 % :D $xClass5ist)Eind/pOame, i#; < // encontrada2 = 'f /%# t*en (e"'n > 1Class :D 4PersistentClass/$xClass5ist)L%jectsRiS#; ? @ // O#R% OPC!3": A 7Class :D 2etClass/M48hape$x1rro9M#; B en/;

Para finali,ar + despus de ha%er reali,ado unas compro%aciones, llamamos al mtodo 2ar"ar2ate"#r'a, que crea de forma din.mica la ventana asociada a esa cate'or a /con la descripci&n# + tam%in crea el elemento individual asociada a cada 8hape implementado en esa clase) $n este punto +a hemos hecho uso de todo lo implementado en ese pac6a'e, puesto que +a hemos creado un o%jeto de todos los implementados) TT Car'ar los o%jetos de ese plu'(n Car'arCate'oria/1Class, desc#; $n este ejemplo, no descar'amos los pac6a'es, puesto que los necesitamos para se'uir tra%ajando con los o%jetos que tenemos en pantalla, lo que hacemos realmente es ocultar la ventana) 8i la operaci&n que desempea el pac6a'e no necesita que posteriormente est car'ado, %astar a con descar'arlo utili,ando Unl#a/Pa&.a"e) Hasta aqu las descripci&n de todo el proceso) Uunto con el art culo os adjunto el ejemplo completo + %astante comentado) $s sencillo, pero muestra a la perfecci&n el manejo pr.ctico de este tipo de ficheros) $spero que ha+a quedado claro + si ha+ comentarios o su'erencias, +a sa%is) VVKisparadWW ;"K

(ma'en del pro'rama de ejemplo) $l c&di'o del ejemplo se puede descar'ar desde mi 9e% junto con los %inarios /$I$ X 7P5Ys# en paquetes separados)

También podría gustarte