Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > OOP
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Grupo de Teaming del ClubDelphi

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 20-05-2020
Avatar de mRoman
mRoman mRoman is offline
Miembro
 
Registrado: nov 2003
Posts: 599
Poder: 21
mRoman Va por buen camino
Llenar TreeView desde una tabla

Hola amigos buenas noches.

Iniciando con un proyecto. Trabajo Delphi6/Firebird 2.0/Win10

Explico:

Quiero llenar un TreeView con las opciones del menu principal y en cada Nodo agregar un checkbox para que el usuario pueda habilitar o deshabilitar dicha opción. Esta selección deberá ser guardada en una tabla etiquetando esta configuración con un nombre para después ser asignado a un USUARIO del sistema.

Hasta ahorita he consultado un código de Neftali que hace justamente esto, agregar un checkbox a cada nodo, pero no se como almacenarlo en una tabla y luego ser recuperado para volver a llenar el TreeView con esta configuración de opciones del menu y poder modificarlo si asi lo desea el usuarios-administrador.

Vi este video, el cual el código es de visual basic, pero la verdad no le entiendo bien, pero de ahi tomé la estructuras de las tablas tratando de hacer lo que quiero pero no doy bien...me es complicado el manejo de TreeView, almacenarlo para despues recuperarlo de la tabla, montarlo en el treeview y estando ahí, modificarlo si es necesario...(habilitar/deshabilitar).
(Me gustaría mas tomar las opciones de una tabla que desde el mismo TMainMenu)

Talvez me este complicando de mas, pero me gustaría poder hacerlo con treeview, q el usuario seleccione las opciones a habilitar y después grabarlo para asignarlo posteriormente a un usuario. Esta forma de quererlo hacer es porque me parece una manera muy fácil y gráfica, para el usuario final, para que a el le sea mas fácil y de mejor compresión, la habilitación o deshabilitación de opciones.

También he consultado los diferentes hilos de este club asi como otros, y he leido que lo han desarrollado de diferentes formas, desde NIVELES del 1 al 5 usando el TAG hasta configurar formularios con permisos especiales a ejecutar, dentro del mismo formulario(ALTAS, BAJAS, CAMBIOS, IMPRIMIR,etc), que me parecen bien, pero no es lo que busco.

Espero haberme explicado.

Saludos y muchas gracias por su tiempo.

p.d. Tengo esta tabla
Código SQL [-]
CREATE TABLE SEG_OPCIONES_MENU (
    NODO_PADRE       INTEGER NOT NULL,
    NODO             INTEGER NOT NULL,
    OPC_DESCRIPCION  VARCHAR(50),
    OPC_TAG          INTEGER
);
__________________
Miguel Román

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

Última edición por mRoman fecha: 20-05-2020 a las 04:51:08.
Responder Con Cita
  #2  
Antiguo 20-05-2020
Avatar de Neftali [Germán.Estévez]
Neftali [Germán.Estévez] Neftali [Germán.Estévez] is offline
[becario]
 
Registrado: jul 2004
Ubicación: Barcelona - España
Posts: 18.285
Poder: 10
Neftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en bruto
Cita:
Empezado por mRoman Ver Mensaje
...pero no se como almacenarlo en una tabla y luego ser recuperado para volver a llenar el TreeView con esta configuración de opciones del menu y poder modificarlo si asi lo desea el usuarios-administrador.
Al final sólo debes recorrer los nodos del TreeView y para cada nodo crear un registro en la tabla que has adjuntodo.
¿Cual es el problema concretamente?
¿El recorrido del TreeView, guardarlo en la tabla?

Para recuperar lo contrario, realizar un recorrido por toda la tabla e ir creando los nodos en el TreeView.
Lo mismo de antes. ¿Cual es concretamente el problema? ¿Hacer el recorrido, crear los nodos en runtime?
__________________
Germán Estévez => Web/Blog
Guía de estilo, Guía alternativa
Utiliza TAG's en tus mensajes.
Contactar con el Clubdelphi

