PDA

Ver la Versión Completa : Cambiar propiedades de componentes desde una DLL


Albano
19-04-2007, 01:44:38
Hola a todos, que tengan un buen dia.
Tengo el siguiente procedimiento
procedure TForm2.CentrarMarco(Marco: TFrame);
var
aux: double;
s: string;
begin
aux := panelcontenido.Width - marco.Width;
aux := aux / 2;
s := floattostr(aux);
Delete(s, pos(decimalseparator, s), MaxInt);
marco.Left := strtoint(s);
aux := panelcontenido.Height - marco.Height;
aux := aux / 2;
s := floattostr(aux);
Delete(s, pos(decimalseparator, s), MaxInt);
marco.Top := strtoint(s) - 20;
end;
en un proyecto, lo que hace es que centra un marco (frame) en un panel, lo uso cada vez que creo un marco o cada vez que ajusto el tamaño de mi forma. Quiero usar este procedimiento en otros proyectos, entonces lo que hice fue ponerlo en una DLL, para estar reutilizando el código. En la DLL lo puse de la siguiente manera:
library frames;

uses
SysUtils, Classes, Forms, ExtCtrls;

{$R *.res}

procedure centrarmarco(marco: tframe; base: tpanel);
var
aux: double;
s: string;
begin
aux := base.Width - marco.Width;
aux := aux / 2;
s := floattostr(aux);
Delete(s, pos(decimalseparator, s), MaxInt);
marco.Left := strtoint(s);
aux := base.Height - marco.Height;
aux := aux / 2;
s := floattostr(aux);
Delete(s, pos(decimalseparator, s), MaxInt);
marco.Top := strtoint(s) - 20;
end;

exports centrarmarco;

begin
end.
En mi aplicación tengo declarado el procedimiento de la siguiente manera:
procedure centrarmarco(marco: tframe; base: tpanel); stdcall; external 'frames.dll'
Lo mando llamar de la siguiente manera:
CentrarMarco(FrameCamAlt, panelcontenido);
Y no hace nada, no mueve las propiedades de mi frame... pensé en hacer dos funciones que me regresen un número entero, una para el left y otra para el top del marco que quiero centrar, pero quisiera hacerlo de la manera en que lo muestro aqui... Es esto posible?
Gracias de antemano, Dios los bendiga.

roman
19-04-2007, 02:22:51
Aun cuando no sé si eso resuelva tu problema, yo quitaría el stdcall al momento de importar la rutina pues deben coincidir las convenciones de llamada.

// Saludos

Robert01
19-04-2007, 02:26:36
Hola

Por lo que veo no exportas el procedure:



procedure centrarmarco(marco: tframe; base: tpanel);


Yo usaría


procedure centrarmarco(marco: tframe; base: tpanel);stdcall;


Saludos

Albano
19-04-2007, 20:36:18
Ya encontré mi error... lo que pasaba es que estaba llamando la función con un Frame que ni siquiera tengo visible, cambíe el frame y si modifica sus propiedades...
Perdon por hacerles perder el tiempo, pero espero que por lo menos de algo sirvan los pedazos de código que puse...
Gracias por las respuestas... ya quité el stdcall y sigue funcionando bien.

Albano
20-04-2007, 00:43:00
Hola de nuevo... otra vez vengo con una duda referente a este procedimiento...
Quiero saber si es posible crear el procedimiento de alguna otra manera para que acepte otro componente en lugar del Frame y haga lo mismo, que lo centre sobre mi panel, un ejemplo de otro componente que quiero centrar es un TImage. O sea que lo que quiero es que el mismo procedimiento centre a ambos componentes, aunque sean de diferente tipo.
Y ya que estoy en esto, quiero saber si es posible centrar estos componentes sobre algun otro componente, por ejemplo un Form.
Gracias de antemano.

basti
20-04-2007, 02:09:50
Para poder hacer eso, en general, tienes que buscar la clase donde están definidas las propiedades que vas a necesitar. En tu caso necesitas left, top, width y height, que están declaradas en TControl. Como TControl es antecesor de TFrame y TImage no tendrás problemas, sólo tienes que declarar el procedimiento como:

procedure centrarmarco(objeto: TObject; base: tpanel)

En caso de que no fuese así sería más complejo.

Albano
20-04-2007, 02:34:32
Acabo de intentarlo, cambié el tipo de componente de TFrame a TObject y me marcó el siguiente error al compilar la DLL [Error] frames.dpr(13): E2003 Undeclared identifier: 'Width'
Tengo que agregar algo al uses de mi DLL? o cuál es el problema?

basti
20-04-2007, 02:51:04
Perdón, error mío, en vez de TControl puse TObject en la declaración del procedimiento.

Debería ser

procedure centrarmarco(objeto : TControl; base : tpanel);

Albano
20-04-2007, 21:41:38
Ahora si creo que tengo que agregar algo al uses, me esta marcando el error de:
Undeclared identifier: 'tcontrol'

luisgutierrezb
20-04-2007, 23:47:28
Vas a decir que que me importa, pero la rutina que haces para centrar se me hace que es mucho para tan poco, a simple vista hice otra basada en la tuya, espero que te sirva:


procedure centrarmarco(marco: tframe; base: tpanel);
var
aux: Integer;
begin
aux := base.Width - marco.Width;
aux := aux div 2;
marco.Left := aux;
aux := base.Height - marco.Height;
aux := aux div 2;
marco.Top := aux - 20;
end;

roman
21-04-2007, 00:05:36
¡Caramba! No había yo puesto atención al método que usabas y ahora veo que tomaste literal lo de este hilo (http://www.clubdelphi.com/foros/showthread.php?t=40236). Es mucho mejor como propone Luis.

// Saludos

Albano
23-04-2007, 19:58:13
Vas a decir que que me importa, pero la rutina que haces para centrar se me hace que es mucho para tan poco
Claro que no voy a decir eso, la idea de poner mi código es para que vean mi problema y también para que detecten cosas como esta, muchisimas gracias por esta otra opción. Ya había usado el div, pero en este momento ni me acordaba de el.