Entrada e Saída em Arquivos

Arquivos fornecem um meio de armazenamento de informações a longo prazo. Valores contidos em variáveis são transitórios, desaparecem quando o aplicativo é fechado, sendo recalculados quando o programa é processado novamente. Para armazenar dados permanentes que possam ser acessados e recuperados, você deve salvar as informações em arquivos.

Este capítulo apresenta como o Visual Basic trata algumas operações padrões de arquivos, incluindo localização, abertura, gravação e fechamento. Permite que você crie um aplicativo simples para demonstrar as ferramentas do sistema de arquivos do Visual Basic. Com essas ferramentas, você pode produzir caixas de diálogo que trabalhem como as caixas de diálogo Abrir Arquivo e Salvar Arquivo Como criadas pelo controle de diálogos comuns.

Veremos também duas formas de armazenar e recuperar dados em arquivos: o método linha a linha, que trata essencialmente as informações como texto; e o método orientado a registros. Adicionalmente, você aprenderá a armazenar informações de configuração no banco de dados de registro, de modo a salvar informações de configuração e de inicialização de seus aplicativos no formato padrão do Windows.

Visão Geral do Sistema de Arquivos

Conforme descrito no Capítulo 2, o microprocessador de seu computador usa os bits de informações armazenadas na memória como instruções e dados. O projeto de hardware dos microprocessadores permite acesso imediato à RAM (Memória de Acesso Aleatório) do sistema de computação. Porém, nem mesmo os micro-computadores modernos, com dúzias de megabytes de RAM, conseguem manter todas as informações necessárias em RAM. O sistema precisa de outro local para armazenar os dados que não cabem na RAM.

Os sistemas de computação têm usado diversos mecanismos para oferecer armazenamento externo, desde cartões perfurados a discos fixos e de discos flexíveis a discos óticos (CD-ROMs). Essas mídias externas podem armazenar centenas de mega-bytes ou, ainda, gigabytes de dados, a um custo centenas de vezes menor do que o da RAM adicional. Baixo custo e alta capacidade tornam os dispositivos de armazenamento externo muito atrativos, apesar de serem mais lentos e menos práticos.

A grande quantidade de dados tratados pelos dispositivos de armazenamento externo conduz ao problema da organização. Torna-se necessário arrumar uma forma de dizer "Muito bem, aqui está a minha carta para a Vovó" e "Ali se encontra o meu programa processador de textos". Os primeiros projetistas de sistemas de computação abordaram o problema da organização com uma analogia comercial, criando o equivalente a um sistema de pastas suspensas e chamando cada agrupamento individual de dados de pasta (arquivo). A interface gráfica continua a adotar essa analogia, usando ícones de catálogos de arquivos e armários de aço.

Como a memória em disco está fora do processador principal, o computador tem de executar um conjunto de atividades para obter ou incluir informações em um arquivo. O Visual Basic classifica o arquivo de acordo com a forma pela qual o computador irá acessá-lo: seqüencial, acesso aleatório ou binário.

Operações com Arquivos

Quando você abre um arquivo ou salva seu trabalho em um arquivo, a maioria dos programas para Windows apresenta uma caixa de diálogo, permitindo-lhe especificar o nome do arquivo, diretório e unidade de disco. Em Visual Basic, você normalmente deveria usar o controle de diálogos comuns para apresentar a caixa de diálogo Abrir Arquivo ou Salvar Arquivo Como. Entretanto, pode ser que seja necessário criar uma caixa de diálogo semelhante, porém com opções adicionais. Você pode criar uma caixa de diálogo assim usando três das ferramentas da caixa de ferramentas do Visual Basic: Caixa de Lista de Arquivos, Caixa de Lista de Diretórios e Caixa de Lista de Unidades, mostradas na Figura 10.1. Estas ferramentas permitem-lhe criar três tipos de objetos que foram projetados para trabalhar em conjunto; a maioria dos aplicativos não usa esses objetos separadamente.

Figura 10.1 As ferramentas Caixa de Lista de Arquivos, Caixa de Lista de Diretórios e Caixa de Lista de Unidades.

Criando o Aplicativo TestarArquivo

O aplicativo TestarArquivo demonstra como criar uma caixa de diálogo usando forms do Visual Basic e as três ferramentas do sistema de arquivos. O código de TestarArquivo e a caixa de diálogo são reutilizáveis, permitindo que você copie-os para outros aplicativos que requeiram esses recursos. Esta caixa de diálogo irá chamar-se Abrir Arquivo.

Comece abrindo um novo projeto. Configure a propriedade Caption do form para Principal e assinale FormPrin para a propriedade Name do form. Coloque um botão de comando no centro do form, configure a propriedade Name do botão para btnTeste e sua propriedade Caption para Teste. Dê um clique duplo no botão de comando para abrir a janela de código e defina o procedimento Click do botão como mostrado a seguir:

Private Sub btnTeste_Click ()

Dim Selecionado As String

Selecionado = OpenFileDlg("*.TXT")

lf Selecionado = "" Then

MsgBox "Cancelado"

Else

MsgBox "Arquivo " & Selecionado & " selecionado"

End If

End Sub

Esse procedimento chama a função OpenFileDIg (ainda não-definida), que exibe uma caixa de diálogo permitindo ao usuário selecionar um arquivo baseado na especificação *.TXT. Se o usuário não selecionar um arquivo e simplesmente fechar a caixa de diálogo, a função retornará uma string vazia; do contrário, o procedimento btnTeste_Click exibirá o nome do arquivo selecionado.

Incluindo um Segundo Form

O próximo passo é criar a caixa de diálogo que a função OpenFileDIg exibirá. Escolha a opção Add Form do menu Project ou dê um clique no botão Add Form na barra de ferramentas para colocar um segundo form Visual Basic na tela. No form novo, inclua uma caixa de lista de arquivos, uma caixa de lista de diretórios, uma caixa de lista de unidades e dois botões de comando. Configure as propriedades destes objetos, conforme mostrado na Figura 10.2, e então disponha-os como na Figura 10.3.

Figura 10.2 Configuração das propriedades para o segundo form do aplicativo TestarArquivos.

Figura 10.3 O projeto do form para a caixa de diálogo Abrir Arquivo no aplicativo TestarArquivos.

Quando você cria um aplicativo que usa mais de um form, o Visual Basic carrega apenas um dos forms quando o programa inicia. No nosso caso FormPrin já está designado para ser o form inicial da aplicação por ter sido o primeiro form criado, mas, para sua informação, escolha a opção Project Properties do menu Project. Na caixa de diálogo Project Properties, mostrada na Figura 10.4, selecione o item Startup Object. A caixa combinada Startup Object, no topo da caixa de diálogo, contém uma lista de todos os forms de seu aplicativo. Se FormPrin não estivesse selecionado, este seria o lugar de selecioná-lo para ser o form carregado na inicialização do aplicativo.

 

Figura 10.4 A caixa de diálogo Project Properties.

 

Nota: Observe que, quando você seleciona o item Startup Object na caixa de diálogo Project Properties, a caixa de lista de configurações inclui a opção Sub Main, além dos forms que o seu aplicativo contém. Escolher a opção Sub Main significa indicar para o Visual Basic não carregar qualquer form quando o programa for iniciado, em vez disso deverá ser executado o procedimento chamado Main (o qual você deve criar). Você pode querer usar essa opção se, por exemplo, o form de seu programa depende do dia da semana ou de alguns parâmetros de inicialização.