P.D: Más tiempo dedicado a la pregunta=Mejores respuestas.
Responder Con Cita
  #3  
Antiguo 20-05-2020
Avatar de mRoman
mRoman mRoman is offline
Miembro
 
Registrado: nov 2003
Posts: 599
Poder: 21
mRoman Va por buen camino
Cita:
Empezado por Neftali [Germán.Estévez] Ver Mensaje
Al final sólo debes recorrer los nodos del TreeView y para cada nodo crear un registro en la tabla que has adjuntodo.
¿Cual es el problema concretamente?
¿El recorrido del TreeView, guardarlo en la tabla?

Para recuperar lo contrario, realizar un recorrido por toda la tabla e ir creando los nodos en el TreeView.
Lo mismo de antes. ¿Cual es concretamente el problema? ¿Hacer el recorrido, crear los nodos en runtime?
Hola Neftalí gracias por contestar.

Si, esto es el problema:
Cita:
¿Hacer el recorrido, crear los nodos en runtime? /*DESDE EL DATASET*/
Y también esto otro:
Cita:
¿El recorrido del TreeView, guardarlo en la tabla?
Mi problema es este:
Cita:
me es complicado el manejo de TreeView, almacenarlo para después recuperarlo de la tabla, montarlo en el treeview y estando ahí, modificarlo si es necesario...(habilitar/deshabilitar).
(y luego grabarlo otra vez en la tabla)

No sé como hacerlo. No sé como implementar código para hacer esto. Mostrar las opciones tomándolas de un DATASET -ligado obviamente a una tabla con todas las opciones del menu-, estando éstas cargadas al TreeView seleccionar cuales si y cuales no serán visibles para el usuario, y luego grabar esta configuración en la TABLA para luego ser asignado a cualquier usuario...como permisos de acceso al menu del sistema.

Estoy tratando con el siguiente código (q lo tome de uno de los foros consultados) de implementarlo para lo que quiero, pero en realidad apenas lo estoy analizando...

Código Delphi [-]
procedure TfrmSegMenuNiv.CargarTreeView;
var
   i,x,n:integer;
   Nod : TTreeNode;
   NodSuplementario : TTreeNode;
   MiPunteroInteger : ^integer;
begin
    qryMenu.Close;
    qryMenu.Open;
    qryMenu.Last;
    n:=qryMenu.RecordCount;
    qryMenu.First;
    for x:=0 to (n-1) do
    begin
         i:=qryMenu.FieldByName('nodo_padre').AsInteger;
         if i=0 then
           begin
              Nod:=TreeView1.Items.Add (nil,qryMenu.FieldByName('opc_Descripcion').asstring);
              New(MiPunteroInteger);
              MiPunteroInteger^:=qryMenu.Fieldbyname('nodo').asinteger;
              nod.Data:=MiPunteroInteger;
              nod.Selected :=true;
           end
         Else
           begin
               n:=TreeView1.Items.Count-1;
               While MiPunteroInteger(TreeView1.Items[n].Data)^ <> i do
                  Dec(n);
               nodSuplementario:=TreeView1.Items.AddChild(TreeView1.Items[N],qryMenu.FieldByName('opc_Descripcion').asstring);
               New(MiPunteroInteger);
               MiPunteroInteger^:= qryMenu.Fieldbyname('nodo').asinteger;
               nodSuplementario.Data:=MiPunteroInteger;
               Nod.selected:=True;
               Nod.Expanded:=False;
            end;
         qryMenu.Next;
    end;
end;


Espero me puedas/puedan orientar.

MUCHAS GRACIAS !! por tu tiempo

Saludos.
__________________
Miguel Román

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

Última edición por Casimiro Notevi fecha: 20-05-2020 a las 18:21:13.
Responder Con Cita
  #4  
Antiguo 21-05-2020
Avatar de Neftali [Germán.Estévez]
Neftali [Germán.Estévez] Neftali [Germán.Estévez] is offline
[becario]
 
