Categoria Dicas Delphi - Classe Helpers

Posted by webmaster | Delphi |

Hoje vamos ver que o compilador do Delphi 2005 faz mágicas.

Helper

A palavra Helpers é utilizada no Delphi para criar uma extensão de uma classe, podendo assim dividi-la em duas Units, sem precisar herdá-la. Uma das mais novas características da linguagem e do poderoso compilador Delphi, é poder estender novas funcionalidades às classes já existentes, podendo assim construir novos métodos e propriedades sem ter que criar uma nova classe herdando-a.

A razão principal deste recurso implantado no compilador pela Borland foi a necessidade de estender as classes existentes na VCL para VCL.NET. na Listagem 1. veremos um exemplo de como é feito o uso de uma classe helper.

Listagem 1. Aqui está um exemplo como estender uma classe com helpers.

TPessoa = class

procedure SomaSalario;

end;

TPessoaFisica = class helper for TPessoa

function ValidaCPF(Value: string) Boolean;

end;

Com as definições da classe acima, podemos usar-la da seguinte maneira:

var
objPessoa: TPessoa;
begin
objPessoa := TPessoa.Create;
objPessoa.ValidaCPF(’00.000.000-00’);

Limitações

Você não pode estender uma classe se ela já for à extensão de outra classe. Veja na listagem 2.

Listagem 2. Limitação de uso do Helpers

TPessoa = class; // OK

TPessoaFisica = class helper for TPessoa; // OK

TPessoaFisicaPobre = class helper for TPessoaFisica // Isto não funcionará

Dúvidas

Quando podemos utilizar estes recursos em nosso dia a dia? Para que estender uma classe?

1. Quando você trabalha em equipe, podemos usar o recurso de ter vários colaboradores trabalhando em uma mesma classe mas teríamos que usar um gerenciador de código fonte como o Starteam para fazer check-in/check-out e mesclar as alterações de cada um. Usando classes estendidas podemos dividir nossa classe para que cada programador trabalhe em uma classe estendida (cada classe estendida seria uma unit), ai quem tem o trabalho de juntar os códigos da classe e suas classes estendidas seria o compilador.

2. Vejamos a necessidade de manter duas versões de seu produto, onde uma versão tem mais características que outra (isto é “profissional” e versão “padrão”). As classes estendidas permitem que você adicione todas as características para a versão “profissionais” que ficará em uma unit separada. Quando você gerar a versão “padrão”, você simplesmente valida o tipo da versão e não compila unit da versão “profissionais”.

Teríamos N motivos e necessidades para usar classes estendidas, mas nosso foco é no recurso que o compilador Delphi nos oferece.

Na Prática

Vamos a um exemplo onde estenderemos uma classe para compreender como a classe estendida funciona na prática. O projeto tem duas units. A unit “Automovel.pas” define a classe de TAutomovel com um procedimento “LigarLimpadorDianteiro” da classe. A unit “ArCondicionado.pas” define uma classe de TArCondicionado estendida da classe TAutomovel. TArCondicionado irá implementar o procedimento “LigarArCondicionado” à classe de TAutomovel. Vejamos na Listagem 3.

Listagem 3. Na prática com estender uma classe.

{ Classe TAutomovel }

unit Automovel;

interface

uses Dialogs;

type

TAutomovel = class

class procedure LigarLimpadorDianteiro;

end;

implementation

{ TAutomovel }

class procedure Tautomovel.LigarLimpadorDianteiro;

begin

ShowMessage(’Limpador Ligado .’);

end;

end.

{ Classe estendida da TAutomovel chamada de TArCondicionado }

unit ArCondicionado;

interface

uses Dialogs, Automovel;

type

TArCondicionado = class helper for TAutomovel

class procedure LigarArCondicionado;

end;

implementation

{ TArCondicionado }

procedure TArCondicionado.LigarArCondicionado;

begin

ShowMessage(’Ar Condicionado Ligado.’);