Incluindo um Módulo de Código

A seguir, você terá de escrever os procedimentos que controlam a caixa de diálogo Abrir Arquivo, incluindo a função OpenFileDIg. Você pode achar que todos esses procedimentos deveriam estar no form FormAbrir, porém há uma consideração importante que impede isso: o escopo de todos os procedimentos contidos no módulo de um form está restrito àquele módulo - isto é, qualquer procedimento no FormAbrir poderá ser acessado apenas por outros procedimentos contidos no form FormAbrir. Como a chamada para OpenFileDIg é feita a partir do FormPrin, essa função não pode ser alocada no FormAbrir.

Uma das soluções é colocar o código da função OpenFileDIg no FormPrin. Entretanto, estamos interessados em tornar a caixa de diálogo reutilizável, e o botão Testar no FormPrin evidentemente é dispensável em outros aplicativos. A melhor saída é criar um módulo de código separado, contendo o código que controla a caixa de diálogo. Uma vez que cada procedimento no módulo de código pode ter escopo global se declarado como Public, a questão de acesso estará resolvida. O módulo de código será uma entidade separada que poderá ser carregada em qualquer outro aplicativo Visual Basic.

Inclua o módulo de código, selecionando a opção Add Module do menu Project do Visual Basic. O Visual Basic incluirá um arquivo chamado MODULE1.BAS na lista da janela de projeto e abrirá a janela de código. Na parte de declarações gerais do módulo, adicione a seguinte instrução:

Public ArquivoSelecionado As String

Essa instrução declara uma variável string pública que conterá o nome do arquivo selecionado pelo usuário. Essa variável precisa ter o escopo global, pois será acessada tanto pela função OpenFileDlg contida no módulo de código quanto pelos procedimentos de eventos de FormAbrir.

Agora, inclua o seguinte procedimento no módulo de código:

Public Function OpenFileDIg (Wild As String) As String

Load FormAbrir

FormAbrir.ListArq.Pattern = Wild

ArquivoSelecionado = ""

FormAbrir.Show vbModal

OpenFileDlg = ArquivoSelecionado

End Function

Essa função é chamada com uma string de especificação especial de arquivos (tal como *.TXT) como argumento. Em primeiro lugar, ela carrega o form FormAbrir na memória com a instrução Load. Essa instrução assegura que o form se torne disponível, porem não faz com que se torne visível. A próxima linha de código configura a propriedade Pattern do objeto ListArq (a caixa de lista de arquivos) para string especial de especificação de arquivos. A propriedade Pattern da caixa de lista de arquivos determina quais arquivos deverão aparecer na lista - por exemplo, a string *.* faz com que sejam exibidos todos os arquivos. Observe que o código usa a referência Form.Objeto.Propriedade em vez de Objeto.Propriedade, como é feito normalmente. Como a função OpenFileDIg não está no módulo do form FormAbrir, a função deve explicitar o nome do form quando for preciso acessar um objeto contido no tal form.

A seguir, a variável ArquivoSelecionado é configurada para uma string vazia, indicando que nenhuma seleção foi feita até o momento. A instrução seguinte chama o método Show para FormAbrir, tornando-o visível. Show pode ser chamado com o argumento 0 (vbModeless) ou 1(vbModal). Quando é usado o argumento 0, o form torna-se visível. Com o argumento 1, e este é o caso aqui, o form especificado não apenas se torna visível, mas é exibido modalmente - isto é, nenhum outro form no aplicativo poderá ser usado enquanto esse form for exibido na tela. O processamento é suspenso no procedimento chamador até que o form modal seja fechado.

Quando o usuário fecha a caixa de diálogo, fazendo desaparecer FormAbrir, a função OpenFileDIg continua com sua última instrução, que configura o valor de retorno da função para a string ArquivoSelecionado. O controle do programa retorna então para o procedimento que havia chamado a função OpenFileDIg.

Codificando os Procedimentos de Eventos

Resta agora codificar os procedimentos de eventos para os objetos em FormAbrir. Esses procedimentos estão definidos na Figura 10.5. Os comentários no código descrevem o que acontece à medida que o programa os executa. Como você pode ver, a operação dos objetos do sistema de arquivos é relativamente simples, apesar de ser necessário programar cuidadosamente a interação entre eles. (Você pode usar uma técnica similar para criar a caixa de diálogo Salvar Arquivo, com algum esforço de programação a mais, para testar a validade da informação fornecida pelo usuário. A documentação do Visual Basic contém informações mais detalhadas.)

 

Figura 10.5 O código de programa dos procedimentos de eventos para o aplicativo TestarArquivo.

 

Executando e Salvando o Aplicativo TestarArquivo

Quando você iniciar o aplicativo TestarArquivo, verá apenas o form de inicialização, que contém o botão Testar. Dê um clique nesse botão para exibir a caixa de diálogo Abrir Arquivo. Selecione diretórios e unidades de disco diferentes, para ver como os controles reagem. Quando você escolher um arquivo, uma caixa de mensagem irá informar-lhe sobre sua escolha. Se não escolher um arquivo, ou der um clique no botão Cancelar, uma caixa de mensagem irá avisar-lhe do cancelamento da caixa de diálogo. Você pode dar um clique no botão Testar e ir para a caixa de diálogo quantas vezes quiser.

Como você pode ver, é necessário um bom esforço adicional para duplicar as capacidades do controle de diálogos comuns. (discutido no Capítulo 5). Se fosse usado o controle de diálogos comuns, o aplicativo TestarArquivo poderia ser programado com um único form, e aproximadamente 10 linhas de código, no procedimento btnTestar_Click.

Assegure-se de salvar o aplicativo TestarArquivo, pois você poderá precisar da função OpenFileDIg em outros aplicativos. Quando encerrar o aplicativo, escolha a opção Save Project do menu File. Use os nomes de arquivo FORMPRIN.FRM, FORMABRI.FRM e FORMABRI.BAS para o form principal, o form de caixa de diálogo e o módulo de código, respectivamente. Salve o arquivo de projeto como TESTARQ.VBP.

Arquivos Seqüenciais

Como mencionado anteriormente, o método mais simples de processamento de arquivos de dados envolve a leitura e a gravação de linhas de dados textuais, como se fossem linhas seqüenciais de texto em um livro. Um editor de texto como o aplicativo Bloco de Notas do Windows, por exemplo, trabalha com documentos seqüencialmente: ele carrega a primeira linha para a memória e exibe-a, carrega e exibe a segunda linha, e assim por diante. Quando você avisa o programa para salvar o seu documento, um processo similar faz com que o documento seja

gravado no arquivo, uma linha de cada vez. A Figura 10.6 ilustra esse processo.

Figura 10.6 Um arquivo seqüencial no disco e no vídeo.

 Novidades do VB6

Observe os símbolos <CR> e <LF> na ilustração. Esses dois caracteres,