Registrado: jul 2004
Ubicación: Barcelona - España
Posts: 18.285
Poder: 10
Neftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en bruto
Creo que es más sencillo...
Con este código puedes recorrer el treeview y almacenar en la tabla ls items:
Código Delphi [-]
var
  i:integer;
  tv:TTreeNode;
begin
  tblOpcMenu.Open;                                      // Abrir la tabla
  for i := 0 to (TreeView1.Items.Count -1) do begin     // recorro el treeview
    tv := TreeView1.Items[i];                           // accedo al nodo
    tblOpcMenu.Append;
    // Si es un nodo de primer nivel (-1), si no, me apunto el padre
    tblOpcMenu.FieldByName('NODO_PADRE').AsString := ifThen(Assigned(tv.Parent), tv.Parent.Index.ToString, '-1');
    tblOpcMenu.FieldByName('NODO').AsInteger := tv.Index;
    tblOpcMenu.FieldByName('OPC_DESCRIPCION').AsString := tv.Text;
    tblOpcMenu.FieldByName('OPC_TAG').AsInteger := tv.AbsoluteIndex;

    tblOpcMenu.Post;
  end;
  tblOpcMenu.Close;


Y con este otro recuperrarlos y añadirlos a un Treeview vacío:
Código Delphi [-]
var
  i, iParent:integer;
  tv, tvParent:TTreeNode;
begin
  tblOpcMenu.Open;                         // Abrir la tabla
  while not tblOpcMenu.Eof do begin        // Recorrer los registros hasta el final
    iParent := tblOpcMenu.FieldByName('NODO_PADRE').AsInteger;     // buscar el nodo padre (los de primer nivel = -1)
    if (iParent = -1) then begin           // Los de primer nivel...
      tv := TreeView1.Items.Add(nil, tblOpcMenu.FieldByName('OPC_DESCRIPCION').AsString);   // Se añaden
      tvParent := tv;                      // es un nodo padre
    end
    else                                   // Los que no son de primer nivel, loos añado al padre
      tv := TreeView1.Items.AddChild(tvParent, tblOpcMenu.FieldByName('OPC_DESCRIPCION').AsString);
    tblOpcMenu.Next;
  end;
  tblOpcMenu.Close;
__________________
Germán Estévez => Web/Blog
Guía de estilo, Guía alternativa
Utiliza TAG's en tus mensajes.
Contactar con el Clubdelphi

P.D: Más tiempo dedicado a la pregunta=Mejores respuestas.
Responder Con Cita
  #5  
Antiguo 21-05-2020
Avatar de mRoman
mRoman mRoman is offline
Miembro
 
Registrado: nov 2003
Posts: 599
Poder: 21
mRoman Va por buen camino
Cita:
Empezado por Neftali [Germán.Estévez] Ver Mensaje
Creo que es más sencillo...
Con este código puedes recorrer el treeview y almacenar en la tabla ls items:
Código Delphi [-]
var
  i:integer;
  tv:TTreeNode;
begin
  tblOpcMenu.Open;                                      // Abrir la tabla
  for i := 0 to (TreeView1.Items.Count -1) do begin     // recorro el treeview
    tv := TreeView1.Items[i];                           // accedo al nodo
    tblOpcMenu.Append;
    // Si es un nodo de primer nivel (-1), si no, me apunto el padre
    tblOpcMenu.FieldByName('NODO_PADRE').AsString := ifThen(Assigned(tv.Parent), tv.Parent.Index.ToString, '-1');
    tblOpcMenu.FieldByName('NODO').AsInteger := tv.Index;
    tblOpcMenu.FieldByName('OPC_DESCRIPCION').AsString := tv.Text;
    tblOpcMenu.FieldByName('OPC_TAG').AsInteger := tv.AbsoluteIndex;

    tblOpcMenu.Post;
  end;
  tblOpcMenu.Close;