end;

end.

{ Utilização da classe TAutomovel e da classe estendida TArCondicionado }

unit Helpers;

uses Automovel, ArCondicionado;

{$R *.dfm}

procedure TfrmHelpers.LipadorDianteiroClick(Sender: TObject);

begin

// Aqui dispara o método da classe TAutomovel.

TAutomovel.LigarLimpadorDianteiro;

end;

procedure TfrmHelpers.ArCondicionadoClick(Sender: TObject);

begin

// Aqui dispara o método da classe estendida que é TArcondicionado

// extensão do TAutomovel.

TAutomovel.LigarArCondicionado;

end;

end.

Tags:

Categoria Dicas Delphi - Acessando/Manipulando o Registro do Windows

Posted by webmaster | Delphi |

Os sistemas desenvolvidos cada vez mais precisam de informações de configuração e opções (como senhas, posições de impressão e coisas do tipo) e você precisa gravar estas informações em algum lugar.

O Delphi possibilita armazenar estas informações em Arquivos .INI (lembra deles…do Windows 3.x) através do Objeto TInifile, mas a não ser q você esteja utilizando esta versão do Windows (coisa q eu acho difícil..rsrsrs), a melhor alternativa é utilizar o registro do Sistema, que já está disponível a partir da versão Windows 95.

Se você não sabe do que eu estou falando, não se desespere. Antes de começar a utilizar estas informações vá até Iniciar-Executar e digite Regedit. O editor do registro do sistema será exibido e você poderá ter uma idéia de como ele funciona. O programa separa as opções de registro em “pastas”, conhecidas aqui como “chaves”. Essas chaves contém dados, chamados de “valores”. Esses valores possuem um nome, um tipo e um valor específico.

O Delphi encapsula o registro através do objeto TRegistry. É através dele que você irá acessar os dados do Registro. Para você entender melhor como funciona o objeto, vamos explicar primeiro como funciona o Registro do Windows:

As principais chaves “raízes” são: HKEY_LOCAL_MACHINE e HKEY_CURRENT_USER. Todas as informações sobre os programas ficam nessas chaves (as outras normalmente possuem informações sobre o Windows).

O InstallShield (programa para geração de instaladores), por exemplo, instala as informações sobre o nome de usuário e empresa do seu programa em HKEY_LOCAL_MACHINE\SOFTWARE\Nome da Sua Empresa\Nome Do Programa\Versão, com os valores Company e Name (Empresa e Nome do Usuário).

Os programas, por sua vez, usam a chave HKEY_CURRENT_USER\Software para armazenar informações de seus programas. E é nessa chave que você deve inserir sua sub-chave e colocar lá as informações necessárias.

Um pequeno exemplo de como utilizar o registro do Windows. Suponhamos que o programa necessite gravar a posição da janela, o seu tamanho e o diretório inicial dos diálogos Abrir e Salvar.

Após a criação do objeto, devemos informar qual chave devemos utilizar, utilizando o método OpenKey (Chave, PodeCriar); onde Chave é o nome da sub-chave e PodeCriar é um valor booleano que permite (ou não) criar a chave caso a mesma não exista.

Bom, agora vamos logo ao que interessa. A gravação/Leitura no Registro.
Este exemplo ilustra como gravar dados no Registro.

Primeiramente devemos declarar a Unit Registry na clausula Uses de sua aplicação.

