Clube Delphi 71
Esse artigo faz parte da revista Clube Delphi 71. Clique aqui para ler todos os artigos desta edição

Virtual TreeView

Sofistique suas aplicações com um TreeView profissional

A interface de um aplicativo sempre foi um fator determinante no sucesso ou no fracasso de um projeto. De nada adianta um código complexo rodando nos bastidores se a parte visual da aplicação não agradar o “todo-poderoso” usuário. E interagir corretamente com este “ser”, através de controles que tornem a utilização da aplicação mais fácil e intuitiva, pode determinar se você irá receber um email de elogio ou um telefonema mal-educado.

Uma boa maneira de se criar interfaces intuitivas e fáceis de utilizar é seguindo os padrões das grandes empresas de software, como a Microsoft, por exemplo. E esta companhia usa e abusa dos componentes que seu sistema operacional oferece, como o TreeView. O problema deste controle nativo é que ele não oferece muitas opções, tanto de flexibilidade quanto de apresentação. É aí que entra o componente que dá nome a este artigo: VirtualTreeView.

 

O componente

Criado em 2000 por Mike Lischke, este controle impressiona pela quantidade de recursos, onde a maioria absoluta não existe na opção do Windows. Coisas simples, como exibir checkboxes para cada item, ordenar os dados etc., que exigiriam certo esforço para codificar, estão ao alcance de meras propriedades. Para o leitor ter uma idéia da qualidade deste componente, basta saber que ele foi escolhido pela Borland para compor o IDE da versão 2005/2006 do Delphi. Vamos ver neste artigo as características mais importantes deste componente, que pode dar uma aparência extremamente profissional as suas aplicações.

 

Baixando e instalando

Acesse o site www.delphi-gems.com/VirtualTreeview/VT.php e baixe o instalador do componente. Certifique-se de ter o Delphi fechado antes de executá-lo. O programa de instalação irá criar automaticamente no registro uma entrada para a BPL necessária. O instalador possui versões para Delphi 4 a 2005 (e até você ler isso provavelmente para 2006) e C++ Builder 4 a 6. Abra o Delphi após o processo e veja a nova paleta adicionada (Figura 1). Observe que há três componentes: VirtualStringTree, VirtualDrawTree e VTHeaderPopupMenu. Neste artigo focaremos principalmente o VirtualStringTree.

 

imagem

Figura 1. Paleta Virtual Controls

 

Antes de começar: ponteiros

Um pré-requisito essencial para se poder trabalhar corretamente com o VirtualTreeView é conhecer sobre ponteiros. Um ponteiro denota um endereço de memória, armazenando o endereço de outra variável. Dizemos que ele aponta para o local daquela variável, ou para os dados armazenados por ela. Para se declarar um ponteiro de um tipo de dados, usa-se a seguinte sintaxe:

 

type NomeDoPonteiro = ^TipoDeDado

 

Isso quer dizer que NomeDoPonteiro representa ponteiros para variáveis do tipo TipoDeDado. O símbolo (^) também tem outra função. Se colocado no final do nome de uma variável do tipo de um ponteiro, ele “de-referencia” (em uma tradução literal de dereferences) o ponteiro, isto é, retorna o valor contido no endereço da memória armazenado por ele. Veja o código na Listagem 1:

 

Listagem 1. Exemplo de ponteiro

var

  S1, S2: string;

  P: ^string;

begin

  { S1 recebe um valor }

  S1 := 'ClubeDephi';

  { P aponta para o endereço de S1 }

  P := @S1;

  { S2 recebe o valor armazenado no endereço salvo

    por P }

  S2 := P^;

end;

 

O código anterior copia o valor de S1 em S2. Ou seja, simplesmente S1 := S2. Ponteiros são úteis por diversas razões. Em primeiro lugar, entendê-los irá ajudar você a compreender melhor a Delphi Language, uma vez que ponteiros quase sempre atuam implicitamente em qualquer código que você escreva. Além disso, tipos de dado que precisam de blocos grandes e dinâmicos de memória usam ponteiros. Isso vale para strings longas, como PChar e PWideChar, Algumas técnicas avançadas de programação, como API Hooking, vista até a edição anterior, fazem uso extensivo de ponteiros.

 

A interface da aplicação

Para começarmos a estudar o componente, vamos montar a interface da aplicação. Adicione no formulário principal de uma nova aplicação, inicialmente, os seguintes controles: um VirtualStringTree (“tvAgenda”), quatro LabeledEdit, um ComboBox, um Label e três Button. Organize-os no formulário conforme a Figura 2.

 

imagem

Figura 2. Interface da aplicação

 

Definindo uma estrutura de dados

O VirtualTreeView opera da seguinte forma: define-se a estrutura a ser armazenada, e só a preenchemos quando o seu elemento associado for acessado. Tal estrutura pode ser qualquer coisa referenciável através de um ponteiro. Portanto, tipos primitivos, records, arrays, objetos etc.

Tudo praticamente pode ser associado a um elemento dentro do componente. Como já mencionado, isso dá ampla flexibilidade para nós, desenvolvedores. Adicione uma nova unit ao projeto existente, vá ao Code Editor e na seção type da unit digite o código da Listagem 2.

 

Listagem 2. Estrutura de dados

type

  TSexo = (seMasculino, seFeminino);

  PRecordAgenda = ^TRecordAgenda;

  TRecordAgenda = record

    Nome,

    Endereco: string[50];

    Telefone: string[10];

    DataNascimento: TDate;

    Sexo: TSexo;

    HoraAdicao: TTime;

  end;

 

Repare que definimos o ponteiro para a estrutura criada: PRecordAgenda. É através dele que teremos acesso aos nossos dados, depois que forem incluídos no TreeView.

 

Cadê Items?

Provavelmente a primeira coisa que o leitor acostumado com o TreeView do Windows vai notar é a ausência da propriedade Items, responsável por armazenar e gerenciar os itens da árvore. Ela não está presente porque o VirtualTreeView usa uma abordagem diferente para manter os dados.

Para entender esse mecanismo, relembremos antes como se comporta o TreeView da Microsoft. Nele, os elementos da árvore são do tipo TTreeNode, que publica alguns métodos, propriedades e eventos. Já no componente VirtualTreeView, os elementos são do tipo de dados que você quiser. Isso oferece uma grande flexibilidade na hora de armazenar dados.

 

Nota: Você poderia simular algo parecido através da propriedade Data da classe TTreeNode, fornecendo um ponteiro para a estrutura desejada.

Se Items não existe, como incluir itens na TreeView? Simples, mas não trivial, como veremos a seguir.

 

Adicionando elementos

Sabendo como os dados serão armazenados, temos que dizer isso para a TreeView, através da propriedade NodeDataSize. Ela recebe o valor, em bytes, que deve ser reservado na memória para cada elemento criado. Também devemos informar ao componente quantos elementos serão criados. Nesse caso, usa-se a propriedade RootNodeCount. Como o próprio nome diz, ela indica a quantidade de itens-raiz, isso é, que estarão no topo da hierarquia de nós da árvore.

 

Nota: Ambas as propriedades podem ser configuradas em design time. Porém, é difícil saber qual valor colocar em NodeDataSize só olhando para a estrutura que criamos. É mais prático e seguro definir isso em tempo de execução.

Então, no evento OnCreate do formulário, digite o código a seguir:

 

tvAgenda.NodeDataSize := SizeOf(TRecordAgenda);

 

...

Quer ler esse conteúdo completo? Tenha acesso completo