Y con este otro recuperrarlos y añadirlos a un Treeview vacío:
Código Delphi [-]
var
  i, iParent:integer;
  tv, tvParent:TTreeNode;
begin
  tblOpcMenu.Open;                         // Abrir la tabla
  while not tblOpcMenu.Eof do begin        // Recorrer los registros hasta el final
    iParent := tblOpcMenu.FieldByName('NODO_PADRE').AsInteger;     // buscar el nodo padre (los de primer nivel = -1)
    if (iParent = -1) then begin           // Los de primer nivel...
      tv := TreeView1.Items.Add(nil, tblOpcMenu.FieldByName('OPC_DESCRIPCION').AsString);   // Se añaden
      tvParent := tv;                      // es un nodo padre
    end
    else                                   // Los que no son de primer nivel, loos añado al padre
      tv := TreeView1.Items.AddChild(tvParent, tblOpcMenu.FieldByName('OPC_DESCRIPCION').AsString);
    tblOpcMenu.Next;
  end;
  tblOpcMenu.Close;
Gracias Neftali por contestar. Lo aplico y haré mis comentarios al respecto. Todo esto es porq estoy desarrollando el módulo de seguridad del sistema, crear usuarios, roles y configuraciones de las opciones del menu principal del sistema...que es el tema q nos ocupa.

Nuevamente gracias y estamos pendientes...

Saludos.
__________________
Miguel Román

Afectuoso saludo desde tierras mexicanas....un aguachile?, con unas "cetaseas" bien "muertas"?, VENTE PUES !!
Responder Con Cita
  #6  
Antiguo 22-05-2020
Avatar de mRoman
mRoman mRoman is offline
Miembro
 
Registrado: nov 2003
Posts: 599
Poder: 21
mRoman Va por buen camino
Hola Neftali

Estoy analizando tu código que muy amablemente me respondiste. Tengo una duda, manejas otra versión de Delphi?, yo uso Delphi6, lo anterior debido a la siguiente instrucción:

Código:
 tblOpcMenu.FieldByName('NODO_PADRE').AsString := ifThen(Assigned(tv.Parent), tv.Parent.Index.ToString, '-1');
(IfThen)
Mi delphi no la reconoce...
__________________
Miguel Román

Afectuoso saludo desde tierras mexicanas....un aguachile?, con unas "cetaseas" bien "muertas"?, VENTE PUES !!
Responder Con Cita
  #7  
Antiguo 22-05-2020
Avatar de Neftali [Germán.Estévez]
Neftali [Germán.Estévez] Neftali [Germán.Estévez] is offline
[becario]
 
Registrado: jul 2004
Ubicación: Barcelona - España
Posts: 18.285
Poder: 10
Neftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en bruto
Es un IF..THEN..ELSE abreviado que tienen las últimas verisones de delphi.
http://docwiki.embarcadero.com/Libra...trUtils.IfThen


Al final es equivalente a poner:
Código Delphi [-]
if Assigned(tv.Parent) then
  tblOpcMenu.FieldByName('NODO_PADRE').AsString := tv.Parent.Index.ToString
else
  tblOpcMenu.FieldByName('NODO_PADRE').AsString :=  '-1';

Usar el ToString, es equivalente à la función IntToStr, BoolToStr,...

Código Delphi [-]
  Str:= tv.Parent.Index.ToString;

// Es equivalente a:


  Str := IntToStr(tv.Parent.Index);
__________________
Germán Estévez => Web/Blog
Guía de estilo, Guía alternativa
Utiliza TAG's en tus mensajes.
Contactar con el Clubdelphi

P.D: Más tiempo dedicado a la pregunta=Mejores respuestas.
Responder Con Cita
  #8  
Antiguo 22-05-2020
Avatar de mRoman
mRoman mRoman is offline
Miembro
 
