viernes, 12 de octubre de 2012

Llenando un Treeview desde un directorio en lazarus (Linux/Windows)

Bueno vengo a poner un ejemplo sencillo de como llenar un Treeview desde un directorio en Lazarus, algo curioso que note al portarlo a Linux y OsX es que el valor que la constante "faDirectory" en Windows toma un valor de "16" y en SO "Unix" toma el valor de "48" por ese detalle al principio no me listaba los directorios, después de ir viendo paso por paso los valores que tomaban me di cuenta de eso, solo agregamos una validación que identifique el SO en el que se esta ejecutando y ajustar ese valor.

En el ejemplo agregamos al evento OnClick de un botón el siguiente código:

procedure TfrmMain.btnAgregaMarcadorClick(Sender: TObject);
var
    lcSearch: TSearchRec;
    lcFileAttr: integer;
    lcFatherNode: TTreeNode;
    lcChildNode: TTreeNode;
    lcPath: String;
begin
    {$IFDEF UNIX}
        lcFileAttr:= 48;
    {$ELSE}
        lcFileAttr:= faDirectory;
    {$ENDIF}
    SelectDirectoryDialog1.Execute;
    lcPath:=SelectDirectoryDialog1.FileName;
    if Length(lcPath) > 0 then begin
        lcFatherNode:= TTreeNode.Create(TreeView1.Items);
        lcFatherNode:= TreeView1.Items.AddChild(TreeNodeRoot,lcPath);
        lcFatherNode.ImageIndex:=0;
        lcFatherNode.SelectedIndex:=0;
        lcFatherNode.Expanded:=True;
    end;
    lcPath:=lcPath+PathDelim;
    If FindFirst(lcPath+'*',faDirectory,lcSearch)=0 then begin
        repeat
            if lcSearch.Attr = lcFileAttr then begin
                if (lcSearch.Name = '.') or (lcSearch.Name = '..') then continue;
                lcChildNode:= TreeView1.Items.AddChild(lcFatherNode,lcSearch.Name);
                lcChildNode.ImageIndex:=0;
                lcChildNode.SelectedIndex:=0;
                AddDirectorios(lcChildNode,lcPath+lcSearch.Name);
            end;
        until FindNext(lcSearch) <> 0;
        FindClose(lcSearch);
    end;
   TreeView1.Refresh;
end;

El siguiente procedimiento lo agregamos nosotros, este será llamado desde nuestro anterior proceso cuando encuentre un directorio, y será llamado recursivamente desde él mismo agregando los nodos hijos con el nombre de los directorios encontrados.

procedure TfrmMain.AddDirectorios(elNodo: TTreeNode; cPath: String);
var
    sr: TSearchRec;
    lcFileAttr: Integer;
    theNewNode : tTreeNode;
begin
    {$IFDEF UNIX}
        lcFileAttr:= 48;
    {$ELSE}
        lcFileAttr:= faDirectory;
    {$ENDIF}

    if FindFirst(cPath+PathDelim+'*', faDirectory, sr) = 0 then begin
        repeat
            if sr.Attr = lcFileAttr then begin
                if (sr.Name = '.') or (sr.Name = '..') then continue;
                    theNewNode := TreeView1.Items.AddChild(elNodo,sr.name);
                    theNewNode.ImageIndex:=0;
                    theNewNode.SelectedIndex:=0;
                    AddDirectorios(theNewNode,cPath+PathDelim+sr.Name);
            end;
        until FindNext(sr) <> 0;
        FindClose(sr);
    end;
end;

No hay comentarios: