Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > OOP
Registrarse FAQ Miembros Calendario Guía de estilo Buscar Temas de Hoy Marcar Foros Como Leídos

Grupo de Teaming del ClubDelphi

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 09-04-2017
Avatar de mRoman
mRoman mRoman is offline
Miembro
 
Registrado: nov 2003
Posts: 599
Poder: 21
mRoman Va por buen camino
Crear botones en tiempo de ejecucion

Hola amigos....aqui de nuevo solicitandoles de su apoyo.

Trabajo con: Delphi6, Firebird 2.0

Estoy tratano de hacer un arreglo de botones y que estos se muestren en la pantalla para el usuario. El sistema q estoy desarrollando es uno de comandas, el cliente quiere que por cada comanda se genere un boton en la pantalla, y que estos se ordenen en base a los numeros de mesa. El caso de los numeros de mesas es el siguiente:

1 fila de mesas, serian las mesas 1....y cada mesa seria 1,2,3,4,5, etc., de tal manera que la mesa 11, es un numero compuesto para identificar las mesa 1 de la fila de mesas 1, y para las mesas de la fila 2, seria igual: 21,23,24,25 etc...

Aqui es donde el cliente quiere lo siguiente:

Q en el pantalla se le generen en una primer fila de botones, todos las mesas q correspondan a la fila 1...boton11=mesa11, boton12=mesa12, boton3=mesa13...etc
En una segunda fila de botones, todas las mesas de la fila 2...boton21=mesa21, boton22=mesa22, etc.

Buscando en este foro me encontré este codigo de efcsa, le hice unas modificaciones para hacer lo q requiero, pero me marca un error...aqui mi codigo:
Código Delphi [-]
procedure TForm1.BitBtn1Click(Sender: TObject);
var
  MaxC, MaxR, c, r: Integer;
  iTop, iLeft: Integer;
  iHeight, iWidth , nn: Integer;
begin
  MaxC := StrToInt(edit1.Text);  // Nro columnas
  MaxR := StrToInt(edit2.text);  // Nro filas
  SetLength(v, MaxC+1, MaxR+1);  // Inicializar arreglo

  iWidth  := 75;    // ancho botón
  iHeight := 25;    // alto botón
  iTop    := 100;   // inicio de filas
  nn      := 1;     // contador

  for c := 1 to 30 do
  begin
    if c=StrToInt(Edit2.Text) then
    begin
          iLeft := 100;   // inicio de columnas
          for r := 1 to 30 do
          begin
                if r=StrToInt(Edit1.Text) then
                begin
                      v[c,r]         := TButton.Create(Self);
                      v[c,r].Name    := 'DynButton' + IntTostr(nn);
                      v[c,r].Caption := v[c,r].Name;
                      v[c,r].Width   := iWidth;
                      v[c,r].Height  := iHeight;
                      v[c,r].Top     := iTop;
                      v[c,r].Left    := iLeft;
                      v[c,r].Parent  := Self;
                      Inc(iLeft, iWidth + 15);  // 15: separación horizontal
                      Inc(nn);  // contador
                end;
          end;
          Inc(iTop, iHeight + 25);  // 25: separación vertical
    end;
  end;
end;

Mas arriba defino un array de botones:
Código Delphi [-]
    v: array of array of TButton;

Lo que busco es algo como lo siguiente:

Buscar dentro del array, la CELDA para ahi almacenar el boton, y visualmente dejarlo en esa posicicion, por ejemplo si SE ABRE LA MESA 34, que en la linea 3, columna 4, crear el boton y visualmente que se vea ahi....se podrá hacer esto????

Tambien estoy abierto a mejores ideas....no estoy "casado" con esta q expongo....porq me salta ahoria una idea....crear desde un inicio todos los botones que necesito y q el usuario de click sobre el boton deseado q corresponda a la mesa, para abrirle la cuenta....sería otra opcion....

Aqui les dejo el codigo de mi sistema donde creo los botones en tiempo de ejecución, pero se generan en el orden en que se van creando....
Código Delphi [-]
procedure TfrmMesasAbiertas.CrearBoton();
begin
     n:=n+1;
     Botones[n]:=TBitBtn.Create(Self);
     with Botones[n] do
     begin
         Caption:=nIDMesa+'-'+BD.AliasEmpleado;
//         bCaption:=Caption;
//         IdRegistro:=
         Hint:=nIDMesa;
         Parent:=ScrollBox1;
         Height:=vHeight;
         PosY:=PosY+Height+10;
         if n>1 then
            vLeft:=vLeft+126;
         if vLeft=1270 then
         begin
             vTop:=vTop+87;
             vLeft:=10;
         end;
         Top:=vTop;
         Left:=vLeft;
         Width:=vWidth;
         OnClick:=BitBtn1Click;
         Name:='btn'+IntToStr(n);
         Font.Size:=13;
//         Tag:=n;
         Tag:=BD.n_IDRegistro;
         IDRegistro:=BD.n_IDRegistro;
         ValidarTicketSinDetalle();
         if qryValidarTicketSinDetalle.FieldByName('regs').AsInteger=0 then
            Glyph:=BitBtn2.Glyph
         else
            Glyph:=BitBtn1.Glyph;
         Layout:=blGlyphTop;
     end;
end;

Bueno espero me puedan orientar en lo antes expuesto. Saludos !!!!...(hacia mucho que no los consultaba)...

GRacias!"!!
__________________
Miguel Román

Afectuoso saludo desde tierras mexicanas....un aguachile?, con unas "cetaseas" bien "muertas"?, VENTE PUES !!

Última edición por mRoman fecha: 09-04-2017 a las 05:05:36.
Responder Con Cita
  #2  
Antiguo 09-04-2017
Avatar de escafandra
[escafandra] escafandra is offline
Miembro Premium
 
Registrado: nov 2007
Posts: 2.195
Poder: 20
escafandra Tiene un aura espectacularescafandra Tiene un aura espectacular
Una primera aproximación sería crear los botones en sus posiciones e irlos visualizando conforme se necesiten.

Te muestro una clase que crea los botones ordenados con los caption de las mesas correspondientes, en este caso son 5 filas de 5 mesas cada una pero puedes poner las que quieras:
Código Delphi [-]
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TButtons = class
  private
    Owner: TWinControl;
    nRows: integer;
    nCols: integer;
    Buttons: array of TButton;
  public
    constructor Create(AOwner: TWinControl);
    destructor Destroy; override;
    procedure SetButtons(Rows, Cols: integer);
    procedure SetOnClick(OnClick: TNotifyEvent);
  end;

  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
    procedure ButtonClick(Sender: TObject);
  private
    Buttons: TButtons;
  public
    { Public declarations }
  end;


var
  Form1: TForm1;

implementation

{$R *.dfm}
constructor TButtons.Create(AOwner: TWinControl);
begin
  inherited Create;
  Owner:= AOwner;
end;

destructor TButtons.Destroy;
begin
  SetLength(Buttons, 0);
  inherited Destroy;
end;

procedure TButtons.SetButtons(Rows, Cols: integer);
var
  i, Count: integer;
begin
  nRows:= Rows;
  nCols:= Cols;
  Count:= Rows*Cols;
  SetLength(Buttons, Count);
  for i:= 0 to Count-1 do
  begin
    Buttons[i]:= TButton.Create(Owner);
    Buttons[i].Caption:= IntToStr((i div Cols + 1)*10 + (i mod Cols) + 1);
    Buttons[i].Top:=  Buttons[i].Height*(i mod Cols);
    Buttons[i].Left:= Buttons[i].Width*(i div Cols);
    Buttons[i].Parent:= Owner;
  end;
end;

procedure TButtons.SetOnClick(OnClick: TNotifyEvent);
var
  i, Count: integer;
begin
  Count:= nRows * nCols;
  for i:= 0 to Count-1 do
    Buttons[i].OnClick:= OnClick;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  Buttons:= TButtons.Create(self);
  Buttons.SetButtons(5,5);
  Buttons.SetOnClick(ButtonClick);
end;

procedure TForm1.ButtonClick(Sender: TObject);
begin
  MessageBox(Handle, PCHAR(TButton(Sender).Caption), 'hola', 0);
end;

end.

Saludos.
Responder Con Cita
  #3  
Antiguo 09-04-2017
Avatar de mRoman
mRoman mRoman is offline
Miembro
 
Registrado: nov 2003
Posts: 599
Poder: 21
mRoman Va por buen camino
Te agradezco escafandra....lo aplicaré en la primera oportunidad q tenga el dia de hoy, para ver su comportamiento.

Muchas Gracias por tu tiempo !!!...

Saludos.
__________________
Miguel Román

Afectuoso saludo desde tierras mexicanas....un aguachile?, con unas "cetaseas" bien "muertas"?, VENTE PUES !!
Responder Con Cita
  #4  
Antiguo 23-04-2017
Avatar de mRoman
mRoman mRoman is offline
Miembro
 
Registrado: nov 2003
Posts: 599
Poder: 21
mRoman Va por buen camino
Disculpen por tardar en contestar...el cliente me ha estado pidiendo cosas y no habia podido contestar.