Registrado: nov 2003
Posts: 599
Poder: 21
mRoman Va por buen camino
Cita:
Empezado por Neftali [Germán.Estévez] Ver Mensaje
Creo que es más sencillo...

[/delphi]
Que tal Neftali

Anexo el código completo donde se carga las opciones del menu principal, agregando un checkbox a cada opción, para habilitar o deshabilitar la misma, para mas adelante, cuando se conecta el usuario al sistema, solo vea las opciones habilitadas, bueno ya se graba la información a la tabla -que por cierto le agregue campos-, pero como que el arbol no lo esta cargando bien desde la tabla, es decir, las subopciones no las inserta en los niveles que son.

Aparte estoy buscando la forma de como saber que opciones tiene CHECKED en el treeview para almacenar el dato y me sirva para habilitar o deshabilitar.

Envio el código completo: (Tengo un pagecontrol en el mismo formulario y hay código que nada que ver con el TreeView)

Código Delphi [-]
unit SegMenuNiv;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ComCtrls, Buttons, ToolWin, ExtCtrls, CommCtrl, StdCtrls, Mask,  DB,
  IBCustomDataSet, DBCtrls, sSkinProvider, IBQuery, Menus, IBTable, StrUtils;

type
  TfrmSegMenuNiv = class(TForm)
    Panel2: TPanel;
    PageControl1: TPageControl;
    TabSheet1: TTabSheet;
    TabSheet2: TTabSheet;
    Panel1: TPanel;
    Panel4: TPanel;
    Label1: TLabel;
    mskIDMenu: TMaskEdit;
    GroupBox1: TGroupBox;
    dsTipoMenu: TIBDataSet;
    dSoTipoMenu: TDataSource;
    dsTipoMenuMENU_TIPO_ID: TSmallintField;
    dsTipoMenuMENU_TIPO_DESCRIP: TIBStringField;
    dsTipoMenuMENU_HABILITAR: TIBStringField;
    DBEdit1: TDBEdit;
    Panel3: TPanel;
    btnGrabar: TBitBtn;
    btnCancelar: TBitBtn;
    sSkinProvider1: TsSkinProvider;
    Panel5: TPanel;
    Panel7: TPanel;
    Panel8: TPanel;
    Label2: TLabel;
    cbxTipoMenu: TDBLookupComboBox;
    GroupBox2: TGroupBox;
    TreeView1: TTreeView;
    Panel6: TPanel;
    btnGrabarCFG: TBitBtn;
    btnCancelarCFG: TBitBtn;
    GroupBox3: TGroupBox;
    DBCheckBox1: TDBCheckBox;
    btnEliminar: TBitBtn;
    qryTipoMenu: TIBQuery;
    dSoTipoMenuCFG: TDataSource;
    qryTipoMenuMENU_TIPO_ID: TSmallintField;
    qryTipoMenuMENU_TIPO_DESCRIP: TIBStringField;
    qryTipoMenuMENU_HABILITAR: TIBStringField;
    dsMenuOpCFG: TIBDataSet;
    dSoMenuOpCFG: TDataSource;
    qryMenu: TIBQuery;
    btnEliminarCFG: TBitBtn;
    qryMenuNODO_PADRE: TIntegerField;
    qryMenuNODO: TIntegerField;
    qryMenuOPC_DESCRIPCION: TIBStringField;
    qryMenuOPC_TAG: TIntegerField;
    tblOpcMenu: TIBTable;
    dsMenuOpCFGMENU_TIPO_ID: TSmallintField;
    dsMenuOpCFGNODO: TIntegerField;
    dsMenuOpCFGNODO_PADRE: TIntegerField;
    dsMenuOpCFGOPC_VISIBLE: TIBStringField;
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure Panel1Enter(Sender: TObject);
    procedure Panel1Exit(Sender: TObject);
    procedure btnGrabarClick(Sender: TObject);
    procedure btnEliminarClick(Sender: TObject);
    procedure btnCancelarClick(Sender: TObject);
    procedure FormShow(Sender: TObject);
    procedure Panel7Enter(Sender: TObject);
    procedure cbxTipoMenuCloseUp(Sender: TObject);
    procedure TreeView1Click(Sender: TObject);
    procedure btnGrabarCFGClick(Sender: TObject);
  private
    { Private declarations }
    procedure ToggleTreeViewCheckBoxes(Node:TTreeNode; cUnChecked, cChecked: Integer);
  public
    { Public declarations }
      i, iParent:integer;
      tv, tvParent:TTreeNode;
  end;

