FTP | CCD | Buscar | Trucos | Trabajo | Foros |
|
Registrarse | FAQ | Miembros | Calendario | Guía de estilo | Buscar | Temas de Hoy | Marcar Foros Como Leídos |
|
Herramientas | Buscar en Tema | Desplegado |
#1
|
|||
|
|||
Crear un Componente TScrollbox con botones dentro
Hola a todos, hace unos días estaba pidiendo consejo sobre la creación de una aplicación, cosa que ya he acabado.
Para dicha aplicación he usado un Scrollbox y dentro de él he metido botones que creo en tiempo de ejecución, dependiendo la cantidad de los mismos de cierta cantidad de una consulta. Pues bien, una vez dicho esto, mi intención es hacer un componente con lo que he comentado anteriormente, es decir, un Scrollbox al que se le puedan insertar botones dependiento de la cantidad que lea de una propiedad creada. Hasta ahora tengo el componente del boton creado con las nuevas propiedades que quiero que tenga y su procedimientos pero es solo el botón, yo quiero que me muestro un Scrollbox y como he dicho antes, esos botones se creen leyendo una nueva propiedad. Espero haberme explicado bien, de todas formas no duden en preguntar, un saludo.
__________________
No hay vientos favorables para quién no conoce su rumbo. |
#2
|
||||
|
||||
Hola Corbatin. No he entendido exactamente tu duda. Es que creas el botón, y no te aparece en el Paintbox??
__________________
Juan Antonio Castillo Hernández (jachguate) Guía de Estilo | Etiqueta CODE | Búsca antes de preguntar | blog de jachguate |
#3
|
|||
|
|||
Hola, ya he solucionado ese problema y lo tengo casi acabado el componente.
De todas formas, cuando este del todo terminado (según yo) lo pondré aquí en el foro para mejorarlo y para quién quiera copiarlo, un saludo.
__________________
No hay vientos favorables para quién no conoce su rumbo. |
#4
|
|||
|
|||
Aquí estoy otra vez, he tenido algunos problemillas con la creación del componente pero los he ido solventando poco a poco. En esto momentos estoy parado con el siguiente problema:
- Ya me he creado mi tipo de boton que incluire en el Scrollbox. - También he creado mi Scrollbox el que crea botones dentro de si mismo dependiendo de una cantidad en una propiedad del inspector de objetos (incluso los crea en tiempo de diseño guay). Estos botones los voy metiendo en un array dinámico del mismo tipo para poder interactuar con ellos. - Pero ahora tengo el problema de como hacer algo cuando se pulse sobre el botón, es decir, no se como programar el componente para que cuando se pulse un botón que tiene en su interior hacer lo que sea. - En tiempo de diseño, cuando pulsas sobre el botón en realidad lo estas haciendo sobre mi Scrollbox, por lo que no puedo acceder al evento Onclick del botón. - Si alguién sabe implementar un procedimiento para mi componente Scrollbox, para que cuando se pulse un botón de los que contiene pueda hacer algo, que me lo diga, gracias y saludos.
__________________
No hay vientos favorables para quién no conoce su rumbo. |
#5
|
||||
|
||||
simplemente hace un método en tu componente que reciba un parámetro llamado Sender de tipo TObject. Supongamos que este método se va a llamar BotonClick.
Cuando estas creando los botones, asignas este método a su evento OnClick. . De esta forma se ejecuta el método BotonClick cada vez que se pulsa cualquier boton. Llegando un poco mas lejos, podes incluso definir un nuevo evento en tu componente que se dispare cada vez que se hace click sobre cualquier boton... Hasta luego.
__________________
Juan Antonio Castillo Hernández (jachguate) Guía de Estilo | Etiqueta CODE | Búsca antes de preguntar | blog de jachguate |
#6
|
|||
|
|||
No te he entendido muy bien, ¿lo puedes explicar un poquito más?
Gracias.
__________________
No hay vientos favorables para quién no conoce su rumbo. |
#7
|
|||
|
|||
Aclarando un poquito lo anterior, mi intención es que sea algo parecido o igual a lo que ocurre cuando haces click sobre cualquier componente, te sale el procedimiento o evento Onclick y en él se puede colocar código introducido por el usuario, gracias de nuevo.
__________________
No hay vientos favorables para quién no conoce su rumbo. |
#8
|
||||
|
||||
Un evento es un apuntador a un método. Para ser exactos, es una propiedad de los objetos que apunta a direcciones de métodos de otros objetos. Lo que haces en el object inspector es eso... relacionar los "eventos" de los objetos (componentes) con métodos de otro objeto (regularmente de los formularios).
Esa asignación que hace el ObjectInspector, también podes hacerla por código. La condicion a cumplir es que la lista de parámetros sea igual, en número y tipo, a la requerida por el evento. Esta verificación se realiza usando tipos procedurales para definir los eventos, y es chequeada en tiempo de compilación. Para que el inspector de objetos interprete una propiedad como evento, esta tiene que ser de un tipo procedural. Ya hay algunos tipos definidos en unidades de la VCL, como el TNotifyEvent, cuya definición es algo como:
la clausula of Object indica al compilador que solamente un método de otro objeto será válido, y no un procedimiento "independiente". Lo que haces por código, entonces, es asignar un método de tu componente a la propiedad "evento" de los botones. En este método, ya vos podes identificar, mediante el sender, que botón es el que ha sido pulsado, y actuar en consecuencia. Para ampliar tus conocimientos en este tema, te recomiendo la lectura de un libro que abarque el diseño de componentes. El que a mi mas me gusta es Mastering Delphi, de Marco Cantú. Hasta luego.
__________________
Juan Antonio Castillo Hernández (jachguate) Guía de Estilo | Etiqueta CODE | Búsca antes de preguntar | blog de jachguate |
#9
|
|||
|
|||
Hola a todos, lo prometido es deuda, aquí teneis el componente en el que he estado trabajando. Es mi primer componente, así que espero que las críticas sean moderadas. Ha quedado hacer que cuando se cambia el tamaño del ScrollBox en diseño, se re-coloquen los botones que contienen. Esto se consigue volviendo hacer enter sobre el campo CanBotones. También queda pendiente, que si colocamos algún componente en el interior del Scrollbox como por ejemplo un Toolbar, pues que lo respete y no pinte los botones por encima de ellos. Por lo demás creo que esta bastante logrado, pero aquí lo teneis para mejorarlo o para lo que sea, un saludo.
Ahhh, instalar primero el MyButtons y después el MyBox. Yo los he metido en paquetes diferentes para instarlarlos. Código:
unit MyButtons; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, Buttons; type TMyButtons = class(TBitBtn) private { Private declarations } FOrdBoton: integer; FCodigo: integer; FFocusColor: TColor; FNormalColor: TColor; procedure SetOrdboton (Value: integer);//orden que ocupa en el array procedure SetCodigo (Value: integer);//campo para introducir un codigo que el usuario quiera utilizar procedure SetFocusColor(const Value: TColor);//color para el caption al recibir el foco protected procedure DoEnter; override; procedure DoExit; override; public { Public declarations } constructor Create(AOwner : TComponent);override; // destructor Destroy; published { Published declarations } Property OrdBoton: integer read FOrdBoton write SetOrdBoton default 0; Property Codigo: integer read FCodigo write SetCodigo default 0; property FocusColor: TColor read FFocusColor write SetFocusColor default clRed; end; procedure Register; implementation constructor TMyButtons.Create(AOwner : TComponent); begin inherited Create(AOwner); FOrdBoton := 0; FCodigo := 0; FFocusColor := clRed; Font.color := ClNavy; Visible := True; cursor := crHandPoint; font.name := 'Times New Roman'; font.Size := 7; end; procedure TMyButtons.SetOrdBoton(Value:integer); begin if Value < 0 then FOrdBoton := 0 else FOrdBoton := Value; end; procedure TMyButtons.SetCodigo(Value: integer); begin if Value < 0 then FCodigo := 0 else FCodigo := Value; end; procedure TMyButtons.DoEnter; begin inherited; FNormalColor := font.Color; font.color := FFocusColor; font.Style := [fsunderline]; end; procedure TMyButtons.DoExit; begin inherited; font.color := FNormalColor; font.Style := font.Style-[fsunderline]; end; procedure TMyButtons.SetFocusColor(const Value: TColor); begin if FFocusColor <> Value then begin FFocusColor := Value; if Self.Focused then begin FNormalColor := Color; Font.Color := Value; end; end; end; procedure Register; begin RegisterComponents('Mis Componentes', [TMyButtons]); end; end. Código:
unit MyBox; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, MyButtons,Buttons; type TOnPulsarButtons = procedure(sender: Tobject;Ind:integer) of object; TMyBox = class(TScrollBox) private FLdesp:integer;//para colocar separados los botones FTdesp:integer;//para colocar separados los botones FMyButtonsWidth: integer;//tamaño de los botones FMyButtonsHeight: integer;//tamaño de los botones; FConBotones: boolean;//para saber si el array contiene botones o no FCantBotones: integer;//valor de la propiedad FOldWidth: integer;//tamaño anterior FOldHeight: integer;//tamaño anterior FOldCantBotones: integer;//guarda el ultimo valor introducido FOnPulsarButtons : TOnPulsarButtons; {Campo para el evento} procedure SetCantBotones (Value:integer);//asignar cantidad de botones al Scrollbox procedure AddBotones(Value: integer);//para añadir los botones procedure SetMyButtonsHeight(Value: integer);//calcular tamaño de los botones interiores procedure SetMyButtonsWidth(Value: integer);//calcular tamaño de los botones interiores procedure SetAncho(Value:integer);//darle el tamaño a los botones procedure SetLargo(Value:integer);//darle el tamaño a los botones procedure AjustarSeparacion();//ajustar botones al cambiar el tamaño del Scrollbox protected { Protected declarations } procedure PulsarButtons(Sender: TObject); dynamic; public { Public declarations } Botones: array of TMybuttons;//array donde guardo los botones insertados constructor Create(AOwner : TComponent);override; destructor destroy;override; published { Published declarations } property CantBotones: integer read FCantBotones write SetCantBotones default 0; property MyButtonsWidth: integer read FMyButtonsWidth write SetMyButtonsWidth default 150; property MyButtonsHeight: integer read FMyButtonsHeight write SetMyButtonsHeight default 50; property OnPulsarButtons : TOnPulsarButtons read FOnPulsarButtons write FOnPulsarButtons; end; procedure Register; implementation constructor TMyBox.Create(AOwner : TComponent); begin inherited Create(AOwner); FMyButtonsWidth := 150; FMyButtonsHeight := 50; FCantBotones := 0; FOldCantBotones := 0; FConBotones := false; end; destructor TMyBox.destroy; VAR x: integer; begin if FConBotones then begin for x := 0 to FcantBotones-1 do Botones[x].free; end; inherited destroy; end; procedure TMyBox.SetMyButtonsWidth(Value: integer); begin if (Value <= 0) and (Value = FOldWidth) then FMyButtonsWidth := FOldWidth else begin if FCantBotones > 0 then begin FOldWidth := Value; FMyButtonsWidth := Value; SetLargo(Value); end; end; end; procedure TMyBox.SetMyButtonsHeight(Value: integer); begin if (Value <= 0) and (Value = FOldHeight) then FMyButtonsHeight := FOldHeight else begin if FCantBotones > 0 then begin FOldHeight := Value; FMyButtonsHeight := Value; SetAncho(Value); end; end; end; procedure TMyBox.SetAncho(Value:integer); var x: integer; begin for x := 0 to FCantBotones -1 do Botones[x].Height := Value; AjustarSeparacion(); end; procedure TMyBox.SetLargo(Value:integer); var x: integer; begin for x := 0 to FCantBotones -1 do Botones[x].Width := Value; AjustarSeparacion(); end; procedure TMyBox.AjustarSeparacion(); var x,TamMax,ContBot: integer; begin TamMax := 0; ContBot := 1; FLdesp := 2; FTdesp := 0; for x := 0 to FCantBotones -1 do begin with Botones[x] do begin TamMax := (ContBot * Width) + 25; if TamMax > self.Width then begin FTdesp := FTdesp+Height+2; FLdesp := 2; ContBot := 1; end; Left := FLdesp; Top := 2 + FTdesp; FLdesp := FLdesp + Width + 2; inc(Contbot); end; end; end; procedure TMyBox.PulsarButtons(Sender: TObject); var ind: integer; begin if Assigned(FOnPulsarButtons) then begin for ind := 0 to FCantBotones-1 do if botones[ind].Focused then FOnPulsarButtons(sender,ind); end; end; procedure TMyBox.SetCantBotones (Value:integer); var x: integer; begin if Value < 0 then FCantBotones := FOldCantBotones else begin if FConBotones then begin for x := 0 to FcantBotones-1 do Botones[x].free; end; FOldCantBotones := Value; FCantBotones := Value; AddBotones(Value); end; end; procedure TMyBox.AddBotones(Value: integer); var ind,ContBot,TamMax:integer; begin Setlength(Botones,Value); TamMax := 0; ContBot := 1; FLdesp := 2; FTdesp := 0; for ind := 0 to Value-1 do begin Botones[ind] := TMyButtons.Create(self); with Botones[ind] do begin Onclick := PulsarButtons; caption := 'MyButtons'+inttostr(ind);; FConBotones := true; OrdBoton := ind; Width := 150; Height := 50; TamMax := (ContBot * Width) + 25; if TamMax > self.Width then begin FTdesp := FTdesp+Height+2; FLdesp := 2; ContBot := 1; end; Left := FLdesp; Top := 2 + FTdesp; FLdesp := FLdesp + Width + 2; parent := self; inc(Contbot); end; end; end; procedure Register; begin RegisterComponents('Mis Componentes', [TMyBox]); end; end.
__________________
No hay vientos favorables para quién no conoce su rumbo. |
#10
|
|||
|
|||
Pero que os pasa, nadie quiere opinar sobre los componentes que he creado?
tal vez mejorarlos?. Espero que alguién pueda contribuir con opiniones, son mis primeros componentes y encima que los comparto, me esperaba más interés, en fin, la vida es así de dura, un saludo para todos.
__________________
No hay vientos favorables para quién no conoce su rumbo. |
#11
|
||||
|
||||
Hola Corbatin.
No te impacientes. El código lo publicaste hace apenas un par de días. Para que alguien se interese en tu componente, debiera tener una necesidad específica que este cubra, no te parece? Solo ve a tu alrededor y te vas a dar cuenta que la gente no vuela a poner una crítica constructiva, ni por los componentes que son mucho mas espectaculares... Julián, un moderador del club ha hecho un componente para conectarse a Word y hacer algunas maravillas... y ha recibido algun feedback?? pos no! Yo he echado un ojo a la interfaz del componente, sin entrar a ver nada de la implementación... y lo que puedo decirte es que:
No te desanimes. Quizas sea mejor que colgues el componente listo para descargarlo e instalarlo (indicando para que versión de delphi funciona). Si no tenes un espacio para hacerlo, yo te ofrezco colgarlo de mi (futura) web personal aqui en el club, y por lo pronto se puede colocar alli y poner un enlace desde aqui para quien quiera probarlo. hasta luego.
__________________
Juan Antonio Castillo Hernández (jachguate) Guía de Estilo | Etiqueta CODE | Búsca antes de preguntar | blog de jachguate Última edición por jachguate fecha: 06-05-2004 a las 00:42:16. |
#12
|
|||||
|
|||||
Cita:
Cita:
Cita:
Cita:
mybox1.botones[indice].caption:= 'hola'; mybox1.botones[indice].glyh.loadfromfile('dibujo.bmp'); Además existe un evento en el mybox llamado "Pulsarboton" que podemos saber que botón ha sido pulsado a través del sender e incluso un indice para poder localizarlo en el array botones: (sender as TMyButtons).caption:= 'hola'; También existe propiedades para cambiar el tamaño de los botones dentro del MyBox como MyButtonsHeight y MyButtonsWidth. Cita:
Te agradezco tus opiniones, de momento aquí se queda el componente, en cuanto lo tenga un poquito más definido te aviso y si quieres lo puedes colocar en tú futura página web, un saludo para todos y gracias.
__________________
No hay vientos favorables para quién no conoce su rumbo. Última edición por CORBATIN fecha: 06-05-2004 a las 21:20:47. |
#13
|
||||
|
||||
CORBATIN
Me tomé la libertad de borrar el mensaje en donde te equivocaste al usar las etiquetas viendo que lo habías repetido posteriormente con el formato correcto. Quizá no te hayas percatado pero te informo que cuando te suceda eso puedes editar tú mismo el mensaje paa hacer las correcciones pertinentes. // Saludos |
#14
|
||||
|
||||
Hola corbatín.
En primer lugar, te comento que has encerrado las citas en etiquetas [ code ], cuando debiste hacerlo en etiquetas [ quote ]cita[ /quote ] que queda asi: Cita:
Luego... una última idea, ya que realmente me parece engorroso tener que asignar por código los captions e imagenes de los botones... supongo que ya dependerá de las necesidades de cada uno, pero para hacer algo mas de propósito general, creo que podrias definir una propiedad Captions en el componente, que sea un TStrings, y que al ser asignada escriba el caption de cada botón... igual, podes poner una propiedad glyphs, que se base en un TImageList. O bien que hagas otras dos propiedades arrays para acceder estas propiedades y no directamente a los botones... Hasta luego.
__________________
Juan Antonio Castillo Hernández (jachguate) Guía de Estilo | Etiqueta CODE | Búsca antes de preguntar | blog de jachguate |
#15
|
|||
|
|||
Aquí estamos otra vez, pido perdón por el error anterior del [code], lo he editado y le ha cambiado los tags pero sigue siendo muy ancho, lo siento.
Cita:
Lo de la propiedad glyphs esta tal y como se hace actualmente con los bitbtn naturales y con respecto a los arrays para acceder a las propiedades y no directamente a los botones, no entiendo lo que quieres decir. Si puedes ser un poco más concreto intentaré hacerlo, pero debes tener en cuenta que ha sido mi primer componente, así que como se suele decir, no le pidas Peras al Olmo jajaja. De todas formas, y como te he dicho anteriormente, si me explicas un poquito mejor lo que quieres decir, lo intentare seguro, un saludo.
__________________
No hay vientos favorables para quién no conoce su rumbo. |
#16
|
||||
|
||||
Declarar un par de propiedades propiedad tipo array... de manera que podas hacer:
ButtonBox1.glyphs[1].LoadFromFile('glyph1.bmp'); ButtonBox1.captions[1] := 'Prueba'; en lugar de ButtonBox1.buttons[1].glyph.LoadFromFile('glyph1.bmp'); ButtonBox1.buttons[1].caption := 'Prueba'; es solo un capricho... Por otro lado, al haber editado tus etiquetas en el post anterior, en mi navegador ahora se ve perfecto... Hasta luego.
__________________
Juan Antonio Castillo Hernández (jachguate) Guía de Estilo | Etiqueta CODE | Búsca antes de preguntar | blog de jachguate |
Herramientas | Buscar en Tema |
Desplegado | |
|
|
|