artefatos históricos dos dias de comunicação por teletipos, são usados para separar uma linha de outra em arquivos seqüenciais. Os teletipos imprimiam em rolos de papéis, uma linha de cada vez. Além de imprimir o texto, eles também reagiam a certos códigos de controle (não-imprimíveis), como Ctrl-G, que fazia tocar um sino na máquina. Iniciar uma nova linha de texto requeria dois códigos de controle: o retorno de carro (ASCII 13), que provocava o movimento da cabeça de impressão para o início da linha; e uma alimentação de linha linefeed), que fazia o papel avançar uma linha. Esses códigos estavam contidos nos arquivos de texto, juntamente com o texto propriamente dito.

À medida que foram desenvolvidos novos dispositivos de saída, como terminais burros e impressoras de margaridas, os fabricantes adotaram alguns códigos de controle dessa convenção. O mundo do MS-DOS/Windows acabou herdando também o legado do retorno de carro e alimentação de linha - <CR> e <LF>.

Abertura e Fechamento de Arquivos Seqüenciais

A instrução Open informa ao Visual Basic que arquivo acessar. Normalmente, você usa uma caixa de diálogo padronizada, como a que foi desenvolvida neste capítulo, para obter o nome do arquivo. Após isso, você especifica esse nome de arquivo na instrução Open usando esta sintaxe:

Open NomeArquivo For (Input I Output) As #NúmeroArquivo

Juntamente com o nome do arquivo, você deve informar ao Visual Basic quando deseja ler (Input) ou gravar (Output) o arquivo, e deve fornecer um número de arquivo. Esse número de arquivo deve ser um inteiro entre 1 e 511, inclusive. Use a função FreeFile do Visual Basic para obter o próximo número de arquivo disponível. Eis aqui algumas instruções que abrem arquivos seqüenciais:

Open "C:\CONFIG.SYS" For Input As #1

Doc$ = "A:\PROP\BANZAI.DOC"

Open Doc$ For Input As #2

Open "RESULT.TXT" For Output As #15

Se você tentar abrir um arquivo para leitura e ele não existir, o Visual Basic gerará um erro. Se você estiver abrindo o arquivo para gravação, o Visual Basic sempre criará um arquivo novo, sobrepondo-o a qualquer arquivo existente de mesmo nome. Se deseja verificar a existência do arquivo antes de abri-lo para gravação, use a função Dir$. Se você chamar a função Dir$ com um nome de arquivo como parâmetro, a função retornará o próprio nome do arquivo (indicando que ele existe) ou uma string vazia, indicando que o arquivo não existe. Este fragmento de programa serve como ilustração da função Dir$:

If Dir$("DIRCEU.TXT') <> "" Then

lf lnputBox("DIRCEU.TXT já existe. Deseja removê-lo ?) <> Sim Then

Exit Sub

End If

End If

Open "DIRCEU.TXT" For Output As #15

 

Após acabar o trabalho com um arquivo, você deve fechá-lo. A instrução Close do Visual Basic tem a seguinte sintaxe:

Close #NúmeroArquivo

O número de arquivo na instrução Close corresponde ao número que você assinalou para o arquivo na instrução Open. Quando você fecha um arquivo, todos os dados gravados nele (se houver) são salvos, e outros programas estão liberados para acessar o arquivo.

Lendo Arquivos Seqüenciais

A leitura de arquivos seqüenciais é incrivelmente fácil. Uma simples instrução Line Input # lê cada linha de texto. Como você pode ver na sintaxe para a instrução, o arquivo deve ser identificado (pelo seu número) e uma variável string na qual será armazenado o texto de entrada fornecida:

Line Input #NúmeroArquivo, VariávelString

A função EOF (que é a abreviatura para End Of File - Final de Arquivo) permite que você saiba quando o final dos dados foi atingido. Ela requer um único argumento (número do arquivo) e retorna um valor True se todas as informações já foram lidas. Eis um exemplo de uma codificação para abrir, ler, processar e fechar um arquivo seqüencial.

Open VarArq For Input As #1

Do While Not EOF(1)

Line Input #1, VarLinha

' Procedimento do usuário para tratar a linha de texto

Process VarLinha

Loop

Close #1

Esse código assume a existência das variáveis strings VarArq e VarLinha. VarArq deve ter sido inicializada com o nome do arquivo e o código lê cada linha do arquivo de texto carregando-a na variável VarLinha.

Gravando Arquivos Seqüenciais

A gravação em arquivo seqüencial é quase tão simples quanto a leitura. A instrução Print # grava urn arquivo seqüencial de forma muito semelhante a como o método Print escreve em um form. Eis a sintaxe para a instrução Print #:

Print #NúmeroArquivo [, expressão [{, | ; } expressão ] ...] [{, | ;}]

Os valores das expressões, separadas por ponto-e-virgula, são escritos sem espaços em branco entre eles, enquanto os valores de expressões separadas por vírgulas são escritos em campos de impressão separados, que têm 14 caracteres de comprimento. Os caracteres correspondentes ao retorno de carro <CR> e à alimentação de linha <LF> são anexados à linha de saída, a menos que o último caractere da instrução Print # seja vírgula ou ponto-e-virgula.

O Aplicativo Configurador

Vamos construir um pequeno programa de exemplo usando entrada e saída seqüencial. Iremos chamá-lo de Configurador, pois ele permitirá que você edite o seu arquivo CONFIG.SYS. Por medida de segurança, tire uma cópia do seu arquivo CONFIG.SYS antes de usá-lo neste exercício e restaure-o após o exercício.

Crie um novo projeto e posicione uma grande caixa de texto e três botões de comando no form, conforme mostrado na Figura 10.7. Configure as propriedades dos objetos, como listado na Figura 10.8.

Figura 10.7 O projeto inicial do form para o aplicativo Configurador.

Figura 10.8 Configuração de propriedades para o aplicativo Configurador.

Na seção de declarações gerais do código, inclua as seguintes declarações:

Dim TextoAlterado As Integer

Dim ConfigAchado As Integer

Dim CRLF As String

Depois, introduza os procedimentos mostrados na Figura 10.9 para os

objetos apropriados.

Figura 10.9 Código de programa para o aplicativo Configurador.

Note que a variável CRLF aparece no código do programa Configurador. Normalmente, a implementação do mecanismo de final de linha é transparente. A instrução Line Input # lê até o final da linha e então passa uma string contendo todos os caracteres da linha, sem incluir os caracteres terminadores de linha. A instrução Print # escreve o que você especificar e automaticamente anexa os caracteres de final de linha. Entretanto, em nosso exemplo, tornou-se necessário reinserir os caracteres retorno de carro e alimentação de linha, eliminados pela instrução Line Input #, para que a caixa de texto soubesse onde está o final de cada linha e assim pudesse construir a exibição corretamente.

A Figura 10.10 mostra como o aplicativo Configurador deverá ficar quando você usar o programa para editar o seu arquivo CONFIG.SYS.

Figura 10.10 Editando um arquivo CONFIG.SYS com o aplicativo Configurador.

Ignorando os Limites de Linha

Ainda que a instrução Print # normalmente seja usada para escrever apenas uma

linha, ou parte dela, você pode usá-la para escrever quantas linhas quiser de uma única vez, como foi feito no programa Configurador. A instrução Line Input #, ao contrário, está restrita ao processamento de uma única linha de cada vez.

Alternativamente, você pode usar a função Input$ do Visual Basic para ler um arquivo de entrada, um caractere de cada vez. A função Input$ retorna a string de caracteres lida do arquivo de entrada, incluindo os caracteres de final de linha. Eis a sintaxe:

lnput$(QtdCaract, #NúmeroArquivo)

Você pode especificar a leitura de 1 a 32.767 caracteres (QtdCaract) em uma única vez. Se o arquivo contiver uma quantidade de caracteres menor do que a especificada, o Visual Basic gerará uma mensagem de erro Input past end of file (Entrada além do final do arquivo).

Você poderia escrever facilmente o programa Configurador usando a função Input$. Veja, a seguir, o procedimento de evento btnAbrir_Click, reescrito para usar esta função:

Sub btnAbrir_Click ( )

Dim Clinha As String

If ConfigAchado Then

Beep

Exit Sub

End If

Open "C:\CONFIG.SYS" For Input As #1

TxtConteúdo.Text = lnput$(LOF(1), #1)

Close #1

ConfigAchado = True

End Sub

 

Esse procedimento lê o arquivo CONFIG.SYS de uma só vez, o que é aceitável, pois o CONFIG.SYS normalmente é um arquivo pequeno. Com arquivos maiores, seria necessária a construção de um laço que verificasse a ocorrência do final do arquivo (EOF). Observe também que o procedimento reescrito usa a função LOF (que retorna o comprimento do arquivo). Essa função recebe um número de arquivo como argumento e retorna a quantidade de bytes que o arquivo contém.

Arquivos de Acesso Aleatório

A maioria dos programadores eventualmente encontra dois problemas com leitura seqüencial como a que acabou de ser descrita. Uma das questões é que nem sempre é eficiente representar dados textualmente. Por exemplo, você pode armazenar o número 42,1596 em uma variável de precisão simples (4 bytes), porém seriam necessários 7 bytes para armazenar esse valor como texto em um arquivo seqüencial. Outro problema é que, em determinadas ocasiões, torna-se necessário processar as informações de forma não-seqüencial.

Retornemos novamente às nossas amigas doninhas. Da última vez em que as vimos, estava sendo construído um banco de dados para armazenar informações a seu respeito. Naquela altura, a suposição era de que todas as informações sobre as doninhas seriam armazenadas em variáveis de programas (em matrizes). Com tal abordagem, no entanto, as modificações feitas nos dados demandavam alterações do programa, um problema equivalente a ter de modificar fisicamente seu processador de textos para cada documento que fosse escrito.

A solução natural é armazenar os dados em um arquivo. Você não deseja armazenar dados como texto, é preferível armazená-los como são tratados pelos programas: inteiros como inteiros, números de dupla precisão como dupla precisão. Além disso, você será capaz de acessar certa informação vital sobre uma certa doninha a qualquer instante, sem ter de ler o arquivo seqüencialmente até encontrar o que deseja. Nas páginas seguintes, construiremos o banco de dados de doninhas, para demonstrar um programa que usa acesso aleatório a arquivos.

Abertura e Fechamento de Arquivos de Acesso Aleatório

A sintaxe da instrução Open para arquivos de acesso aleatório é a seguinte:

Open NomeArquivo For Random As NúmeroArquivo Len = TamanhoRegistro

Nessa versão da instrução Open, você não especifica o modo lnput (Entrada) ou Output (Saída), pois poderá ler e gravar arquivos de acesso aleatório sem ter de abrir e fechar o arquivo toda vez. Adicionalmente, você deve fornecer o tamanho do registro, que é a quantidade de bytes a serem lidos ou gravados a cada instrução Get ou Put (instruções usadas para leitura e gravação do arquivo). Por exemplo, se você pretendesse usar um arquivo contendo apenas números inteiros, o tamanho do registro seria 2. Porém, se cada valor no arquivo fosse do tipo Currency, o tamanho do registro deveria ser 8. Se não for especificado o tamanho de registros, o Visual Basic assumirá 128. (Há grande possibilidade de esse valor default não ser apropriado para seu arquivo.)

Para poder determinar o tamanho de registro para o banco de dados de doninhas, é preciso verificar os dados que você planeja ler e gravar. No Capítulo 6, você definiu o tipo de dado DoninhaTFB como segue:

Type DoninhaTFB

Nome As String

Cor As String

Peso As Integer

Tamanho As Integer

Data_nascimento As Double

Cor_topete As String

Compr_topete As Integer

End Type

Supondo que cada registro seja exatamente igual a isso, você pode somar o comprimento de todos os campos componentes para obter o tamanho do registro. Infelizmente, há três campos que são strings, e você não tem como saber o comprimento deles.

Para resolver essa questão, o Visual Basic permite que você declare comprimentos fixos para strings. Se usar essa capacidade, impondo algumas restrições aos seus dados, você poderá calcular o tamanho do registro. Por exemplo, se você restringir o nome das doninhas a 32 caracteres e a cor a 12 caracteres, poderá redefinir o tipo DoninhaTFB como segue:

Type DoninhaTFB

Nome As String * 32

Cor As String * 12

Peso As Integer

Tamanho As Integer

Data_nascimento As Double

Cor_topete As String * 12

Compr_topete As Integer

End Type

A expressão String * 32 fixa em 32 bytes o tamanho para cada nome de doninha. Caso o nome ocupe menos de que 32 posições, o Visual Basic preencherá o nome com espaços em branco no final. Nomes que requeiram mais de 32 posições serão truncados. Assim, o comprimento total do registro de DoninhaTFB é agora 70 bytes; (32 + 12 + 2 + 2 + 8 + 12 + 2).

Fechar um arquivo de acesso aleatório é bem simples. Use a instrução Close exatamente da mesma forma que é usada para fechamento de arquivos seqüenciais. Por exemplo, se você abriu um arquivo de acesso aleatório, como arquivo #1, use a instrução Close #1 para fechá-lo.

 

Lendo e Gravando Arquivos de Acesso Aleatório

As instruções Get e Put são usadas para ler e gravar em arquivos de acesso aleatório. A sintaxe para essas duas instruções é simples:

Get #NúmeroArquivo, [NúmeroRegistro], variável

Put #NúmeroArquivo, [NúmeroRegistro], variável

A instrução Get lê o dado a partir do arquivo, armazenando-o em uma variável, enquanto a instrução Put grava o conteúdo da variável especificada no arquivo. Nos dois casos, você pode especificar o número do registro. Caso não seja especificado o número do registro, será usada a próxima posição seqüencial no arquivo.

Um arquivo de acesso aleatório parece-se muito com uma matriz de tipos definidos pelo usuário. A principal diferença é que os dados são armazenados em disco, e não na memória, assim eles não se perdem quando o programa encerra o seu processamento. (Observe, ainda, que os registros em disco são indexados, começando pelo registro 1, enquanto a indexação de elementos de uma matriz é iniciada por 0.) A Figura 10.11 mostra como os registros são armazenados em disco.

Figura 10.11 Registros em um arquivo de acesso aleatório.

 
O Aplicativo de Banco de Dados Doninha

Vamos iniciar agora a construção do aplicativo de banco de dados Doninha, que controlará as suas doninhas de topete. Naturalmente, se você não tiver a felicidade de possuir pelo menos uma doninha, lembre-se de que esse programa poderá ser facilmente adaptado para controlar outros tipos de informações.

O planejamento básico para o banco de dados de doninhas envolve o uso de um arquivo de acesso aleatório para armazenar informações sobre as doninhas. Quando você processar o aplicativo, ele varrerá o arquivo, juntando o nome de cada doninha e exibindo a lista desses nomes numa caixa de lista. Ao se escolher um dos nomes dessa lista, o programa localizará o registro da doninha desejada no arquivo e exibirá todas as informações relevantes. Além disso, botões de comando permitirão que você inclua uma nova doninha ou elimine uma doninha do arquivo.

Para iniciar, crie um projeto novo. Coloque no form uma caixa de lista combinada, seis caixas de texto, sete rótulos e dois botões de comando. O esquema inicial é mostrado na Figura 10.12.

Figura 10.12 Projeto inicial do form para o aplicativo de banco de dados Doninha.

Configure as propriedades dos objetos, conforme indicado pela Figura

9.13. Após isto, o form deverá parecer-se com o mostrado na Figura 10.14.

 

Figura 10.13 Configuração de propriedades para o aplicativo de banco de dados Doninha.

Figura 10.14 O projeto final do form para o aplicativo de banco de dados Doninha.

 

O aplicativo precisa de algumas declarações de escopo global. Criaremos para isto um módulo de código. Escolha a opção Add Module do menu Project. Na janela de código, inclua as seguintes declarações na seção de declarações gerais:

Type DoninhaTFB

Nome As String * 32

Cor As String * 12

Peso As Integer

Tamanho As Integer

Data_nascimento As Double

Cor_topete As String * 12

Compr_topete As Integer

End Type

Public Const DONINHA_TAM_REG = 70

A definição da constante DONINHA_TAM_REG facilitará a leitura do seu programa; a visão do nome da constante em vez do número 70 lembra o que o valor realmente significa. Entretanto, a maior razão para o uso de constantes desse tipo é a facilidade de manutenção do programa.

Suponha que, no futuro, seja necessário redefinir o tipo DoninhaTFB; talvez pela necessidade de incluir um novo campo, ou porque você chegou à conclusão de que 32 caracteres são insuficientes para os nomes. Se você não tivesse usado uma constante para o tamanho do registro, seria necessário examinar cada linha do programa, alterando o número 70 para o novo tamanho do registro. Além disso, teria de tomar o cuidado de verificar se cada número 70 que aparece no,programa realmente refere-se ao tamanho do registro. Usando o nome de uma constante, você pode apenas trocar o valor da constante, e o restante do programa será instantaneamente atualizado com o novo tamanho de registro.

O restante das declarações são locais ao form. Feche a janela de código para o módulo de código e abra a janela de código para o form. Inclua as seguintes linhas na seção de declarações gerais:

Dim DoninhaAtualIx As Integer 'Número da doninha atual

Dim DoninhaCont As Integer 'Quantid. total de doninhas

Dim RegModif As Integer 'Flag booleano

Essas variáveis armazenarão um número de índice, indicando quais registros de doninhas estão sendo exibidos; controlarão a quantidade total de registros de doninhas armazenados no arquivo; e controlarão quando houve ou não alteração de qualquer informação no vídeo. (Observe que esse programa usa a abreviação Ix em vez de Index, pois Index é o nome de uma propriedade Visual Basic.)

Para inicializar o sistema, o programa deverá ler cada registro do arquivo e colocar os nomes das doninhas na caixa de lista. O usuário poderá então escolher um nome. O programa responderá, recuperando o registro completo para a tal doninha e exibindo-o. Se o usuário modificar o registro, essas alterações serão gravadas de volta no arquivo.

Para ilustrar um estilo de programação que funcione a contento com grandes quantidades de dados, esse programa não lerá todos os registros, armazenando-os em uma matriz. Em vez disso, ele trabalhará inteiramente com variáveis de memória. Mantendo apenas um registro na memória de cada vez, você consegue reduzir significativamente os requisitos de memória.

Por questões de simplicidade, o programa requer que todos os nomes possam ser alocados na memória de uma única vez, porém se o comprimento médio dos nomes é de 8 ou 9 caracteres, isso não deverá ser um problema. Supondo que o arquivo de dados exista em uma localização predefinida em disco, você pode escrever a seguinte rotina de inicialização. (Nesse aplicativo, não usaremos a função FileOpenDIg. Assumiremos um nome de arquivo e um caminho de acesso predeterminado para os dados. O caminho C:\VB designa o diretório do Visual Basic em meu sistema; assegure-se de usar um caminho de acesso que seja válido para o seu sistema.)

Figura 10.15

 

A instrução Open abre ou cria o arquivo. A função LOF retorna a quantidade total de bytes ocupados pelo arquivo, que dividida pelo tamanho do registro permite obter a quantidade total de registros. Depois, cada registro existente é lido e o nome de cada doninha é inserido na caixa de lista.

Quando a inicialização termina, o usuário pode escolher o nome de uma doninha para exibir os seus dados e eventualmente alterar alguma informação. Os procedimentos mostrados na Figura 10.16 atendem a esses requisitos.

Figura 10.16 Os procedimentos MostrarDoninha e AtualizarDoninhaAtual

O procedimento MostrarDoninha recebe o número do índice (elemento) como argumento. Ele assinala esse valor para a variável DoninhaAtualIx e acessa o arquivo para recuperar os dados da doninha gravados no registro correspondente ao valor de DoninhaAtuallx, atualizando cada campo de exibição. A seguir, configura o status RegModif para indicar que o registro ainda não foi modificado. O procedimento AtualizarDoninhaAtual verifica o status RegModif para determinar quando se trata de um registro modificado. Caso não tenha sido alterado, o procedimento simplesmente encerra o seu processamento. Se o usuário tiver alterado o registro, o valor atual de cada campo é recuperado e o registro alterado é gravado novamente em disco.

As outras tarefas principais do programa são: criar novos registros e remover registros desatualizados. Você pode criar novos registros com o procedimento de função mostrado na Figura 10.17. (Discutiremos os procedimentos de remoção um pouco mais adiante.) A função NovaDoninha preenche o registro da doninha com o nome que lhe é passado como argumento e com valores defaults; para os outros campos. Ela incrementa DoninhaCont para levar em consideração a nova doninha, grava o novo registro no arquivo de dados e inclui o nome na caixa de lista. Uma vez que o registro novo é sempre gravado no final do arquivo, o seu índice na caixa de lista é o mesmo que o valor anterior de DoninhaCont, que é retornado ao procedimento chamador como valor da função.

 

Function NovaDoninha (NovoNome As String) As Integer

Dim Doninha As DoninhaTFB

Doninha.Nome = NovoNome

'Assinalamento de informações default

Doninha.Cor = "Marrom"

Doninha.Peso = 0

Doninha.Tamanho = 0

Doninha.Data_nascimento = Now

Doninha.Cor_topete = "Marrom"

Doninha.Compr_topete = 0

'Assinalar número do índice como retorno

NovaDoninha = DoninhaCont

'Incrernentar quantidade de doninhas

DoninhaCont = DoninhaCont + 1

'Gravar o novo registro

Put #1, DoninhaCont, Doninha

'Incluir o nome na lista de doninhas

cboNome.Additem Doninha.Nome

RegModif = False

End Function

Figura 10.17 O procedimento de função NovaDoninha.

Os procedimentos escritos até agora para esse programa foram definidos na seção geral do form, pois cada rotina executa uma tarefa específica. Esses procedimentos podem ser chamados por qualquer outro procedimento, inclusive por procedimentos de eventos, de forma que é melhor defini-los como unidades independentes em vez de codificá-los como parte de um procedimento de evento de um determinado objeto. É melhor realizar o trabalho específico do aplicativo em procedimentos gerais, fazendo com que o código nos procedimentos de eventos sirva de conexão entre a interação do usuário e a parte funcional do programa.

A primeira conexão importante é o vínculo entre a inicialização do programa e a inicialização do banco de dados. Quando você inicia o programa, o procedimento de evento Load do form é o primeiro a ser chamado:

Sub Form_Load ()

DoninhaInicia

End Sub

É preciso conectar a escolha de um nome feita pelo usuário a partir da caixa combinada ao procedimento que faz a exibição do registro. Além disso, você deve ligar a criação de um novo registro ao botão Incluir. Estas duas rotinas fazem essas conexões:

Figura 10.18

Posicionar o registro exibido é simples, pois, somando-se 1 ao índice do nome na caixa de lista, obtém-se a posição do registro no arquivo. Com a segunda rotina, o usuário é incitado a nomear a nova doninha quando um clique é dado no botão Incluir. Se não for fornecido um nome, não será incluído qualquer registro. Caso contrário, o procedimento chama NovaDoninha para criar o novo registro e passa o valor do índice retornado diretamente para MostrarDoninha, de forma que o novo registro seja exibido.

Para completar esse aplicativo, você deve implementar o suporte para edição de registros de doninhas. Serão necessárias duas rotinas simples para cada caixa de texto. O procedimento Change executa a instrução RegModif = True, e o procedimento LostFocus atualiza o registro chamando AtualizarDoninhaAtual. O código para cada caixa de texto é apresentado na Figura 10.19.

Figura 10.19 Procedimentos de eventos para as caixas de texto no aplicativo de banco de dados Doninha.

É melhor apenas configurar o status RegModif, em vez de chamar a rotina AtualizarDoninhaAtual diretamente, pois o procedimento Change é chamado pelo Visual Basic toda vez que o conteúdo de uma caixa de texto se altera. Por exemplo, se você digitar Vermelho na caixa de texto para Cor, o procedimento Change é chamado oito vezes, uma para cada letra digitada. No entanto, o registro não deve ser atualizado até que o novo conteúdo para a caixa de texto esteja completo, assim o programa chama a rotina para atualização no procedimento de evento LostFocus.

O que é o evento LostFocus (perder o foco)? Todo e qualquer controle na tela pode ser o "foco de atenção" em um determinado instante durante o processamento de um aplicativo. O Windows controla isso através dos eventos GotFocus e LostFocus. Por exemplo, quando você dá um clique numa caixa de texto, o evento GotFocus é disparado. O foco permanece na caixa de texto enquanto você estiver digitando. Ao pressionar a tecla TAB ou dar um clique em algum outro controle, a caixa de texto receberá o evento LostFocus e o novo controle receberá GotFocus. Portanto, quando o procedimento LostFocus de uma caixa de texto for processado, você saberá que o usuário completou a digitação e seu programa pode chamar a rotina de atualização.

O aplicativo de banco de dados Doninha agora está pronto para ser processado. Pressione F5 para iniciar a sua execução. Por ser a primeira vez que você está processando o programa, nenhuma entrada aparecerá na caixa de lista. Dê um clique no botão Incluir e introduza os dados para três ou quatro doninhas. Então, pressione Alt-F4 para sair do programa e processe-o novamente. Conforme ilustrado na Figura 10.20, você deveria ser capaz de escolher um dos nomes que acabou de incluir.

Figura 10.20 Processando o aplicativo de banco de dados Doninha.

 

Eliminando Registros

O modelo lógico desse aplicativo é eficiente e relativamente simples de entender. Porém, essa simplicidade tem o seu preço: você não tem uma forma simples de eliminar registros.

Suponha que o arquivo de banco de dados DONINHAS.DAT contenha quatro registros, para as doninhas chamadas hipoteticamente de A, B, C e D, conforme mostrado na Figura 10.21. A criação desses registros produziu um arquivo que contém 280 Bytes (4 x 70).

Figura 10.21 Um arquivo com quatro registros para o banco de dados Doninhas.

Não é possível simplesmente remover bytes do meio do arquivo e compô-lo novamente. Por exemplo, se deseja eliminar o registro da doninha B, você tem apenas duas opções: copiar todos os registros, exceto aquele a eliminar, para um novo arquivo ou então sobrepor o registro B com algum dado novo. Se você fizer a cópia, poderá então remover o arquivo original e renomear o arquivo copiado com o nome do arquivo original. Essa solução está ilustrada na Figura 10.22.

 

Figura 10.22 Copiando registros e renomeando o arquivo.

 

Se você sobrepuser o registro B com outros dados - por exemplo, um registro contendo apenas espaços em branco -, a caixa de lista eventualmente conterá uma série de entradas em branco. Você pode pensar em fazer com que a rotina de inicialização simplesmente omita qualquer registro com o nome da doninha em branco. Porém, caso isso seja feito, esse aplicativo não será capaz de compatibilizar as entradas da caixa de lista com os registros correspondentes no arquivo. A Figura 10.23 ilustra esse problema.

Esse aplicativo, como está atualmente, requer uma associação de um para um entre os nomes na caixa de lista e os registros no arquivo. (Acidentalmente, esse requisito significa que a propriedade Sorted da caixa de lista não pode ser configurada para True, uma vez que a classificação destruiria o relacionamento entre os valores de índices da caixa de lista e a posição dos registros no arquivo.) É possível contornar esse problema criando-se um mapeamento separado.entre o índice da caixa de lista e as posições no arquivo. A Figura 10.24 contém um exemplo.

 

Figura 10.23 Sobrepondo um registro com espaços brancos.

Figura 10.24 Mapeando os índices da caixa de lista.

 

Qual é a melhor solução? Se você sabe que os arquivos de dados para o seu aplicativo serão sempre pequenos, o método de copiar e renomear pode ser melhor. Ele pode ser implementado sem qualquer modificação no código que já foi escrito, e o aplicativo permanecerá simples e fácil de entender. Entretanto, em se tratando de arquivos volumosos, a cópia demanda tempo e considerável espaço em disco. É preciso ter em mente que tanto a cópia quanto o arquivo original terão de existir ao mesmo tempo, e se o espaço em disco não for suficiente, o programa poderá falhar. A criação de um mapeamento permite que o seu programa seja executado mais eficientemente, algo muito apreciado pelos usuários finais. No entanto, essa solução envolve complexidade adicional (e possivelmente bugs) e a reescrita de algumas partes do código existente.

Como programador, você será constantemente chamado a tomar decisões desse tipo. É muito importante compreender a tarefa do seu programa e a natureza dos dados antes de tomar uma decisão. Não importa o quão livre de bugs esteja o seu código, ele será inútil se os usuários não puderem conviver com as decisões que você toma durante a fase de projeto.

Vejamos mais de perto as alternativas de eliminação de registros do banco de dados Doninhas. A solução copiar e renomear não requer modificações no código existente. Basta incluir o procedimento mostrado na Figura 10.25.

Figura 10.25 O procedimento btnEliminar_Click para o aplicativo Doninha.

O procedimento btnEliminar_Click abre um novo arquivo e copia todos os registros, menos o atual, para ele. Os dois arquivos são então fechados. A instrução Kill recebe o nome original do arquivo como um parâmetro e este arquivo é excluído. A instrução Name renomeia o arquivo criado por meio da cópia. Quando acaba o tratamento dos arquivos, a caixa de lista é limpa e o programa chama o procedimento DoninhaInicia novamente, para recarregar os nomes na caixa de lista.

A segunda alternativa, usando uma matriz como um mapa, é mais complexa, pois envolve modificações no código existente. A Figura 10.26 contém apenas as rotinas que devem ser modificadas para produzir a nova versão; linhas que foram adicionadas ou alteradas encontram-se em destaque.

Figura 10.26A A parte revisada do código do aplicativo Doninha para implementar a matriz de mapeamento.

Figura 10.26B A parte revisada do código do aplicativo Doninha para implementar a matriz de mapeamento. (Continuação)

O programa alterado usa a propriedade chamada ItemData, que é uma característica interna de caixas de lista. ItemData é uma matriz de elementos do tipo Long Integer, com uma entrada para cada item da caixa de lista. Essa matriz é usada para armazenar o mapeamento, isto é, ela conterá o número de registro no arquivo para cada entrada da lista. Na versão original, a variável DoninhaAtualIx refere-se apenas ao índice na caixa de lista; a posição do registro no arquivo deve ser obtida a partir da expressão cboNome.ltemData(DoninhaAtuaIIx).

As alterações feitas nos procedimentos NovaDoninha, MostrarDoninha e AtualizarDoninhaAtual são triviais, simplesmente asseguram que o mapeamento seja usado e atualizado corretamente. As modificações em DoninhaInicia são relativamente diretas: à medida que cada registro é lido, verifica-se se a primeira posição do nome está em branco; se estiver, significa que o registro deve ser ignorado. Além disso, durante a leitura dos registros, é armazenado o valor apropriado na matriz ItemData. A propriedade NewIndex contém o valor do índice da lista para o item incluído mais recentemente. Uma vez que não é mais necessária uma relação biunívoca entre os registros no disco e na caixa de lista, você pode configurar a propriedade Sorted da caixa de lista para True.

Finalmente, o procedimento btnEliminar_Click é completamente diferente na nova versão. Para eliminar o registro atual, o programa irá sobrepô-lo com um registro em branco. Depois, o nome é removido da caixa de lista.

Permanece um pequeno problema nessa nova versão: os registros eliminados ocupam espaço e os novos registros são incluídos sempre no final do arquivo. Seria ideal se o procedimento NovaDoninha reutilizasse o espaço dos registros excluídos, em vez de estender automaticamente o arquivo. Essa modificação impediria que o arquivo crescesse indefinidamente. A implementação desse exercício é deixada a cargo do leitor. (Eu sempre desejei dizer algo semelhante a isso.)

Configuração

Freqüentemente, você pode desejar salvar um ou dois valores importantes de uma seção do aplicativo para outra - talvez uma configuração tal como o modo analógico ou digital para o seu programa de relógio. As variáveis padrões não funcionam, pois o valor armazenado nelas se perde quando o programa acaba. Você poderia criar um arquivo de dados, porém isso exigiria um grande esforço para quantidades mínimas de informações. A solução padrão adotada por aplicativos para o Windows 95 e NT é armazenar os valores no Registro do Sistema. O Registro do Sistema é um conjunto de arquivos que o Windows utiliza para armazenar informações sobre hardware, software do sistema e configuração de aplicações. Cada aplicativo pode criar informações e armazená-las no Registro do Sistema. Você não precisa se preocupar em como estas informações estão organizadas internamente no Registro, basta saber que o Registro do Sistema está organizado na forma de uma árvore de itens onde cada item constitui o que chamamos uma chave do Registro. Nas chaves ficam armazenadas as informações. O Visual Basic possui funções que lhe dão acesso ao Registro para criação, leitura, gravação e exclusão de informações.

O Visual Basic provê uma localização padrão no Registro para o armazenamento de informações de aplicações criadas em Visual Basic: HKEY_CURRENT_USER\Software\VB and VBA Program Settings\NomeAplicação\seção\chave

Observe que NomeAplicação, seção e chave são subchaves de HKEY_CURRENT_USER\Software\VB and VBA Program Settings. Sua aplicação poderá utilizar estas três subchaves para armazenar informações de configuração que permaneçam de uma execução para outra.

 

As funções de manipulação das informações armazenadas pela sua aplicação no registro são:

 

Figura 10.27 Funções de acesso ao Registro

Nota Para examinar entradas no registro, use a aplicação Regedit, que acompanha o Windows 95 e Windows NT.

 

Criando e Salvando Configurações da Aplicação

Você pode usar a instrução SaveSetting para salvar um novo valor para uma chave do registro armazenada na localização do registro destinada à sua aplicação. Por exemplo, você poderia adicionar código ao evento Form_Unload no formulário principal da aplicação no sentido de preservar as configurações no momento de encerramento, ou no evento de Form_Unload de uma caixa de diálogo de Opções para atualizar as preferências do usuário.

Use a seguinte sintaxe para a instrução SaveSetting:

SaveSetting NomeAplicação, seção, chave, valor

O código seguinte salva novos valores para as chaves Backup e LastEntry na

seção Setup do registro para uma aplicação chamada "RegCust". Este código assume que as variáveis strDate e intLastEntry contêm os novos valores.

Private Sub Form_Unload(Cancel As Integer)

SaveSetting "RegCust", "Startup", "Backup", strDate

SaveSetting "RegCust", "Startup", "LastEntry", _

intLastEntry

End Sub

Se uma entrada para a aplicação "RegCust" ou alguma dessas seções ou chaves não existir na seção Software\Microsoft do registro, este código irá criá-la.

Para mais informações veja "SaveSetting Statement" no Language Reference do Books Online.

Recuperando Configurações da Aplicação

Você pode usar as funções GetSetting e GetAllSettings para obter os valores armazenados no localização do registro usada pela sua aplicação. Por exemplo, sua aplicação pode obter as informações do registro para recriar as condições presentes no momento do seu último encerramento.

Uma Informação por Vez

Para recuperar uma única informação do registro, use a seguinte sintaxe para a função GetSetting:

GetSetting(NomeAplicação, seção, chave, [padrão])

O código seguinte recupera o valor da chave LastEntry na seção Startup da aplicação "RegCust" e exibe o valor na janela Immediate.

Private Sub Form_Load()

Dim intLastEntry As Integer

intLastEntry = GetSetting("RegCust", "Startup", _

"LastEntry", "0")

Debug.Print intLastEntry

End Sub

Note que você pode usar um parâmetro opcional, padrão, para determinar o valor retornado pelo Visual Basic quando nenhum valor estiver presente no registro para a chave especificada.

Múltiplas Informações

Para retornar uma lista das chaves e seus valores, use a seguinte sintaxe para a função GetAllSettings:

GetAllSettings(NomeAplicação, seção)

O código seguinte recupera uma lista de duas colunas de chaves do registro e seus valores na seção Startup da aplicação "RegCust", e exibe os resultados na janela Immediate.

Private Sub Form_Load()

Dim avntSettings As Variant

Dim intX As Integer

avntSettings = GetAllSettings("RegCust", "Startup")

For intX = 0 To UBound(avntSettings, 1)

Debug.Print avntSettings(intX, 0), _

avntSettings(intX, 1)

Next intX

End Sub

Para mais informações veja "GetSetting Function" e "GetAllSettings Function" no Language Reference do Books Online.

Excluíndo Configurações da Aplicação

Você pode usar a instrução DeleteSetting para excluir uma chave , seção ou localização de aplicação do registro. Por exemplo, você pode querer excluir todas as informações do registro para uma aplicação quando ela for desinstalada.

Use a sintaxe seguinte para a instrução DeleteSetting:

DeleteSetting(NomeAplicação, seção, chave)

O código seguinte exclui a chave LastEntry na seção Startup da aplicação "RegCust".

Private Sub cmdDelKey_Click()

DeleteSetting "RegCust", "StartUp", "LastEntry"

End Sub

O código seguinte exclui totalmente do registro a seção Startup da aplicação "RegCust".

Private Sub cmdDelSection_Click()

DeleteSetting "RegCust", "StartUp"

End Sub

O código seguinte exclui por inteiro do registro a localização para a aplicação "RegCust".

Private Sub cmdUnInstall_Click()

DeleteSetting "RegCust"

End Sub

Para mais informações veja "DeleteSetting Statement" no Language Reference do Books Online.

Bibliotecas de Ligação Dinâmica

Você pode acessar funções internas do Windows ou internas aos aplicativos desenvolvidos para Windows se as funções fizerem parte de uma biblioteca de ligação dinâmica (Dynamic-link library, uma DLL). Se você pesquisar o diretório SYSTEM do Windows, verá arquivos com a extensão DLL no nome. Alguns desses arquivos acompanham o Windows; outros (tais como VBRUN500.DLL) vêm com os aplicativos que você comprou. Se você souber a definição das funções contidas nesses arquivos, poderá chamar quase todas elas em seus aplicativos Visual Basic.

Para chamar essas funções a partir do Visual Basic, é necessário conhecer algumas informações técnicas a respeito de tipos de dados, passagem de parâmetros e assim por diante. Para ter uma visão detalhada sobre isto consulte no Books Online "Acessing DLL’s and the Windows API". Informações especificas sobre as funções que podem ser chamados em cada DLL devem ser buscadas nos manuais de programação dos produtos que contêm as DLL’s.

Resumidamente, a instrução Declare possui a seguinte sintaxe:

Sintaxe 1

[Public | Private] Declare Sub Nome Lib "NomeBiblioteca" [Alias "NomeApelido"] [([Lista de argumentos])]

 

Sintaxe 2

[Public | Private] Declare Function Nome Lib "NomeBiblioteca" [Alias "NomeApelido"] [([Lista de argumentos]

)] [As TipoRetorno]

Public ou Private: declara se o procedimento pode ser chamado em todos os módulos (Public) ou apenas no módulo onde esta instrução aparece (Private).

Explicações

Aviso: A instrução Declare é muito poderosa. Ela lhe permite acessar qualquer função do sistema Windows. Entretanto, você deve usá-la cuidadosamente. Por fazer chamadas diretas ao sistema, você não desfrutará dos benefícios de verificação de erros do Visual Basic. Há o perigo potencial de você provocar uma queda do sistema, se for cometido um engano na declaração ou chamar uma função do sistema com valores inválidos.

Um Exemplo de Uso das Funções em DLLs do Windows

Uma tarefa comum no uso de caixas de lista e caixas de combinação é verificar a existência de um item na lista. Usando somente os recursos do Visual Basic, você teria que criar um loop para verificar item por item até localizar o item procurado. No entanto, o Windows disponibiliza uma função chamada SendMessage, que pode ser usada para solicitar diretamente essa pesquisa ao objeto caixa de lista ou caixa combinada. O trabalho de codificação diminui e o desempenho é melhor. Antes que você possa usar SendMessage em uma aplicação, no entanto, é preciso declará-la no seu programa. Abaixo está a instrução de declaração de SendMessage.

Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long

Esta função envia uma mensagem à janela identificada pelo argumento hwnd solicitando alguma informação ou ação. A mensagem é identificada pelo argumento wMsg, uma constante, que também precisaremos declarar antes de fazer a chamada a SendMessage. Os dois últimos argumentos têm significados variados dependendo da mensagem que está sendo enviada. No exemplo que daremos a seguir o parâmetro lParam será usado para conter uma string pesquisada numa caixa de lista. Mudemos, portanto, o seu tipo de dados para String na instrução Declare.

Além da declaração de SendMessage, devemos declarar também a constante que identifica a mensagem para a caixa de lista ou caixa combinada. No caso de a mensagem que solicita a pesquisa de uma string ser destinada a uma caixa de lista a declaração da constante é:

Public Const LB_FINDSTRINGEXACT = &H1A2

Declararemos também uma constante usada para verificação do valor de retorno da função: LB_ERR. Caso LB_ERR seja retornado, é sinal de que nenhum item com o texto exatamente igual ao pesquisado existe na lista.

Public Const LB_ERR = (-1)

Uma vez que as declarações estejam feitas, o código abaixo exemplifica a chamada a SendMessage para pesquisar pelo item "Paulo" a partir do inicio da lista de lstNomes. No caso do item ser localizado é dada uma mensagem que exibe o seu índice na lista; caso nada seja encontrado, é dada uma mensagem de aviso.

Figura 10.28 Exemplo de uso de SendMessage para pesquisar listas

Neste exemplo, o terceiro argumento é -1, o que significa, para esta mensagem, que a pesquisa deve começar pelo primeiro item da lista.

Repare no prefixo LB no nome da constante que identifica a mensagem. Este prefixo é abreviatura de ListBox (Caixa de Lista). Se a mensagem fosse para uma caixa combinada, a constante seria declarada como abaixo:

Public Const CB_FINDSTRINGEXACT = &H158

No restante tudo seria feito da mesma forma.

Agora veja abaixo duas outras constantes identificadoras de mensagens para pesquisas em caixas de lista e caixas combinadas:

Public Const LB_FINDSTRING = &H18F

Public Const CB_FINDSTRING = &H14C

Estas constantes identificam mensagens que também fazem pesquisa em listas, mas com uma diferença: retornam o primeiro item que inicie com o texto pesquisado. O modo de chamar é o mesmo que o usado em LB_FINDSTRINGEXACT e CB_FINDSTRINGEXACT.

Há duas formas de você obter as informações necessárias para criar estas declarações sempre que precisar usar as funções das DLLs do Windows. Uma é consultar alguma documentação do Windows sobre o procedimento e fazer por sua própria conta as conversões de tipos de dados da linguagem "C" para os seus correlatos no Visual Basic. Outra é carregar a aplicação API Text Viewer, que acompanha o Visual Basic, e abrir o arquivo de texto Win32API.TXT que contém as declarações prontas para você copiar e colar no seu código. Foi o que fizemos para obter as declarações acima.

Nota: o conjunto de funções que o Windows coloca à disposição dos programadores para serem chamadas de dentro de qualquer aplicação para Windows é conhecido como Windows’ Application Programming Interface ou Windows’ API. Uma excelente fonte de informação detalhada sobre a API do Windows é o livro "Visual Basic 5.0 – Programmer’s Guide to the Win32 API" de Dan Appleman.

 

Torne sua vida mais fácil programando com RabJump