var
  frmSegMenuNiv: TfrmSegMenuNiv;
const cStateUnCheck = 1;
      cStateChecked = 2;

implementation
uses ModuloBD,MenuPrincipal;
{$R *.dfm}

procedure TfrmSegMenuNiv.FormClose(Sender: TObject;
  var Action: TCloseAction);
begin
   Action:=caFree;
end;

procedure TfrmSegMenuNiv.Panel1Enter(Sender: TObject);
begin
   dMod.trscMMS.Active:=False;
   dMod.trscMMS.StartTransaction;
   mskIDMenu.Text:='';
   
   btnGrabar.Enabled:=False;
   btnEliminar.Enabled:=False;
   btnCancelar.Enabled:=False;
end;

procedure TfrmSegMenuNiv.Panel1Exit(Sender: TObject);
begin
    dsTipoMenu.Close;
    dsTipoMenu.ParamByName('menu_id').AsString:=mskIDMenu.Text;
    dsTipoMenu.Open;
    if dsTipoMenu.IsEmpty then
    begin
         btnGrabar.Enabled:=True;
         btnEliminar.Enabled:=False;
         btnCancelar.Enabled:=True;
         dsTipoMenu.Append;
         dsTipoMenu.FieldByName('menu_tipo_id').AsString:=mskIDMenu.Text;
    end Else
    begin
         btnGrabar.Enabled:=True;
         btnEliminar.Enabled:=True;
         btnCancelar.Enabled:=True;
         dsTipoMenu.Edit;
    end;
end;

procedure TfrmSegMenuNiv.btnGrabarClick(Sender: TObject);
begin
    try
       dsTipoMenu.Post;
       dsTipoMenu.ApplyUpdates;
       dMod.trscMMS.Commit;
       Application.MessageBox('Datos grabados correctamente','Aviso',mb_ok+mb_IconInformation);
    except
       on E: Exception do
       begin
          Application.MessageBox('Los registros no pueden ser grabados, consulte al administrador del sistema','Error', mb_ok+mb_IconError);
          ShowMessage(E.Message);
          dMod.trscMMS.Rollback;
       end;
    end;
    mskIDMenu.SetFocus;
end;

procedure TfrmSegMenuNiv.btnEliminarClick(Sender: TObject);
begin
    try
       dsTipoMenu.Delete;
       dsTipoMenu.ApplyUpdates;
       dMod.trscMMS.Commit;
       Application.MessageBox('El Registro ha sido eliminado de forma correcta','Aviso',mb_ok+mb_IconInformation);
    except
       on E: Exception do
       begin
          Application.MessageBox('El Registro no se puede eliminar, consulte al administrador del sistema','Error', mb_ok+mb_IconError);
          ShowMessage(E.Message);
          dMod.trscMMS.Rollback;
       end;
    end;
    mskIDMenu.SetFocus;
end;

procedure TfrmSegMenuNiv.btnCancelarClick(Sender: TObject);
begin
     mskIDMenu.SetFocus;
end;

procedure TfrmSegMenuNiv.FormShow(Sender: TObject);
begin
    PageControl1.ActivePageIndex:=0;
    mskIDMenu.SetFocus;
end;