La propuesta que mi hizo escafandra, me parecio buena solo que el cliente me cambio las cosas ahora, solo quiere mostrar las mesas q están ocupadas, cosa que me resulto más fácil puesto q ya tenia algo elaborado.

Pero ahora me esta marcando un error de "Abstract error", al momento de querer "borrar" el objecto Button de un ScrollBox. Les explico:

Al momento de Pintar el form "Comandero" en OnPaint, mandó ejecutar el siguiente codigo, para crear los botones, siempre y cuando existieran comandas sin haberse impreso..aqui el codigo:
Código Delphi [-]
procedure TfrmMesasAbiertas.FormPaint(Sender: TObject);
begin
     while ScrollBox1.ControlCount>0 do
         ScrollBox1.Controls[0].Free;

    if ScrollBox1.ControlCount=0 then
    begin
       qryMesa.Close;
       qryMesa.Open;
       if not(qryMesa.IsEmpty) then
       begin
           FormShow(Sender);
           qryMesa.First;
           While not(qryMesa.Eof) do
           begin
                nFolio:=qryMesa.fieldByName('folio_ticket_comanda').AsString;
                nAliasEmpleado:=qryMesa.fieldByName('alias_empleado').AsString;
                nIDMesa:=qryMesa.fieldByName('mesa_num').AsString+qryMesa.FieldByName('literal').AsString;
                CrearBoton2();
                qryMesa.Next;
           end;
       end;
    end;
end;

Cuando el form se pinta, se ejecuta el codigo anterior, creando los botones en cada iteracion con "CrearBoton2()", ahora el boton representa a la mesa y al dar click muestra el detalle en otro form:
Código Delphi [-]
      
procedure TfrmMesasAbiertas.BitBtn1Click(Sender: TObject);
begin
//      bCaption:=TBitBtn(Sender).Hint;
//      IdRegistro:=TBitBtn(Sender).Tag;
      BD.n_IDRegistro:=TBitBtn(Sender).Tag;
      BD.n_Bandera:=1;
      frmAbreMesa.AbreTransaccion();
      if FindComponent('frmDetalleComanda') = nil then
           frmDetalleComanda:=TfrmDetalleComanda.Create(self);
      frmDetalleComanda.ShowModal;
end;

Procedimiento que crea los botones "CrearBoton2()":
Código Delphi [-]
procedure TfrmMesasAbiertas.CrearBoton2();
begin
     n:=n+1;
     Botones[n]:=TBitBtn.Create(Self);
     with Botones[n] do
     begin
         Caption:=nIDMesa+'-'+nAliasEmpleado;
         Hint:=nIDMesa;
         Parent:=ScrollBox1;
         Height:=vHeight;
         PosY:=PosY+Height+10;
         if n>1 then
            vLeft:=vLeft+126;
         if vLeft=1270 then
         begin
             vTop:=vTop+87;
             vLeft:=10;
         end;
         Top:=vTop;
         Left:=vLeft;
         Width:=vWidth;
         OnClick:=BitBtn1Click;
         Name:='btn'+IntToStr(n);
         Font.Size:=13;
         Tag:=qryMesa.fieldByName('registro_id').AsInteger;
         IdRegistro:=qryMesa.fieldByName('registro_id').AsInteger;
         Glyph:=BitBtn1.Glyph;
         Layout:=blGlyphTop;
     end;
end;


Y desde el frmDetalleComanda, envio a imprsion en ticket:

Código Delphi [-]
    
procedure TfrmDetalleComanda.sBtnImprimirClick(Sender: TObject);
begin
    qrTicket.qryCantLetra.Close;
    qrTicket.qryCantLetra.ParamByName('id').AsInteger:=qryMaestro.fieldByName('registro_id').AsInteger;
    qrTicket.qryCantLetra.Open;

    qrTicket.qryTicket.Close;
    qrTicket.qryTicket.ParamByName('registro_id').AsInteger:=qryMaestro.fieldByName('registro_id').AsInt  eger;
    qrTicket.qryTicket.Open;
    qrTicket.QuickRep1.Print;
    frmMesasAbiertas.Comandero(Sender); //Al llegar aqui manda el error "Abstract error" !!
    Close;
end;

En codigo anterior, despues de imprimir el ticket, mando llamar al procedimiento "Comandero" que esta en el form MesasAbiertas, que es el código que puse arriba...y a la hora de ejecutarlo me genere el Error "Abstract error". Checando el código, en ningun lado elimino los elementos creados en un Array que tengo del tipo TBitBtn....talvez sea por esto que me marca el error ????.....

Con este codigo elimino los objectos TBitBtn creados dentro del ScollBox, pero no del array.....
Código Delphi [-]
     while ScrollBox1.ControlCount>0 do
         ScrollBox1.Controls[0].Free;