procedure frmMain.GravarRegistro;
const
Raiz : String = ‘Software\Programa’;
var
Registro : TRegistry;
begin
// Chama o construtor do objeto
Registro := TRegistry.Create;
{ Abre a chave (se o 2°. Parâmetro for True, ele cria a chave caso ela ainda não exista. }
Registro.OpenKey (Raiz, True);
// Grava as informações do form
Registro.WriteInteger (’Largura’, Width);
Registro.WriteInteger (’Altura’, Height);
Registro.WriteInteger (’Esquerda’, Left);
Registro.WriteInteger (’Topo’, Top);
// Grava as informações das caixas Abrir e Salvar.
Registro.WriteString (’Abrir Inicial’, OpenDialog1.InitialDir);
Registro.WriteString(’Salvar Inicial’, SaveDialog1.InitialDir);
// Fecha a chave e o objeto
Registro.CloseKey;
Registro.Free;
end;

Após a criação do objeto, deve-se escolher uma chave para armazenas os valores. No caso, “Software\Programa”, cuja chave raiz é HKEY_CURRENT_USER. Note que é para se separar as chaves das sub-chaves utiliza-se o caracter “\”, tal como nos diretórios do DOS.

Os métodos WriteInteger e WriteString são utilizados para gravar valores inteiros e caracteres, respectivamente. A sintaxe básica é:

Registro.WriteString (NomeDoValor, Conteúdo);

onde NomeDoValor é o nome que você vai dar ao valor dentro da chave, e Conteúdo é o conteúdo desse valor.

Para escrever dados de outros tipos, utilize as funções:

WriteBool (NomeDoValor, Conteúdo); // Dados tipo Boolean
WriteBinaryData (NomeDoValor, Conteúdo); // Valor Binário
WriteCurrency (NomeDoValor, Conteúdo); // Dados tipo Currency
WriteDate (NomeDoValor, Conteúdo); // Dados tipo TDate
WriteDateTime (NomeDoValor, Conteúdo); // Dados tipo TDateTime
WriteFloat (NomeDoValor, Conteúdo); // Dados tipo Float (Real)
WriteInteger (NomeDoValor, Conteúdo); // Dados tipo Integer
WriteString (NomeDoValor, Conteúdo); // Dados tipo String
WriteTime (NomeDoValor, Conteúdo); // Dados tipo TTime

Este exemplo mostra como podemos ler dados do registro do Windows utilizando o Delphi.

procedure frmMain.LerRegistro;
const
Raiz : String = ‘Software\Programa’;
var
Registro : TRegistry;
begin
// Chama o construtor do objeto
Registro := TRegistry.Create;
with Registro do
begin
// Somente abre se a chave existir
if OpenKey (Raiz, False) then
// Envia as informações ao form, vendo se os valores existem, primeiramente…
if ValueExists (’Largura’) then
Width := ReadInteger (’Largura’);
if ValueExists (’Altura’) then
Height := ReadInteger (’Altura’);
if ValueExists (’Esquerda’) then
Left := ReadInteger (’Esquerda’);
if ValueExists (’Topo’) then
Top := ReadInteger (’Topo’);
// Envia as informações para as caixas Abrir e Salvar.
OpenDialog1.InitialDir := ReadString (’Abrir Inicial’);
SaveDialog1.InitialDir := ReadString (’Salvar Inicial’);
// Fecha a chave e o objeto
Registro.CloseKey;
Registro.Free;
end;
End;

Sempre use CloseKey quando não for precisar do Registro. Isso permite que as opções sejam gravadas permanentemente, evitando que qualquer problema que o computador tenha afete seu programa.

Os métodos ReadInteger e ReadString funcionam praticamente da mesma maneira que seus correspondentes de escrita. A diferença é que ao invés de passar o valor Conteúdo, eles retornam o valor armazenado. Os correspondentes dos outros tipos são:

ReadBool (NomeDoValor) // Valor booleano
ReadBinaryData ( NomeDoValor ; var Buffer ; TamBuffer : Integer) // Valor Inteiro
ReadCurrency (NomeDoValor) // Valor Currency
ReadDate (NomeDoValor) // Valor Date
ReadDateTime (NomeDoValor) // Valor DateTime;
ReadFloat (NomeDoValor) // Valor Float(Real)
ReadInteger (NomeDoValor) // Valor Inteiro
ReadString (NomeDoValor) // Valor String;
ReadTime (NomeDoValor) // Valor DateTime

Tags:
Page 2 of 2«12