procedure TfrmSegMenuNiv.Panel7Enter(Sender: TObject);
begin
    dMod.trscMMS.Active:=False;
    dMod.trscMMS.StartTransaction;
    btnGrabarCFG.Enabled:=False;
    btnEliminarCFG.Enabled:=False;
    btnCancelarCFG.Enabled:=False;
    dsMenuOpCFG.Close;
    qryMenu.Close;
    qryTipoMenu.Close;
    qryTipoMenu.Open;
    qryTipoMenu.FetchAll;

end;

procedure TfrmSegMenuNiv.cbxTipoMenuCloseUp(Sender: TObject);
  //--------------------------------------------------------------------------
  procedure VerificaMenu(Menu: TMenuItem; Nod: TTreeNode);
  Var
    i: Integer;
    Nodo: TTreeNode;
  Begin
    // Para cada elemento del menu
    for i:= 0 To (Menu.Count - 1) Do Begin
      // Es un elemento correcto
      If Not(Menu.Parent Is TMenuItem) then begin
          // Crear el elemento  asignarle el índice de la imagen
          Nodo:= TreeView1.Items.Add(Nil, Menu.Items[i].Caption);
          Nodo.ImageIndex := Menu.Items[i].ImageIndex;
      End
      Else begin
        // Crear un hijo
        Nodo:= TreeView1.Items.AddChild(Nod, Menu.Items[i].Caption);
        Nodo.ImageIndex := Menu.Items[i].ImageIndex;
      end;

      // Llamada recursiva para los submenus
      If Menu.Items[i].Count > 0 Then begin
        VerificaMenu(Menu.Items[i], Nodo);
      end;
    End;
  End;
  //--------------------------------------------------------------------------

begin
  // Pasar el menú
  tblOpcMenu.Filter:='MENU_TIPO_ID='+IntToStr(cbxTipoMenu.KeyValue);
  tblOpcMenu.Filtered:=True;
  tblOpcMenu.Open;
  if tblOpcMenu.IsEmpty then
  begin
      btnGrabarCFG.Caption:='Grabar';
      btnGrabarCFG.Enabled:=True;
      btnEliminarCFG.Enabled:=False;
      btnCancelarCFG.Enabled:=False;
      VerificaMenu(frmMenu.MainMenu1.Items, Nil);
      SetWindowLong(TreeView1.Handle, GWL_STYLE, GetWindowLong(TreeView1.Handle, GWL_STYLE) or TVS_CHECKBOXES);
      TreeView1.FullExpand;
      TreeView1.Items.Item[0].Selected:=True;
  end Else
  begin
      btnGrabarCFG.Caption:='Actualizar';
      btnGrabarCFG.Enabled:=True;
      btnEliminarCFG.Enabled:=True;
      btnCancelarCFG.Enabled:=True;
      tblOpcMenu.First;
      while not tblOpcMenu.Eof do
      begin        // Recorrer los registros hasta el final
          iParent := tblOpcMenu.FieldByName('NODO_PADRE').AsInteger;     // buscar el nodo padre (los de primer nivel = -1)
          if (iParent = -1) then begin           // Los de primer nivel...
             tv := TreeView1.Items.Add(nil, tblOpcMenu.FieldByName('OPC_DESCRIPCION').AsString);   // Se añaden
             tvParent := tv;                      // es un nodo padre
          end
          else                                   // Los que no son de primer nivel, loos añado al padre
             tv := TreeView1.Items.AddChild(tvParent, tblOpcMenu.FieldByName('OPC_DESCRIPCION').AsString);
          tblOpcMenu.Next;
      end;
      tblOpcMenu.Close;
  end;
end;

procedure TfrmSegMenuNiv.TreeView1Click(Sender: TObject);
var
   P: TPoint;
begin
   GetCursorPos(P);
   P := TreeView1.ScreenToClient(P);
   if (htOnStateIcon in TreeView1.GetHitTestInfoAt(P.X, P.Y)) then
      ToggleTreeViewCheckBoxes(TreeView1.Selected, cStateUnCheck, cStateChecked);
end;

procedure TfrmSegMenuNiv.ToggleTreeViewCheckBoxes(Node: TTreeNode; cUnChecked,
  cChecked: Integer);