No andara por aqui el problema....y si es asi...como elimino todo lo q contiene el array, para volver crearlos dentro del array...???

Gracias por sus comentarios y su valioso tiempo....saludos !!!
__________________
Miguel Román

Afectuoso saludo desde tierras mexicanas....un aguachile?, con unas "cetaseas" bien "muertas"?, VENTE PUES !!

Última edición por mRoman fecha: 23-04-2017 a las 07:24:29.
Responder Con Cita
  #5  
Antiguo 23-04-2017
Avatar de escafandra
[escafandra] escafandra is offline
Miembro Premium
 
Registrado: nov 2007
Posts: 2.195
Poder: 20
escafandra Tiene un aura espectacularescafandra Tiene un aura espectacular
Cita:
Empezado por mRoman Ver Mensaje
No andara por aqui el problema....y si es asi...como elimino todo lo q contiene el array, para volver crearlos dentro del array...???
Si. Cada botón referenciado en el array es el mismo que el localizado en ScrollBox1, por lo que si lo borras de un lado, lo has borrado. Por otra parte, no es buena idea crear los botones en el OnPaint, ya que se volverán a creas cada vez que se pinte el formulario y esa situación puede repetirse muchas veces siendo dependiente Windows y de otras aplicaciones que se superpongan. Es mejor crear los botones solo una vez y esconder los que no te hagan falta simplemente dejándolos inactivos, o si prefieres, haciéndolos no visibles:
Código Delphi [-]
 
BitBtn1.Visible:= false;

Saludos.
Responder Con Cita
  #6  
Antiguo 24-04-2017
Avatar de mRoman
mRoman mRoman is offline
Miembro
 
Registrado: nov 2003
Posts: 599
Poder: 21
mRoman Va por buen camino
Cita:
Empezado por escafandra Ver Mensaje
Si. Cada botón referenciado en el array es el mismo que el localizado en ScrollBox1, por lo que si lo borras de un lado, lo has borrado. Por otra parte, no es buena idea crear los botones en el OnPaint, ya que se volverán a creas cada vez que se pinte el formulario y esa situación puede repetirse muchas veces siendo dependiente Windows y de otras aplicaciones que se superpongan. Es mejor crear los botones solo una vez y esconder los que no te hagan falta simplemente dejándolos inactivos, o si prefieres, haciéndolos no visibles:
Código Delphi [-]
 
BitBtn1.Visible:= false;

Saludos.
Te agradezco escafandra, por contestar. Entonces quieres decir que si lo borro del ScrollBox...automáticamente tambien se elimina del Array ???. Efectivamente, el código dentro del OnPaint, es latoso....visiblemente es molesto, cada vez q se pinte el formulario, se generen los botones, ya lo quite de ahi.

Me comentas que los botones crearlos 1 sola vez y dejarlos visibles o no visibles dependiendo, esta era mi mejor carta pero el cliente tiene mesas que se hacen 2...se dividen, si creo desde un inicio la mesa 23 (por decir algo), luego si esa mesa la dividen, se convierte o la identifican como mesa 23-A, entonces...seria un boton nuevo??...lo anterior puede susceder para todas las mesas, entonces crear los botones desde un inicio....o como lo haria para cuando pase esto??. Se me viene a la mente, mejor crear los botones conforme se vayan abriendo las mesas...Sé que 23-A, 11-A, 10-A, 10-B, al final de cuentas vienen siendo mesas, entonces, con una "ALIAS" podriamos resolverlo??..puediera ser, independientemente de que el ID de la mesa sea un número distinto....(no se me habia ocurrido lo del alias!!).

En breve les enviaré mejor todo el código que tengo y que hace todo el "circo".....los que postee al inicio de este hilo, es solo una parte.

Saludos. !!!
__________________
Miguel Román

Afectuoso saludo desde tierras mexicanas....un aguachile?, con unas "cetaseas" bien "muertas"?, VENTE PUES !!
Responder Con Cita
Respuesta


Herramientas Buscar en Tema
Buscar en Tema:

Búsqueda Avanzada
Desplegado

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
Crear Form en tiempo de ejecución mjjj OOP 2 19-01-2012 20:11:54
Crear Form en tiempo de Ejecución harvicoco Varios 3 28-06-2006 15:55:05
Crear Componentes en tiempo de ejecucion fartycl Varios 3 21-06-2006 23:03:13
Crear un DSN en tiempo de ejecucion neyvan Conexión con bases de datos 7 21-05-2004 18:41:45


La franja horaria es GMT +2. Ahora son las 11:54:11.


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