begin
   if Assigned(Node) then
   begin
      if Node.StateIndex = cUnChecked then
         Node.StateIndex := cChecked
      else if Node.StateIndex = cChecked then
         Node.StateIndex := cUnChecked;
   end;
end;


procedure TfrmSegMenuNiv.btnGrabarCFGClick(Sender: TObject);
var
  i, nNodoPadre : integer;
//  tv : TTreeNode;
begin

  tblOpcMenu.Open;                                      // Abrir la tabla
  for i := 0 to (TreeView1.Items.Count -1) do begin     // recorro el treeview
    tv := TreeView1.Items[i];                           // accedo al nodo
    tblOpcMenu.Append;
    // Si es un nodo de primer nivel (-1), si no, me apunto el padre
    if ( Assigned(tv.Parent) ) then
       nNodoPadre:=tv.Parent.Index
    else
       nNodoPadre:=-1;

    tblOpcMenu.FieldByName('MENU_TIPO_ID').AsInteger:=cbxTipoMenu.KeyValue;
    tblOpcMenu.FieldByName('NODO_PADRE').AsInteger := nNodoPadre;
    tblOpcMenu.FieldByName('NODO').AsInteger := tv.Index;
    tblOpcMenu.FieldByName('OPC_DESCRIPCION').AsString := tv.Text;
    tblOpcMenu.FieldByName('OPC_TAG').AsInteger := tv.AbsoluteIndex;
    tblOpcMenu.FieldByName('OPC_VISIBLE').AsInteger:=tv.StateIndex;

    tblOpcMenu.Post;

  end;
  tblOpcMenu.Close;
end;

end.

Espero me puedan ayudar a almacenar el CHECKED y el UNCHECKED de cada nodo en la tabla, que por cierto tuvo cambios:
Código SQL [-]
CREATE TABLE SEG_MENU_OPC_CONFIG (
    MENU_TIPO_ID     NUMERIC(2,0) NOT NULL,
    NODO_PADRE       INTEGER NOT NULL,
    NODO             INTEGER NOT NULL,
    OPC_VISIBLE      VARCHAR(5),
    OPC_DESCRIPCION  VARCHAR(60),
    OPC_TAG          INTEGER
);

Saludos y muchas gracias por su tiempo a todos.
__________________
Miguel Román

Afectuoso saludo desde tierras mexicanas....un aguachile?, con unas "cetaseas" bien "muertas"?, VENTE PUES !!
Responder Con Cita
  #9  
Antiguo 22-05-2020
Avatar de Neftali [Germán.Estévez]
Neftali [Germán.Estévez] Neftali [Germán.Estévez] is offline
[becario]
 
Registrado: jul 2004
Ubicación: Barcelona - España
Posts: 18.285
Poder: 10
Neftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en bruto
Tal vez deberías enviar un proyecto (puedes adjuntar un ZIP) con lo mínimo para poder probar el código.
__________________
Germán Estévez => Web/Blog
Guía de estilo, Guía alternativa
Utiliza TAG's en tus mensajes.
Contactar con el Clubdelphi

P.D: Más tiempo dedicado a la pregunta=Mejores respuestas.
Responder Con Cita
Respuesta



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
Llenar un Combobox con un campo de una tabla MySql. Desde un qry volcar los datos. juanpy PHP 9 12-10-2012 04:46:06
Llenar un qListBox desde una tabla MySql. RADPHP(Delphi for Php) juanpy PHP 2 07-03-2012 20:52:32
LLenar un TreeView en ejecucion con datos de una tabla canelita Varios 0 18-01-2008 22:34:03
Error al llenar tabla desde archivo txt bohemioloco Conexión con bases de datos 9 13-11-2006 13:49:54
Llenar menú desde Tabla... vladimirbp Varios 2 10-11-2006 18:26:53


La franja horaria es GMT +2. Ahora son las 20:12:21.


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